【shader】基础光照模型

兰伯特光照模型,高洛德着色

Shader "Custom/Shader3"
{
    Properties
    {
        _DiffuseColor("漫反射颜色",Color)=(1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            //设定光照模型为向前模式(才能正常获取光的颜色和光的方向)
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //加载cg语言的脚本,用来处理光照参数
            //处理光照的cg库文件(cginc扩展名),目录在unity安装目录下Editor/Data/CGIncludes/Lighting.cginc
            #include "Lighting.cginc"

            //导入材质颜色
            fixed4 _DiffuseColor;

            //如果在cg编程中,顶点或者片元着色器接收多个参数的时候,一般会用结构体去实现
            struct c2v
            {
                float4 vertex:POSITION;//从cpu接收模型空间下的点的位置
                float3 normal:NORMAL;//从cpu接收模型空间下的法线向量
            };

            struct v2f
            {
                float4 pos:SV_POSITION;//经过顶点着色器计算后的裁剪空间下的位置
                fixed3 color:COLOR;//经过兰伯特定律计算后的点的颜色
            };

            //使用高洛德着色,计算颜色写在顶点着色器中
            v2f vert(c2v data)
            {
                v2f r;
                //将点从模型空间转换到裁剪空间
                r.pos = UnityObjectToClipPos(data.vertex);

                //兰伯特光照模型计算
                //漫反射光照=光源的颜色*材质的漫反射颜色*MAX(0,标准化后物体表面法线向量·标准化后光源方向向量)

                //光照是在世界中发生的,需要将所有的数值,变换到世界坐标系下,再运算
                fixed3 wordNormal1 = normalize(mul((float3x3)unity_ObjectToWorld, data.normal));
                //获得直射光的光方向
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                //公式运算
                fixed3 diffuse = _LightColor0.rbg * _DiffuseColor.rbg * max(0, dot(wordNormal1, worldLightDir));
                //将环境光追加在计算后的颜色上
                r.color = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuse;
                return r;
            }

            fixed4 frag(v2f data):SV_Target
            {
                return fixed4(data.color, 1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

兰伯特光照模型,phong着色

Shader "Custom/Shader4"
{
    Properties
    {
        _DiffuseColor("漫反射颜色",Color)=(1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            //设定光照模型为向前模式(才能正常获取光的颜色和光的方向)
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //加载cg语言的脚本,用来处理光照参数
            //处理光照的cg库文件(cginc扩展名),目录在unity安装目录下Editor/Data/CGIncludes/Lighting.cginc
            #include "Lighting.cginc"

            //导入材质颜色
            fixed4 _DiffuseColor;

            //如果在cg编程中,顶点或者片元着色器接收多个参数的时候,一般会用结构体去实现
            struct c2v
            {
                float4 vertex:POSITION; //从cpu接收模型空间下的点的位置
                float3 normal:NORMAL; //从cpu接收模型空间下的法线向量
            };

            struct v2f
            {
                float4 pos:SV_POSITION; //经过顶点着色器计算后的裁剪空间下的位置
                fixed3 wordNormal1:NORMAL; //经过变换后的世界空间下的法线向量
            };

            v2f vert(c2v data)
            {
                v2f r;
                //将点从模型空间转换到裁剪空间
                r.pos = UnityObjectToClipPos(data.vertex);
                //光照是在世界中发生的,需要将所有的数值,变换到世界坐标系下,再运算
                r.wordNormal1 = normalize(mul((float3x3)unity_ObjectToWorld, data.normal));
                return r;
            }

            //使用冯着色,计算颜色写在顶点着色器中
            fixed4 frag(v2f data):SV_Target
            {
                //兰伯特光照模型计算
                //漫反射光照=光源的颜色*材质的漫反射颜色*MAX(0,标准化后物体表面法线向量·标准化后光源方向向量)

                //获得直射光的光方向
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                //公式运算
                fixed3 diffuse = _LightColor0.rbg * _DiffuseColor.rbg * max(0, dot(data.wordNormal1, worldLightDir));
                //将环境光追加在计算后的颜色上
                fixed3 color = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuse;
                return fixed4(color, 1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

半兰伯特光照模型

Shader "Custom/Shader5"
{
    Properties
    {
        _DiffuseColor("漫反射颜色",Color)=(1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            //设定光照模型为向前模式(才能正常获取光的颜色和光的方向)
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //加载cg语言的脚本,用来处理光照参数
            //处理光照的cg库文件(cginc扩展名),目录在unity安装目录下Editor/Data/CGIncludes/Lighting.cginc
            #include "Lighting.cginc"

            //导入材质颜色
            fixed4 _DiffuseColor;

            //如果在cg编程中,顶点或者片元着色器接收多个参数的时候,一般会用结构体去实现
            struct c2v
            {
                float4 vertex:POSITION; //从cpu接收模型空间下的点的位置
                float3 normal:NORMAL; //从cpu接收模型空间下的法线向量
            };

            struct v2f
            {
                float4 pos:SV_POSITION; //经过顶点着色器计算后的裁剪空间下的位置
                fixed3 wordNormal1:NORMAL; //经过变换后的世界空间下的法线向量
            };

            v2f vert(c2v data)
            {
                v2f r;
                //将点从模型空间转换到裁剪空间
                r.pos = UnityObjectToClipPos(data.vertex);
                //几何运算,在顶点着色器中完成
                //光照是在世界中发生的,需要将所有的数值,变换到世界坐标系下,再运算
                r.wordNormal1 = normalize(mul((float3x3)unity_ObjectToWorld, data.normal));
                return r;
            }

            //使用冯着色,计算颜色写在顶点着色器中
            fixed4 frag(v2f data):SV_Target
            {
                //半兰伯特光照模型计算
                //漫反射光照=光源的颜色*材质的漫反射颜色*MAX(0,标准化后物体表面法线向量·标准化后光源方向向量)

                //获得直射光的光方向
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                //公式运算
                fixed3 diffuse = _LightColor0.rbg * _DiffuseColor.rbg * max(
                    0, dot(data.wordNormal1, worldLightDir) * 0.5 + 0.5);
                //将环境光追加在计算后的颜色上
                fixed3 color = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuse;
                return fixed4(color, 1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

高光反射,高洛德着色

Shader "Custom/Shader6"
{
    Properties
    {
        _SpecularColor("高光反射颜色",Color)=(1,1,1,1)
        _Gloss("光晕系数",Range(8,255))=10
    }
    SubShader
    {
        Pass
        {
            //设定光照模型为向前模式(才能正常获取光的颜色和光的方向)
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //加载cg语言的脚本,用来处理光照参数
            //处理光照的cg库文件(cginc扩展名),目录在unity安装目录下Editor/Data/CGIncludes/Lighting.cginc
            #include "Lighting.cginc"

            //导入材质颜色
            fixed4 _SpecularColor;
            //导入光晕大小系数
            float _Gloss;

            //如果在cg编程中,顶点或者片元着色器接收多个参数的时候,一般会用结构体去实现
            struct c2v
            {
                float4 vertex:POSITION; //从cpu接收模型空间下的点的位置
                float3 normal:NORMAL; //从cpu接收模型空间下的法线向量
            };

            struct v2f
            {
                float4 pos:SV_POSITION; //经过顶点着色器计算后的裁剪空间下的位置
                fixed3 color:COLOR; //经过高光反射以后计算的当前点的颜色
            };

            //逐顶点
            v2f vert(c2v data)
            {
                v2f r;
                //将点从模型空间转换到裁剪空间
                r.pos = UnityObjectToClipPos(data.vertex);
                //高光反射计算
                //高光光照=光源的颜色*材质的高光反射颜色*(MAX(0,标准化后的观察方向向量·标准化后的反射方向))^光晕系数
                //光反射方向:reflect(入射光的方向,当前点的法线方向)

                //观察方向(相机的位置-被渲染点的位置)
                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, data.vertex).xyz);
                //光反射方向
                fixed3 refDir = normalize(
                    reflect(-_WorldSpaceLightPos0, mul((float3x3)unity_ObjectToWorld, data.normal)));
                fixed3 specular = _LightColor0.rbg * _SpecularColor.rbg * pow(max(0, dot(viewDir, refDir)), _Gloss);
                r.color = UNITY_LIGHTMODEL_AMBIENT.xyz + specular;
                return r;
            }

            fixed4 frag(v2f data):SV_Target
            {
                return fixed4(data.color, 1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

高光反射,phong着色

Shader "Custom/Shader7"
{
    Properties
    {
        _SpecularColor("高光反射颜色",Color)=(1,1,1,1)
        _Gloss("光晕系数",Range(8,255))=10
    }
    SubShader
    {
        Pass
        {
            //设定光照模型为向前模式(才能正常获取光的颜色和光的方向)
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //加载cg语言的脚本,用来处理光照参数
            //处理光照的cg库文件(cginc扩展名),目录在unity安装目录下Editor/Data/CGIncludes/Lighting.cginc
            #include "Lighting.cginc"

            //导入材质颜色
            fixed4 _SpecularColor;
            //导入光晕大小系数
            float _Gloss;

            //如果在cg编程中,顶点或者片元着色器接收多个参数的时候,一般会用结构体去实现
            struct c2v
            {
                float4 vertex:POSITION; //从cpu接收模型空间下的点的位置
                float3 normal:NORMAL; //从cpu接收模型空间下的法线向量
            };

            struct v2f
            {
                float4 pos:SV_POSITION; //经过顶点着色器计算后的裁剪空间下的位置
                float4 worldPos:TEXCOORD0; //借用纹理的语义,实现世界空间下,点的位置的传送
                fixed3 normal:NORMAL; //世界坐标下,法线的方向
            };

            //逐顶点
            v2f vert(c2v data)
            {
                v2f r;
                //将点从模型空间转换到裁剪空间
                r.pos = UnityObjectToClipPos(data.vertex);

                r.worldPos = mul(unity_ObjectToWorld, data.vertex);
                r.normal = mul((float3x3)unity_ObjectToWorld, data.normal);
                return r;
            }

            fixed4 frag(v2f data):SV_Target
            {
                //高光反射计算
                //高光光照=光源的颜色*材质的高光反射颜色*(MAX(0,标准化后的观察方向向量·标准化后的反射方向))^光晕系数
                //光反射方向:reflect(入射光的方向,当前点的法线方向)

                //观察方向(相机的位置-被渲染点的位置)
                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - data.worldPos.xyz);
                //光反射方向
                fixed3 refDir = normalize(reflect(-_WorldSpaceLightPos0, data.normal));
                fixed3 specular = _LightColor0.rbg * _SpecularColor.rbg * pow(max(0, dot(viewDir, refDir)), _Gloss);
                fixed3 color = UNITY_LIGHTMODEL_AMBIENT.xyz + specular;
                return fixed4(color, 1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

phong光照模型,phong着色

Shader "Custom/Shader8"
{
    Properties
    {
        _DiffuseColor("漫反射颜色",Color)=(1,1,1,1)
        _SpecularColor("高光反射颜色",Color)=(1,1,1,1)
        _Gloss("光晕系数",Range(8,255))=10
    }
    SubShader
    {
        Pass
        {
            //设定光照模型为向前模式(才能正常获取光的颜色和光的方向)
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //加载cg语言的脚本,用来处理光照参数
            //处理光照的cg库文件(cginc扩展名),目录在unity安装目录下Editor/Data/CGIncludes/Lighting.cginc
            #include "Lighting.cginc"

            //导入材质颜色
            fixed4 _DiffuseColor;
            //导入材质颜色
            fixed4 _SpecularColor;
            //导入光晕大小系数
            float _Gloss;

            //如果在cg编程中,顶点或者片元着色器接收多个参数的时候,一般会用结构体去实现
            struct c2v
            {
                float4 vertex:POSITION; //从cpu接收模型空间下的点的位置
                float3 normal:NORMAL; //从cpu接收模型空间下的法线向量
            };

            struct v2f
            {
                float4 pos:SV_POSITION; //经过顶点着色器计算后的裁剪空间下的位置
                float4 worldPos:TEXCOORD0; //借用纹理的语义,实现世界空间下,点的位置的传送
                fixed3 normal:NORMAL; //世界坐标下,法线的方向
            };

            //逐顶点
            v2f vert(c2v data)
            {
                v2f r;
                //将点从模型空间转换到裁剪空间
                r.pos = UnityObjectToClipPos(data.vertex);

                r.worldPos = mul(unity_ObjectToWorld, data.vertex);
                r.normal = mul((float3x3)unity_ObjectToWorld, data.normal);
                return r;
            }

            fixed4 frag(v2f data):SV_Target
            {
                //高光反射计算
                //高光光照=光源的颜色*材质的高光反射颜色*(MAX(0,标准化后的观察方向向量·标准化后的反射方向))^光晕系数
                //光反射方向:reflect(入射光的方向,当前点的法线方向)

                //观察方向(相机的位置-被渲染点的位置)
                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - data.worldPos.xyz);
                //光反射方向
                fixed3 refDir = normalize(reflect(-_WorldSpaceLightPos0, data.normal));
                fixed3 specular = _LightColor0.rbg * _SpecularColor.rbg * pow(max(0, dot(viewDir, refDir)), _Gloss);


                //兰伯特光照模型计算
                //漫反射光照=光源的颜色*材质的漫反射颜色*MAX(0,标准化后物体表面法线向量·标准化后光源方向向量)

                //获得直射光的光方向
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                //公式运算
                fixed3 diffuse = _LightColor0.rbg * _DiffuseColor.rbg * max(0, dot(data.normal, worldLightDir));


                fixed3 color = UNITY_LIGHTMODEL_AMBIENT.xyz + specular + diffuse;
                //将环境光追加在计算后的颜色上
                return fixed4(color, 1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

效果


六种光照模型从左到右依次对应

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值