Unity Shader:(七)漫反射光照模型

漫反射公式=光源颜色*材质漫反射颜色*光源强度

1. 逐顶点漫反射光照

复制代码
 1 Shader "Test/DiffuseShader"
 2 {
 3     Properties{ _Color("Diffuse",Color)=(1.0,1.0,1.0,1.0)}
 4     SubShader
 5     {
 6         Pass
 7         {
 8             Tags{"LightMode"="ForwardBase"}
 9 
10             CGPROGRAM
11             #pragma vertex vert
12             #pragma fragment frag
13             
14             #include "Lighting.cginc"
15             fixed4 _Diffuse;//材质的漫反射颜色
16 
17             struct a2v 
18             {
19                 float4 vertex:POSITION; 
20                 float3 normal:NORMAL;  //法线,注意a2v的法线位于模型空间
21             };
22             struct v2f 
23             {
24                 float4 pos:SV_POSITION;
25                 fixed3 color : COLOR;
26             };
27 
28             v2f vert(a2v v)
29             {
30                 v2f o;
31                 o.pos = UnityObjectToClipPos(v.vertex);//顶点位置从模型空间转换到裁剪空间
32                 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光
33                 //计算漫反射
34                 fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));//把法线转换到世界空间,(float3x3)表示取矩阵的3行3列
35                 fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//得到光源方向
36                 //漫反射公式=光源颜色*材质漫反射颜色*光源强度
37                 fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));//saturate可以把参数截取到[0,1]范围内
38                 o.color = ambient + diffuse;//环境光+漫反射光
39                 return o;
40             }
41             fixed4 frag(v2f i) : SV_Target
42             {
43                 return fixed4(i.color,1.0);
44             }
45             ENDCG
46         }
47     }
48     FallBack "Diffuse"
49 }
复制代码

2. 逐像素漫反射光照:更平滑的光照效果

复制代码
Shader "Test/DiffuseShader2"
{
    Properties{ _Color("Diffuse",Color) = (1.0,1.0,1.0,1.0) }
        SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"
            fixed4 _Diffuse;//材质的漫反射颜色

            struct a2v
            {
                float4 vertex:POSITION;
                float3 normal:NORMAL;  //法线,注意a2v的法线位于模型空间
            };
            struct v2f
            {
                float4 pos:SV_POSITION;
                fixed3 worldNormal : TEXCOORD0;
            };
            //顶点着色器不计算漫反射,只是把转换后的法线传给片元着色器
            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);//顶点位置从模型空间转换到裁剪空间
                o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);//把法线转换到世界空间,(float3x3)表示取矩阵的3行3列
                return o;
            }
            //片元着色器里计算漫反射
            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光
                //计算漫反射
                fixed3 worldNormal = normalize(i.worldNormal);
                fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//得到光源方向
                //漫反射公式=光源颜色*材质漫反射颜色*光源强度
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));//saturate可以把参数截取到[0,1]范围内
                fixed3 color = ambient + diffuse;//环境光+漫反射光
                return fixed4(color,1.0);
            }
            ENDCG
        }
    }
        FallBack "Diffuse"
}
复制代码

3. 半兰伯特光照模型:背光区域也会有明暗变化(与逐像素漫反射模型差别用加粗字标注,在光源强度的计算上有差别)

复制代码
 1 Shader "Test/DiffuseShader3"
 2 {
 3     Properties{ _Color("Diffuse",Color) = (1.0,1.0,1.0,1.0) }
 4         SubShader
 5     {
 6         Pass
 7         {
 8             Tags{"LightMode" = "ForwardBase"}
 9 
10             CGPROGRAM
11             #pragma vertex vert
12             #pragma fragment frag
13 
14             #include "Lighting.cginc"
15             fixed4 _Diffuse;//材质的漫反射颜色
16 
17             struct a2v
18             {
19                 float4 vertex:POSITION;
20                 float3 normal:NORMAL;  //法线,注意a2v的法线位于模型空间
21             };
22             struct v2f
23             {
24                 float4 pos:SV_POSITION;
25                 fixed3 worldNormal : TEXCOORD0;
26             };
27             //顶点着色器不计算漫反射,只是把转换后的法线传给片元着色器
28             v2f vert(a2v v)
29             {
30                 v2f o;
31                 o.pos = UnityObjectToClipPos(v.vertex);//顶点位置从模型空间转换到裁剪空间
32                 o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);//把法线转换到世界空间,(float3x3)表示取矩阵的3行3列
33                 return o;
34             }
35             //片元着色器里计算漫反射
36             fixed4 frag(v2f i) : SV_Target
37             {
38                 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光
39                 //计算漫反射
40                 fixed3 worldNormal = normalize(i.worldNormal);
41                 fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//得到光源方向
42                 //漫反射公式=光源颜色*材质漫反射颜色*光源强度
43                 fixed halfLambert = dot(worldNormal, worldLight) * 0.5 + 0.5;
44                 fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;//saturate可以把参数截取到[0,1]范围内
45                 fixed3 color = ambient + diffuse;//环境光+漫反射光
46                 return fixed4(color,1.0);
47             }
48             ENDCG
49         }
50     }
51         FallBack "Diffuse"
52 }
复制代码
posted @   番茄玛丽  阅读(175)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示