zoukankan      html  css  js  c++  java
  • Unity里基础光照(Lambert、Phong、BlinnPhong模型)的Shader代码

    //以下是各种光照模型(Lambert、Phong、BlinnPhong、Gourand)的Shader代码,在Unity里创建一个Material后可以选择使用,各行代码都有注释,不再详细解释了。

    Shader "MyShader/BaseShader"
    {
    //包含Lambert、Phone、Blin-Phong模型
        Properties
        {//定义属性
            _Diffuse("Diffuse",Color) = (1,1,1,1)
            _Specular("Specular",Color) = (1,1,1,1)
            _Gloss("Gloss",Range(5,255)) = 5
            [Toggle(_Phong)] _Phong("Phong",float) = 1
            [Toggle(BlinnPhong)] _BlinnPhong("BlinnPhong",float) = 1
            _MainTex ("Texture", 2D) = "white" {}
        }

        SubShader
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"} //定义Tag
            //LOD 100

            Pass
            {
                CGPROGRAM
                #include "UnityCG.cginc"    //库函数
                #include "Lighting.cginc"
                //定义触发器,改变光照模型
                #pragma shader_feature _PHONG
                #pragma shader_feature _BLINNPHONG
                #pragma shader_feature _LAMBERT
                #pragma shader_feature _GOURAND
                
                #pragma vertex vert //顶点着色器名称
                #pragma fragment frag   //片元着色器名称
      
                float4 _Diffuse;    //全局参数,漫反射、高光颜色、高光参数
                float4 _Specular;
                float _Gloss;

                struct a2v
                {//应用传入顶点着色器的变量
                    float4 vertex : POSITION;
                    float3 normal :NORMAL;
                    float2 uv : TEXCOORD0;
                };

                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float3 worldNormal: NORMAL;
                    float3 worldPos: TEXCOORD1;
                    float3 color: TEXCOORD2;                
                };

                sampler2D _MainTex;
                float4 _MainTex_ST;

                v2f vert (a2v v)
                {//顶点着色器
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);  //顶点空间到裁剪空间
                    //o.worldNormal = normalize(mul(v.normal,(float 3x3) unity_worldTo));
                    o.worldNormal = UnityObjectToWorldNormal(v.normal);   //法线转换到世界空间
                    o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;   //顶点位置转换到世界空间

                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                    #if defined(_GOURAND)
                        float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Diffuse;    //环境光
                        float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);    //归一化光方向
                        float3 worldNormal = normalize(o.worldNormal);              //归一化worldNormal
                        float NdotL = max(0, dot(worldLight, worldNormal));         //法线和光线的点积,即余弦值
                        float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * NdotL;    //计算漫反射Lambert
                        float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - o.worldPos.xyz);  //视角方向
                        float3 reflectDir = normalize(reflect(-worldLight,worldNormal));  //计算反射方向,worldLight表示入射光方向
                        float VdotR = max(0, dot(reflectDir, viewDir));         //反射光方向与观察方向的夹角,点积结果为夹角的余弦值
                        float3 specular = _LightColor0.rgb * _Specular.rgb * pow(VdotR, _Gloss);    //高光值
                        o.color = diffuse + ambient + specular;     //Gourand模型最后输出的颜色值
                    #endif
                    return o;
                }

                fixed4 frag (v2f i) : SV_Target
                {//片元着色器
                    // sample the texture
                    //fixed4 col = tex2D(_MainTex, i.uv);
                    float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Diffuse;     //环境光
                    float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);       //归一化光方向
                    float3 worldNormal = normalize(i.worldNormal);                //归一化worldNormal
                    float NdotL = max(0, dot(worldNormal,worldLight));             //计算漫反射Lambert公式
                    fixed4 renderTex = tex2D(_MainTex, i.uv);  

                    float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * NdotL;         //计算Diffuse光
                    float3 specular;    //存储高光值
                    float3 color;       //存储最终颜色值

                    float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);  //归一化视方向
                    #if defined(_LAMBERT)
                        color = diffuse;    //Lambert模型
                    #endif
                    
                    //#if defined(_PHONG)
                      //Phong模型计算
                        float3 reflectDir = normalize(reflect(-worldLight,worldNormal));    //计算反射方向,worldLight表示入射光方向
                        float VdotR = max(0, dot(viewDir,reflectDir));   //反射光方向与观察方向的夹角,dot(ViewDir,ReflectDir)
                        specular = _LightColor0.rgb * _Specular.rgb * pow(VdotR, _Gloss); //计算高光反射
                        color = ambient + diffuse + specular;
                    //#endif
                    
                    #if defined(_BLINNPHONG)
                       //BlinnPhong模型计算
                        float3 halfDir = (worldLight +viewDir);  //计算半角向量,光线方向+视方向的结果归一化
                        float NdotH = saturate(dot(halfDir,worldNormal));   //半角向量与法线方向的点积,结果归一化
                        specular = _LightColor0.rgb * _Specular.rgb * pow(NdotH, _Gloss);   //计算BlinnPhong的高光值
                        color = ambient + diffuse + specular;
                    #endif
                    
                    #if defined(_GOURAND)
                        color = i.color;    //直接使用顶点着色器中计算出来的颜色值
                    #endif
                    color = color * renderTex.rgb;
                    return fixed4(color,1.0);
                }
                ENDCG
            }
        }
    }

    每日进步一点点
  • 相关阅读:
    robotframework----模板的使用
    RF执行顺序
    RobotFrameWork(四)变量运算与Evaluate
    RobotFrameWork(三)数据类型
    git 命令
    常用网站
    git 应用
    ie if判断
    移动端rem适配
    绘制三角形(sass)
  • 原文地址:https://www.cnblogs.com/laoyueblogs/p/15805672.html
Copyright © 2011-2022 走看看