Shader Forge初学者——镜面反射002

一、常用向量

  1. nDir:法线方向;
  2. LDir:光照方向;
  3. vDir:观察方向;
  4. rDir:光反射方向;
  5. hDir:半角方向(Halfway),LDir和vDir的中间角方向;

二、所在空间

  1. OS:ObjectSpace物体空间,本地空间;
  2. WS:WorldSpace世界空间;
  3. VS:ViewSpace观察空间;
  4. CS:HomogenousClipSpace齐次剪裁空间;
  5. TS:TangentSpace切线空间;
  6. TXS:TextureSpace纹理空间。

例如:nDirWS:世界空间下的法线方向。

三、镜面反射——Specular

  1. 因其反射有明显方向性,所以观察者的视角决定了反射光线的有无,明暗;
  2. 实现方式:
    1. Phong(r dot v):即光反射方向和视角方向越重合,反射越强;
      Phong
      ​​​​​
    2. Blinn-Phong(n dot h):即法线方向和半角方向越重合,反射越强;
      Blinn-Phong

四、实现方式

1)Phong(r dot v)

光反射方向计算:rDir=Reflect(-LDir,nDir);

        a.ShaderForge节点:

镜面反射——Phong的实现方式​​​​​

        b.脚本实现

//镜面反射——Phong

Shader "Shader/U3D_003" {
    Properties {

    _MainColor("颜色",COLOR)=(1.0,1.0,1.0,1.0)
    _SpecualrPow("高光次幂",range(1,90))=30

    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            uniform float3 _MainColor;
            uniform float _SpecualrPow;


            //输入结构
            struct VertexInput {   
                float4 vertex : POSITION;   
                float3 normal : NORMAL;     
            };
            //输出结构
            struct VertexOutput {   
                float4 posCS : SV_POSITION;   
                float4 posWS:TEXCOORD0;
                float3 nDirWS:TEXCOORD1;     
            };
            //输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;    
                o.posCS = UnityObjectToClipPos( v.vertex );      
               o.posWS=mul(unity_ObjectToWorld, v.vertex); 
                o.nDirWS=UnityObjectToWorldNormal(v.normal);    
                return o;   //将输出结构 输出
            }
            //输出结构>>像素Shader
            float4 frag(VertexOutput i) : COLOR {   

                //准备向量
                float3 nDir=i.nDirWS;    
                float3 lDir=normalize(_WorldSpaceLightPos0.xyz);  
                float3 rDir=reflect(-lDir,nDir);
                float3 vDir=normalize(_WorldSpaceCameraPos.xyz-i.posWS.xyz);

                //准备点积结果
                float rDotv=dot(rDir,vDir);
                float nDotl=dot(nDir,lDir);

                //光照模型
                float Phong=pow(max(0.0,rDotv),_SpecualrPow);
                float lambert=max(0.0,nDotl); 
                float3 finalRGB=_MainColor*lambert+Phong;
                return float4(finalRGB,1.0); //输出其最终颜色
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

2)Blinn-Phong(n dot h)

        a.ShaderForge节点:

镜面反射——Blinn-Phong的实现方式

        b.脚本实现:


//镜面反射-Blinn-Phong Shader

Shader "Shader/U3D_002" {
    Properties {
        //暴露参数:高光次幂,基本颜色属性
        //格式:_名称("面板标签",类型(参数,可无))=默认值
        _MainColor("颜色",          COLOR)          =(1.0,1.0,1.0,1.0)
        _SpecularPow("高光次幂",    range(1,90))    =30
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            //参数声明  先声明才能使用

            //规则:要和Properties段定义的参数一一对应
            //      适当选取数据类型

            //修饰字   a.uniform 共享于vert,frag
            //         b.attribute 仅用于vert
            //         c.varing 用于vert,frag传数据
            uniform float3 _MainColor;
            uniform float _SpecularPow;

            //输入结构
            struct VertexInput {   
                float4 vertex : POSITION;   //顶点信息 Get✔
                float3 normal : NORMAL;     //法线信息 Get✔
            };
            //输出结构
            struct VertexOutput {   
                float4 posCS : SV_POSITION;       //屏幕空间 顶点位置
                float4 posWS : TEXCOORD0;         //世界空间 顶点位置
                float3 nDirWS:TEXCOORD1;          //世界空间 法线方向
            };
            //输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;                      //新建输出结构
                o.posCS = UnityObjectToClipPos( v.vertex );           //变换顶点位置 OS>CS
                o.posWS=mul(unity_ObjectToWorld, v.vertex);          //变换顶点位置  OS>WS
                o.nDirWS=UnityObjectToWorldNormal(v.normal);         //变换法线方向  OS>WS
                return o;                                            //返回输出结构
            }
            //输出结构>>像素Shader
            float4 frag(VertexOutput i) : COLOR {   

                //准备向量
                float3 nDir=i.nDirWS;                                           //获取nDir
                float3 lDir=_WorldSpaceLightPos0.xyz;                           //获取IDir
                float3 vDir=normalize(_WorldSpaceCameraPos.xyz-i.posWS.xyz);    //获取vDir
                float3 hDir=normalize(vDir+lDir);                               //获取hDir

                //准备点积结果
                float nDotl=dot(nDir,lDir);                         //nDir点乘IDir
                float nDotH=dot(nDir,hDir);                          //nDir点乘HDir

                //光照模型
                float lambert=max(0.0,nDotl);                           //截断负值
                float blinnPhong=pow(max(0.0,nDotH),_SpecularPow);      //获取blinnPhong值
                float3 finalRGB=_MainColor*lambert+blinnPhong;          //混合颜色
                
                //返回结果
                return float4(finalRGB,1.0);                        //输出其最终颜色
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

 3)区别对比

        a.计算过程上:Phong比Blinn-Phong更消耗性能一点

        b.效果上:差不多,在逆光上Phong会更好看。

左:Blinn-Phong,中:Phong​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逗自己玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值