У меня есть некоторые проблемы при рендеринге набора значений для rendertarget. Значения никогда не заканчиваются в том диапазоне, в котором я их хочу. В основном я использую полноэкранный четырехугольник и пиксельный шейдер для рендеринга в текстуру rendertarget, а затем собираюсь использовать координаты текстуры в качестве основы для некоторых вычислений в шейдере. Координаты текстуры четырехугольной области от (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) как координаты UV, но остальные угловые пиксели не выбирают из другие углы четырехугольника. Я проиллюстрировал это на левом изображении с синим прямоугольником, представляющим квад, а белыми точками - верхние координаты выборки.
Теперь я знаю о смещении в половину пикселя, которое вы должны применять к своим координатам при рендеринге выровненных по экрану квадратов в Direct3D9. Давайте посмотрим, какой результат я получу от этого:
(Квадрат отображается с половинным смещением DX9)
Красный и зеленый стали ярче, но все еще не верны: 223 - максимум, который я получаю на канале красного или зеленого цвета. Но теперь у меня даже больше нет чистого черного, а вместо этого темно-желтовато-серый с RGB (32,32,0)!
Что мне действительно нужно, так это рендеринг:
(целевой рендер, уменьшенный размер квадрата)
Похоже, мне нужно переместить правую и нижнюю границу моего четырехугольника ровно на один пиксель вверх и влево по сравнению с первой фигурой. Тогда правый столбец и нижний ряд пикселей должны корректно получить координаты UV прямо от границы квадрата:
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 на какое-то крошечное количество, чтобы сделать крошечное немного больше, это как бы работает ... по крайней мере, для текстуры 4х4. Это не работает на меньших текстурах, и я боюсь, что это слегка искажает равномерное распределение значений uv на больших текстурах:
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(Я изменил вычисление pixelSize на 0,001f - для текстур меньшего размера, например, таблиц поиска 1D, это не работает, и мне нужно увеличить его до 0,01f или чего-то большего)
Конечно, это тривиальный пример, и я мог бы гораздо проще выполнить этот расчет на процессоре, не беспокоясь о том, чтобы отобразить UV в центры пикселей ... тем не менее, должен быть способ действительно отобразить полный, полный [0, 1] диапазон пикселей на цели рендеринга !?