在Shader中根据光照来调节效果,会比较繁琐,所以可以直接用纹理。美术做好图之后,程序直接从纹理上取样,来模拟很多光照设置。
有颜色的这两个 Capsule 就是使用了 Ramp Texture的。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
打开PS CS6,新建一张图片,设置512x256 大小。
然后选择渐变工具
在图片里面 右键 ,会弹出渐变编辑器
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
选择 一种 渐变预设 ,然后按住鼠标左键,从图片的左上角 拖到 右下角。就会自动生成渐变图了。
2、使用渐变纹理控制漫反射着色
原理就是从根据光照强度的强弱,把这个强弱值作为UV,从渐变纹理中取样。
在最基本的漫反射着色器代码中,对 基本漫反射光照函数进行了一点点修改。,添加了一句
float3 ramp=tex2D( _RampTex , float2(difLight,difLight)).rgb;
完整 shader 代码如下:
Shader "CookBookShaders/Ramp Texture" { Properties { _EmissiveColor("Emissive Color",Color) = (1,1,1,1) //设置默认值 _AmbientColor("Ambient Color",Color) = (1,1,1,1) _PowValue("Power Value",Range(-1,1)) = 1 _RampTex("Ramp Texture",2D) = "" //添加_RampTex属性接受一个Texture } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf rampTextureDiffuse float4 _EmissiveColor; float4 _AmbientColor; float _PowValue; sampler2D _RampTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float4 c; c=pow((_EmissiveColor+_AmbientColor),_PowValue); o.Albedo = c.rgb; o.Alpha = c.a; } //不需要视角方向的前向着色 inline half4 LightingrampTextureDiffuse(SurfaceOutput s,half3 lightDir,half atten) { float difLight = max(0,dot(s.Normal,lightDir) );//dot表示cos值,范围(-1,1) max将difLight的范围限定到了(0,1) float3 ramp=tex2D( _RampTex , float2(difLight,difLight)).rgb; half4 color=(0,0,0,0); color.rgb=s.Albedo * _LightColor0.rgb * (ramp); color.a=s.Alpha; return color; } //需要视角方向的前向着色 inline half4 LightingBasicDiffuseWithViewDir(SurfaceOutput so,half3 lightDir,half3 viewDir,half atten) { half4 color=(0,0,0,0); return color; } //需要使用延迟着色 inline half4 LightingBasicDiffuse_PrePass(SurfaceOutput so,half4 light) { half4 color=(0,0,0,0); return color; } ENDCG } FallBack "Diffuse" }
shader 效果如第一张图的 第三个 Capsule。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
在 Half Lambert光照模型上面应用了 Ramp Texture 也写了一下。
Shader "CookBookShaders/Ramp Texture Half Lambert" { Properties { _EmissiveColor("Emissive Color",Color) = (1,1,1,1) //设置默认值 _AmbientColor("Ambient Color",Color) = (1,1,1,1) _PowValue("Power Value",Range(-1,1)) = 1 _RampTex("Ramp Texture",2D) = "" //添加_RampTex属性接受一个Texture } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf rampHalfLambertDiffuse float4 _EmissiveColor; float4 _AmbientColor; float _PowValue; sampler2D _RampTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float4 c; c=pow((_EmissiveColor+_AmbientColor),_PowValue); o.Albedo = c.rgb; o.Alpha = c.a; } //不需要视角方向的前向着色 inline half4 LightingrampHalfLambertDiffuse(SurfaceOutput s,half3 lightDir,half atten) { float difLight = max(0,dot(s.Normal,lightDir) );//dot表示cos值,范围(-1,1) max将difLight的范围限定到了(0,1) float hLambert = difLight * 0.5 +0.5;//Half Lamert光照模型就表现在这一句,将漫反射的光照值范围限定到了 (0.5,1),所以原来是 0 的地方现在就是 0.5 了,明亮度顿时提升,而原来已经很亮的地方并没有很大的变化。 float3 ramp=tex2D( _RampTex , float2(hLambert,hLambert)).rgb; half4 color=(0,0,0,0); color.rgb=s.Albedo * _LightColor0.rgb * (ramp); color.a=s.Alpha; return color; } //需要视角方向的前向着色 inline half4 LightingBasicDiffuseWithViewDir(SurfaceOutput so,half3 lightDir,half3 viewDir,half atten) { half4 color=(0,0,0,0); return color; } //需要使用延迟着色 inline half4 LightingBasicDiffuse_PrePass(SurfaceOutput so,half4 light) { half4 color=(0,0,0,0); return color; } ENDCG } FallBack "Diffuse" }
使用了 Half Lambert 光照模型之后,然后使用渐变纹理来控制,就像图中的效果,转动查看会法线,只会用到 渐变纹理的右边一半的颜色,左边一边是用不上的。
这是因为 Half Lambert 光照模型中,这一句
float hLambert = difLight * 0.5 +0.5;
所以我们根据 (0.5,1) 这个值 作为 UV 去渐变纹理采样,只能采样到右边一半的颜色。
最终的效果就是,根据光照的方向,计算各点受光照影响的强度,然后把强度作为UV去渐变纹理采样。
示例工程打包下载:
http://pan.baidu.com/s/1jHzC84Y