Bir rendertarget için bir grup değer oluşturmada sorun yaşıyorum. Değerler asla olmasını istediğim aralıkta sonuçlanmaz. Temelde rendertarget dokumuza işlemek için bir tam ekran dörtlü ve bir piksel gölgelendirici kullanıyorum ve daha sonra gölgelendiricideki bazı hesaplamalar için doku koordinatlarını temel almak niyetindeyim. Dörtlüün doku koordinatları sol üstte (0,0) ile sağ alt köşede (1,1) arasında değişir ... sorun, enterpolasyondan sonra bu değerlerin piksel gölgelendiricisine bu şekilde ulaşmamasıdır. .
Bir örnek: 4x4 bir dokuya render ediyorum ve bu durumda gölgelendirici, kırmızı ve yeşil kanallardaki doku koordinatlarını (u, v) çıktılar:
return float4(texCoord.rg, 0, 1);
Bundan çıkmak istediğim, sol üstteki pikselin RGB (0,0,0) ve böylece siyah olduğu, sağ üstteki pikselin RGB (255,0,0) ve böylece parlak olduğu bir doku. kırmızı ve sol alttaki piksel RGB (0,255,0) - parlak yeşil.
Ancak, bunun yerine burada sağda olsun:
(düz dörtlü oluşturma, düzeltme yok)
Sol üst piksel siyah, ancak diğer köşelerde yalnızca nispeten koyu kırmızı ve koyu yeşil elde ediyorum. RGB değerleri (191,0,0) ve (0,191,0) 'dır. Dörtlüün örnekleme konumlarıyla ilgili olduğundan şüpheliyim: sol üst piksel dörtlünün sol üst köşesini doğru bir şekilde örnekliyor ve UV koordinatları olarak (0,0) alıyor, ancak diğer köşe pikselleri örneklemiyor dörtlünün diğer köşeleri. Bunu sol görüntüde dörtlü temsil eden mavi kutu ve beyaz noktalar üst örnekleme koordinatlarını gösterdim.
Direct3D9'da ekran hizalı dörtlüleri oluştururken koordinatlarınıza uygulamanız gereken yarım piksel ofsetini biliyorum. Bundan ne tür bir sonuç aldığımı görelim:
(DX9'un yarım piksel ofseti ile oluşturulmuş dörtlü)
Kırmızı ve yeşil daha parlak hale geldi, ancak hala doğru değil: 223 kırmızı veya yeşil renk kanalında aldığım maksimum. Ama şimdi, artık saf siyahım bile yok, bunun yerine RGB ile koyu, sarımsı bir gri (32,32,0)!
Aslında ihtiyacım olan bu tür bir render olurdu:
(hedef oluşturma, azaltılmış dörtlü boyut)
İlk şekle kıyasla dörtlemin sağ ve alt kenarlığını tam olarak bir piksel yukarı ve sola hareket ettirmem gerekiyor gibi görünüyor. Ardından, sağ sütun ve alt piksel sırası, UV koordinatlarını dörtlüün sınırından doğru bir şekilde almalıdır:
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)),
};
Ancak bu pek işe yaramadı ve alt ve sağ piksellerin hiç görüntülenmemesine neden oldu. Sanırım bu piksellerin merkezleri dörtlü tarafından kaplanmadı ve bu nedenle gölgelendirici tarafından işlenmeyecek. Quad'i küçük bir miktar daha büyük yapmak için pixelSize hesaplamasını küçük bir miktar olarak değiştirirsem, en azından 4x4 dokuda çalışır ... Daha küçük dokular üzerinde çalışmaz ve uv değerlerinin daha büyük dokulardaki eşit dağılımını ustaca bozduğundan korkarım:
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(PixelSize hesaplamasını 0.001f olarak değiştirdim - daha küçük dokular için, örneğin 1D arama tabloları, bu işe yaramıyor ve 0,01 f'ye veya daha büyük bir şeye yükseltmem gerekiyor)
Tabii ki bu önemsiz bir örnek ve bu hesaplamayı UV'leri piksel merkezlerine eşleme konusunda endişelenmeden CPU'da çok daha kolay yapabilirim ... yine de, tam, eksiksiz bir render yapmak için bir yol olmalı [0, 1] bir rendertarget üzerindeki piksel aralığı !?