三种光照模型的shader实现

1.Lambert模型,公式为I=Kd*Il(N*L);

 1 Shader "Custom/Lambert_A" {
 2     Properties {
 3         _Diffuse("Diffuse",Color)=(1,1,1,1)
 4     }
 5     SubShader {
 6     Pass{
 7         Tags { "LightMode"="ForwardBase" }
 8         CGPROGRAM
 9         #pragma vertex vert
10         #pragma fragment frag
11         #include"Lighting.cginc"
12 
13         fixed4 _Diffuse;//为了使用Properties中声明的属性
14         struct a2v//顶点着色器的输入结构体
15         {
16         float4 vertex:POSITION;//位置
17         float3 normal:NORMAL;//法向量
18         };
19 
20         struct v2f//顶点着色器的输出结构体
21         {
22         float4 pos:SV_POSITION;//一般用SV_POSITION作为输出
23         fixed3 color:COLOR;
24         };
25         v2f vert(a2v v)
26         {
27         v2f o;
28         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
29         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//获取环境光
30 
31         fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));//得到顶点单位法向量
32         fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//获取顶点指向灯光的单位向量
33         fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLight));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
34         o.color=ambient+diffuse;//与环境光叠加
35         return o;
36         }
37         fixed4 frag(v2f i):SV_Target
38         {
39         return fixed4(i.color,1.0);
40         }
41         ENDCG
42     }
43     }
44     FallBack "Diffuse"
45 }
46   逐像素代码(效果较好)
47 
48 Shader "Custom/Lambert_B" {
49     Properties {
50         _Diffuse("Diffuse",Color)=(1,1,1,1)
51     }
52     SubShader {
53     Pass{
54     Tags { "LightMode"="ForwardBase" }
55         CGPROGRAM
56         #pragma vertex vert
57         #pragma fragment frag
58         #include"Lighting.cginc"
59 
60         fixed4 _Diffuse;//为了使用Properties中声明的属性
61         struct a2v//顶点着色器的输入结构体
62         {
63         float4 vertex:POSITION;//位置
64         float3 normal:NORMAL;//法向量
65         };
66 
67         struct v2f//顶点着色器的输出结构体
68         {
69         float4 pos:SV_POSITION;//输出位置
70         fixed3 worldNormal:TEXCOORD0;
71         };
72         v2f vert(a2v v)
73         {
74         v2f o;
75         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
76         o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);//得到顶点单位法向量
77         return o;
78         }
79         fixed4 frag(v2f i):SV_Target
80         {
81         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//获取环境光
82         fixed3 worldNormal=normalize(i.worldNormal);
83         fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);//获取顶点指向灯光的单位向量
84         fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
85         fixed3 color=ambient+diffuse;//与环境光叠加
86         return fixed4(color,1.0);
87         }
88         ENDCG
89     }
90     }
91     FallBack "Diffuse"
92 }
逐顶点
 1 Shader "Custom/Lambert_B" {
 2     Properties {
 3         _Diffuse("Diffuse",Color)=(1,1,1,1)
 4     }
 5     SubShader {
 6     Pass{
 7     Tags { "LightMode"="ForwardBase" }
 8         CGPROGRAM
 9         #pragma vertex vert
10         #pragma fragment frag
11         #include"Lighting.cginc"
12 
13         fixed4 _Diffuse;//为了使用Properties中声明的属性
14         struct a2v//顶点着色器的输入结构体
15         {
16         float4 vertex:POSITION;//位置
17         float3 normal:NORMAL;//法向量
18         };
19 
20         struct v2f//顶点着色器的输出结构体
21         {
22         float4 pos:SV_POSITION;//输出位置
23         fixed3 worldNormal:TEXCOORD0;
24         };
25         v2f vert(a2v v)
26         {
27         v2f o;
28         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
29         o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);//得到顶点单位法向量
30         return o;
31         }
32         fixed4 frag(v2f i):SV_Target
33         {
34         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//获取环境光
35         fixed3 worldNormal=normalize(i.worldNormal);
36         fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);//获取顶点指向灯光的单位向量
37         fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
38         fixed3 color=ambient+diffuse;//与环境光叠加
39         return fixed4(color,1.0);
40         }
41         ENDCG
42     }
43     }
44     FallBack "Diffuse"
45 }
逐像素(效果较佳)

 

2.Phong模型,公式为I=KsIl(V*R)^ns

 1 Shader "Custom/Phong_A" {
 2     Properties {
 3         _Diffuse("Diffuse",Color)=(1,1,1,1)
 4         _Specular("Specular",COlor)=(1,1,1,1)
 5         _Gloss("Gloss",Range(8.0,256))=20
 6     }
 7     SubShader {
 8         Pass{
 9         Tags { "LightMode"="ForwardBase" }
10         CGPROGRAM
11         #pragma vertex vert
12         #pragma fragment frag
13         #include"Lighting.cginc"
14 
15         fixed4 _Diffuse;
16         fixed4 _Specular;
17         float  _Gloss;
18         struct a2v
19         {
20         float4 vertex:POSITION;
21         float3 normal:NORMAL;
22         };
23 
24         struct v2f
25         {
26         float4 pos:SV_POSITION;
27         fixed3 color:COLOR;
28         };
29         v2f vert(a2v v)
30         {
31         v2f o;
32         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
33         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//获取环境光
34         fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));//得到顶点单位法向量
35         fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);//得到场景光源
36         fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
37         fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));//得到反射光的单位向量
38         fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(unity_ObjectToWorld,v.vertex).xyz);//视角方向=世界空间的摄像机位置-世界空间的顶点位置
39         fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss);//光源颜色*材质高光颜色*(视角方向和反射光方向的点积(V*R))
40         o.color=ambient+diffuse+specular;//环境光+漫反射+高光
41         return o;
42         }
43         fixed4 frag(v2f i):SV_Target
44         {
45         return fixed4(i.color,1.0);
46         }
47         ENDCG
48     }
49     }
50     FallBack "Specular"
51 }
逐顶点
 1 Shader "Custom/Phong_B" {
 2     Properties {
 3         _Diffuse("Diffuse",Color)=(1,1,1,1)
 4         _Specular("Specular",COlor)=(1,1,1,1)
 5         _Gloss("Gloss",Range(8.0,256))=20
 6     }
 7     SubShader {
 8         
 9         Pass{
10         Tags { "LightMode"="ForwardBase" }
11         CGPROGRAM
12         #pragma vertex vert
13         #pragma fragment frag
14         #include"Lighting.cginc"
15 
16         fixed4 _Diffuse;
17         fixed4 _Specular;
18         float  _Gloss;
19         struct a2v
20         {
21         float4 vertex:POSITION;
22         float3 normal:NORMAL;
23         };
24 
25         struct v2f
26         {
27         float4 pos:SV_POSITION;
28         fixed3 worldNormal:TexCOORD0;
29         float3 worldPos:TEXCOORD1;
30         };
31         v2f vert(a2v v)
32         {
33         v2f o;
34         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);//把顶点矢量从模型空间变换到裁剪空间
35         o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);//得到顶点单位法向量
36         o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;//把顶点矢量从模型空间变换到世界空间
37         return o;
38         }
39 
40         fixed4 frag(v2f i):SV_Target
41         {
42         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
43         fixed3 worldNormal=normalize(i.worldNormal);
44         fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);//得到场景光源
45         fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));//_LightColor0为场景中灯光的颜色,光源颜色*材质漫反射颜色*(法线和入射光的点积(N*L))
46         fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));//得到反射光的单位向量
47         fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);//视角方向=世界空间的摄像机位置-世界空间的顶点位置
48         fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss);//光源颜色*材质高光颜色*(视角方向和反射光方向的点积(V*R))
49         return fixed4(ambient+diffuse+specular,1.0);//环境光+漫反射+高光
50         }
51         ENDCG
52     }
53     }
54     FallBack "Specular"
55 }
逐像素(效果较好)

 

3.Blinn Phong模型,公式为I=KsIl(N*H),其中H=(L+V)/|L+V|;

Shader "Custom/Blinn_Phong" {
    Properties {
        _Diffuse("Diffuse",Color)=(1,1,1,1)
        _Specular("Specular",COlor)=(1,1,1,1)
        _Gloss("Gloss",Range(8.0,256))=20
    }
    SubShader {
        Tags { "LightMode"="ForwardBase" }
        Pass{
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include"Lighting.cginc"

        fixed4 _Diffuse;
        fixed4 _Specular;
        float  _Gloss;
        struct a2v
        {
        float4 vertex:POSITION;
        float3 normal:NORMAL;
        };

        struct v2f
        {
        float4 pos:SV_POSITION;
        fixed3 worldNormal:TexCOORD0;
        float3 worldPos:TEXCOORD1;
        };
        v2f vert(a2v v)
        {
        v2f o;
        o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
        o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
        o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
        return o;
        }

        fixed4 frag(v2f i):SV_Target
        {
        fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
        fixed3 worldNormal=normalize(i.worldNormal);
        fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
        fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));
        //fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));
        fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
        fixed3 halfDir=normalize(worldLightDir+viewDir);
        fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(worldNormal,halfDir)),_Gloss);
        return fixed4(ambient+diffuse+specular,1.0);
        }
        ENDCG
    }
    }
    FallBack "Specular"
}
Blinn_Phong

 

posted @ 2017-02-27 17:11  露夕逝  阅读(461)  评论(0编辑  收藏  举报