XNA Shader编程教程8-光泽贴图(Gloss Map)
这个教程通过实现光泽贴图来更好地控制镜面反射。
什么是光泽贴图?
光泽贴图是一张黑白纹理,我们使用这张纹理控制特定顶点的反射程度,黑白纹理让我们可以很容易地做到这点
Shader中颜色的格式如下:r,g,b,每个分量的变化范围是从0.0到1.0。而一个黑白纹理意味着每个分量具有相同的值:
White=(1,1,1)
Light gray=(0.8,0.8,0.8)
Dark gray=(0.2,0.2,0.2)
Black=(0,0,0)
下图是Gloss贴图的例子:
我们想让白色的部分反光最强,灰色其次,而黑色部分没有反光。
实现Shader
我们需要加载镜面反射纹理并将它传递到shader中。在shader中需要从纹理获取glossmap的颜色并将它储存在一个变量中。
float4 GlossMapColor = tex2D(GlossMapSampler, Tex);
现在,我们需要使用GlossMapColor以决定图素的镜面反射的颜色:
// R = 2 * (N.L) * N – L float3 Reflect = normalize(2 * Diff * Normal - LightDir); float Specular = pow(saturate(dot(Reflect, ViewDir)), 20); // R.V^n
请注意,现在我们在“Specular”变量中存储的是最大反光强度,为了减少反光,我们需要以某种方式修改“Specular”,我们如何做到这一点?你猜的对,将镜面反光的颜色乘以GlossMapColor。光泽贴图中只包含黑白两色,即每个RGB分量都相同。所以我们可以只使用一个分量乘以“Specular”:
// R = 2 * (N.L) * N – L float3 Reflect = normalize(2 * Diff * Normal - LightDir); float Specular = pow(saturate(dot(Reflect, ViewDir)), 20); // R.V^n Specular = Specular*GlossMapColor.x;
这里我使用GlossMapColor的x分量乘以 “Specular”。GlossMapColor.x范围从0.0到1.0,相当于镜面反射的比例。如果glossmap是黑色的,则Specular将乘以0.0,使它的值为0.0。如果是白色的,Specular将保持不变,而镜面反射程度取决于GlossMapColor的灰度。
知道了这一点,我们就可以实现光照方程了:
return vAmbient + vDiffuseColor * ColorMapColor * Diff + vSpecularColor * Specular;
在这个例子中我还增加了一个颜色纹理让效果更明显:)
何时使用光泽映射?
只要你想控制反射,就可以使用光泽映射!比如一个生锈的铁杯在某些部位仍会反光,而生锈的部位反光较少。旧汽车,光滑/粗糙的冰面等情况也适用。
发布时间:2009/4/14 下午12:34:45 阅读次数:11449