本文首发地址:http://98jy.net/article/25
更多文章,请入传送门
----------------------------------------------
Ramp Texture在Valve公司的军团要塞2后开始成为一种控制漫反射的方法。
Ramp Texture是类似下图的一张贴图:
在一般的Blinn/Phong模型中,我们对漫反射的系数是基于入射光和击中的点的法线的角度。在这种情况下,系数的计算代码大致如下:
float DiffuseCoeff(in float3 pos, in float3 normal, in float3 lightPos) { float3 lightDir = lightPos - pos; lightDir.normalize(); return max(0.0, Dot(lightDir, normal)); }
使用Ramp texture,可以用一张1D的材质图来做为索引表。用来控制漫反射的系数。虚拟代码如下:
texture1D rampTex; float DiffuseCoeff(in float3 pos, in float3 normal, in float3 lightPos) { float3 lightDir = lightPos - pos; lightDir.normalize(); // Map value from [-1, 1] to [0, 1] float rampCoord = Dot(lightDir, normal) * 0.5 + 0.5; return tex1D(rampTex, rampCoord); }
我们这节课来改动原来的shader,自己来观察原来的shader在加入Ramp Texture后能做的事情。
inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = dot(s.Normal, lightDir); float hLambert = difLight * 0.5 + 0.5; float3 ramp = tex2D(_RampTex, float2(hLambert, hLambert)).rgb; float4 col; col.rgb = s.Albedo * _LightColor0.rgb * (ramp); col.a = s.Alpha; return col; }
_RampTex("Ramp texture", 2D) = "white"
sampler2D _RampTex;
为了保证你最后的结果跟我的是一样的,这里是最后的代码:
Shader "myDiffuse" { Properties { _EmissiveColor ("Emissive Color", Color) = (1, 1, 1, 1) _AmbientColor ("Ambient Color", Color) = (1, 1, 1, 1) _SomeValue ("Coefficient", Range(0, 10)) = 2.5 _RampTex("Ramp texture", 2D) = "white" } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf BasicDiffuse float4 _EmissiveColor; float4 _AmbientColor; float _SomeValue; sampler2D _RampTex; inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = dot(s.Normal, lightDir); float hLambert = difLight * 0.5 + 0.5; float3 ramp = tex2D(_RampTex, float2(hLambert, hLambert)).rgb; float4 col; col.rgb = s.Albedo * _LightColor0.rgb * (ramp); col.a = s.Alpha; return col; } struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float4 c = pow((_EmissiveColor + _AmbientColor), _SomeValue); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
选中某个材质球,Inspector面板上会出现选择图片的控件,这里我们可以拖入一张图观察结果。
对那些还不会使用绘图工具的读者,你可以用我这里给你准备好的几张图(ramp texture生成方式可以使用photoshop的gradient工具,附录里我们写了这些步骤)
对于Ramp Texture shader来说,我们主要是加入了对送入的Ramp texture的色彩的检索,检索出来的色彩值最后能影响到我们的光照模型的输出。
tex2D()方法是cg的库方法,用来根据第二个参数提供的uv值(类型是float2,分别代码水平方向的u和竖直方向的v),来检索第一个参数代表的图档中的RGBA值。
这里我们给定的uv值有half lambert的值决定,half lambert越大,意味着我们索引到的像素的值的位置在原图中越是偏向于右下角方向。美术可以利用这个特性来控制一个物体表面的漫反射(越是往右,越是往下,意为着物体的法线方向越来越接近于入射光)。
附录:
在Photoshop中,我们可以几个步骤来建立Ramp texture:
98教育原创,转载请注明出处(98jy.net),否则视为侵权。