Shader model 5.0 的片段著色器能不能得到該片段所在的三角圖元實際光柵化後有多少像素?

因為想自己實現mipmap(因為我想把紋理在顯存中以一維度形式存儲 而不是二維 這樣多個紋理 存放到一個顯存空間 就不需要二維裝箱 也不會有空間浪費 代價是紋理採樣濾波 mipmap 都要重新實現)

採樣濾波好弄

mipmap因為涉及到需要知道LOD level因子

這和實際光柵化後的像素麵積 和 紋理本身的像素的面積 有關

所以我想知道 Shader model 5.0 的片段著色器能不能得到該片段所在的三角圖元實際光柵化後有多少像素(並且沒寫入到緩衝區的像素也算入)

注意是一個三角圖元 而不是一個drawcall的Mesh


1. 片段著色器是什麼?fragment shader?都fragment了哪來的圖元?

2. Mipmap和光柵化後有多少像素無關,跟所在點的拉伸程度有關。

3. 你放到1D是沒有空間浪費了,但時間上浪費巨大。cache效率降到1/N,sampler全廢。結果必然是慢的要死。

如果你非得這麼做,那麼你要的只是根據當前的2D紋理坐標計算mipmap level,這個應該在某本古老的書里提到過。根本不用sm5,sm2足以。

sm2x里,shader是可以用ddx/ddy的。所以mipmap這麼來算

float2 dx = ddx(uv * texture_size.x);
float2 dy = ddy(uv * texture_size.y);
float d = max(dot(dx, dx), dot(dy, dy));
mip_level = log2(sqrt(d));

texture_size是從外面傳進來的紋理寬高,sm4+可以從紋理對象上直接獲取。uv是2D紋理坐標。

如果連ddx/ddy都沒有,那麼就用個每層mip不同顏色的紋理,先渲一遍,得到的結果就是mip數。


問問題的時候請打上標點符號,把句子寫通順。

1. Mip-Map Level由像素在紋理空間的大小和形狀決定,它是每個像素的屬性。因為透視修正的存在,在Primitive一級無法得到正確的Mipmap。正確的Mip-Map計算, @叛逆者 已經給出了。

2. 在硬體上,平均一個Bi-linear (Filtering)只需要 &<= 1 個 cycle,三線濾波一般也只需要 0.5 - 2 個Cycle。但是Point Sampler自己,也需要和Bi-linear甚至是Tri-linear差不多的時間。這意味著如果你自己計算獲取一個像素的Mip Map,需要4-8個Cycle才能完成。

3. HW Cache針對2D Texture是有優化的。使用1D Texture會導致紋理的緩存命中率嚴重下降。

4. Pixel無論如何也得不到一個Primitive到底產生了多少個Pixel,因為Primitive一產生新的Pixel後就立刻送到Pixel Shader中了,先產生出來的Pixel哪管的了後面的。


硬體往sm(shader compute unit的)裡面送數據是一堆quad為一組的,一個quad是2x2個像素。一個sm,以nv硬體為例,有32個thread,那麼一次就要計算8個quad。這些quad是將三角形光柵化之後打碎得到的。這個8個quad不一定來自同一個三角形,或者只包含一部分三角形。取決於這個三角形多大。

所以在單個pixel shader thread裡面是看不到一個primitive的,或者更正確的說是看不到一個完整的raster過後的primitive。也就無法得知整個三角形包含多少像素。


推薦閱讀:

為什麼半透明模型的渲染要使用深度測試而關閉深度寫入?
iOS 9 用的是哪種模糊演算法?
Unity5.X中屏幕空間陰影投射技術(Screenspace ShadowMap)如何產生陰影圖?
unity移動開發如何依據性能選擇shader?

TAG:OpenGLES | 計算機圖形學 | shader |