zoukankan      html  css  js  c++  java
  • 三种光照模型的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
  • 相关阅读:
    链表VS数组
    数组VS集合
    最好、最坏、平均、均摊时间复杂度
    代码时间、空间复杂度分析
    “echo >”和“echo >>”的区别
    两数之和
    hadoop学习之----------IntelliJ IDEA上实现MapReduce中最简单的单词统计的程序(本地 和 hadoop 两种实现方式)
    Ubuntu16.04中解决关于The Internet Topology Zoo 的gml文件的读取并画图的问题
    Ubuntu16.04解决Ubuntu Sofware打开后无反应
    Ubuntu16.04中如何启用floodlight的一种方式
  • 原文地址:https://www.cnblogs.com/luxishi/p/6475282.html
Copyright © 2011-2022 走看看