Unity Shaders and Effects Cookbook:创建Ramp Texture

发表于2017-11-24
评论0 1.7k浏览

在Shader中根据光照来调节效果,会比较繁琐,所以可以直接用纹理。美术做好图之后,程序直接从纹理上取样,来模拟很多光照设置。


有颜色的这两个 Capsule 就是使用了 Ramp Texture的。


1、首先来创建一张渐变纹理

打开PS CS6,新建一张图片,设置512x256 大小。


然后选择渐变工具


在图片里面 右键 ,会弹出渐变编辑器


选择 一种 渐变预设 ,然后按住鼠标左键,从图片的左上角 拖到 右下角。就会自动生成渐变图了。



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。


在 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" 


shader 效果如第一张图的 第二个 Capsule。


使用了 Half Lambert 光照模型之后,然后使用渐变纹理来控制,就像图中的效果,转动查看会法线,只会用到 渐变纹理的右边一半的颜色,左边一边是用不上的。

这是因为 Half Lambert 光照模型中,这一句

float hLambert = difLight * 0.5 +0.5;  

Half Lamert光照模型就表现在这一句,将漫反射的光照值范围限定到了 (0.5,1)

所以我们根据 (0.5,1) 这个值 作为 UV 去渐变纹理采样,只能采样到右边一半的颜色。


最终的效果就是,根据光照的方向,计算各点受光照影响的强度,然后把强度作为UV去渐变纹理采样。


示例工程打包下载:http://pan.baidu.com/s/1jHzC84Y

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论