У мене виникають проблеми з рендерінгом купівлі значень. Значення ніколи не закінчуються в тому діапазоні, в якому я їх хочу. В основному я використовую повноекранний квадроцикл і піксельний шейдер для відображення моєї текстури візуалізації, а потім збираюся використовувати координати текстури як основу для деяких обчислень в шейдері. Координати текстур квадратику від (0,0) вгорі зліва до (1,1) в правому нижньому куті ... проблема полягає в тому, що після інтерполяції ці значення не надходять на піксельний шейдер як такий .
Приклад: Я надаю текстуру 4x4, і в цьому випадку шейдер просто виводить координати текстури (u, v) в червоний і зелений канали:
return float4(texCoord.rg, 0, 1);
Я хочу вийти з нього - це текстура, де піксель у верхньому лівому куті - RGB (0,0,0) і, таким чином, чорний, піксель у верхньому правому куті - RGB (255,0,0) і, таким чином, яскравий червоний, а піксель у лівій нижній частині - RGB (0,255,0) - яскраво-зелений.
Однак замість цього я отримую це праворуч:
(пряма квадратіка, без корекції)
Лівий верхній піксель чорний, але я отримую лише відносно темно-червоний і темно-зелений в інших кутах. Їх значення RGB становлять (191,0,0) та (0,191,0). Я сильно підозрюю, що це стосується місць вибірки квадратика: верхній лівий піксель правильно відбирає лівий верхній кут квадрата і отримує (0,0) як УФ-координати, але інші кутові пікселі не вибирають з інші кути квадратика. Я проілюстрував це на лівому зображенні синім полем, що представляє квадратик, а білі точки - верхні координати вибірки.
Тепер я знаю про зсув напівпікселя, який слід застосувати до своїх координат під час візуалізації квадратиків на екрані в Direct3D9. Подивимося, який результат я отримую від цього:
(чотиримісне відображення із зміщенням половинного пікселя DX9)
Червоний і зелений стали яскравішими, але все-таки неправильні: 223 - це максимум, який я отримую на каналі червоного або зеленого кольору. Але зараз у мене вже навіть немає чистого чорного, а натомість темний, жовтуватий сірий з RGB (32,32,0)!
Що мені насправді потрібно, буде такий вид рендерінгу:
(цільовий рендер, зменшений розмір квадратика)
Схоже, я повинен перемістити праву і нижню межу мого квадрата рівно на один піксель вгору і вліво, порівняно з першою цифрою. Тоді правий стовпець і нижній ряд пікселів повинні правильно отримувати УФ-координати прямо від межі квадрата:
VertexPositionTexture[] quad = new VertexPositionTexture[]
{
new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 1f), new Vector2(0,0)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, 1.0f, 1f), new Vector2(1,0)),
new VertexPositionTexture(new Vector3(-1.0f, -1.0f + pixelSize.Y, 1f), new Vector2(0,1)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, -1.0f + pixelSize.Y, 1f), new Vector2(1,1)),
};
Однак це не вийшло, і нижня та права пікселі взагалі не відображалися. Я думаю, що ці піксельні центри вже не вкриті квадратиком, і тому шейдер не оброблятиметься. Якщо я зміню обчислення pixelSize на якусь крихітну суму, щоб зробити квадратик на невеликий розмір більшим, він начебто працює ... принаймні на текстурі 4x4. Він не працює на менших фактурах, і я побоююсь, що це тонко спотворює рівномірний розподіл значень uv на більші текстури:
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(Я змінив обчислення pixelSize на 0,001f - для менших текстур, наприклад, 1D таблиці пошуку, це не працює, і я повинен збільшити його до 0,01f або щось більше)
Звичайно, це тривіальний приклад, і я міг би зробити цей розрахунок набагато простіше на процесорі, не турбуючись про відображення УФ-променів у піксельні центри ... все-таки, повинен бути спосіб фактично зробити повноцінним, повним [0, 1] діапазон до пікселів у вікні відтворення !?