PBR 與 OpenGL ES 2.0 中的LOD紋理:Mipmap (關於Lod和Bias)

MipMap

當使用Mipmap的時候可能會用到xxxLodxxxBias 這幾種紋理採樣函數。

片段着色器中:

    • vec4 texture2D (sampler2D sampler, vec2 coord )
    • vec4 textureCube (samplerCube sampler,vec3 coord ) 自動計算使用的紋理層。
    • vec4 texture2D (sampler2D sampler, vec2 coord, float bias)
    • vec4 textureCube (samplerCube sampler, vec3 coord, float bias ) 需要在t.w中指定一個偏移量來把自動計算出的紋理層全部偏移指定的值。
    • vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)
    • vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod) 需要在t.w中明確指定要使用的紋理層。

下面一段話出自Unity3D的論壇,都是互通的:
In the PS the LOD is determined from the derivatives of the texCoords automatically(tex2D). You can also specify the derivatives explicitly as two extra arguments
tex2D(textureMap, texCoord, ddx(texCoord), ddy(texCoord))
is equivalent to your tex2D, though of course you could use something else as the derivative.
Alternately, you can use tex2Dlod to explicitly select the LOD speicifed by the ‘w’ component of texCoord; eg, something like:
tex2Dlod(textureMap, float4(texCoord.xy, 0, lod))

LOD實現的原理

首先明確幾個概念:

  1. 屏幕上的顏色點叫像素,紋理上的顏色點叫紋素
  2. 屏幕座標系我們用XY座標系,紋理座標系用UV座標系
  3. GPU在着色器階段是在屏幕空間XY座標系中對每一個像素去對應的紋理中查找對應的紋素來確定像素的顏色。

即在着色階段是一個XY空間到UV空間的映射。
我們可以分別求x和y偏導數,通過X和Y的偏導數中的較大值作爲屏幕單個像素寬度紋理座標的變化率

在Shader中使用tex2D(tex, uv)的時候相當於在GPU內部展開成下面:

tex2D(sampler2D tex, float4 uv)
{
    float lod = CalcLod(ddx(uv), ddy(uv));
    uv.w= lod;
    return tex2Dlod(tex, uv);
}

至此uv已經是個(xyzw)的向量,但是並不能確定使用第幾層的MipMap,計算LOD的原理函數代碼如下:

float mipmapLevel(float2 uv, float2 textureSize)
{
    float dx = ddx(uv * textureSize.x);
    float dy = ddy(uv * textureSize.y);
    float d = max(dot(dx, dx), dot(dy, dy));  
    return 0.5 * log2(d);//0.5是技巧,本來是d的平方。
} 

實際使用

在PBR渲染中,在算物體表面反射的時候,可以使用Texture自帶的MIPMAP來模擬粗糙的效果,簡化積分的計算。

順便推薦幾個學習PBR的網站:
- 微軟大牛叛逆者
- LearnOpenGL

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章