Unity的Shader学习笔记(12)[20/12/28_周一][46-50]

目录

课时46:图形学入门-实现phong光照(镜面反射,高光)

课时47:图形学入门-半角向量和BlinnPhong

课时48:FragmentShader-片段级光照1

课时49:FragmentShader-片段级光照2(Specular,PointLight)

课时50:FragmentShader-片段级光照3


昨天带娃、看小说了,没学习....

课时46:图形学入门-实现phong光照(镜面反射,高光)

镜面反光

R和V的夹角,判断是否高亮。

光滑物体,衰减不是线性变化。

向量长度要规范化。

I:光源到顶点的向量

N:法线向量

R:反射向量

UnityObjectToWorldNormal,UnityObjectToWorldDir,UnityWorldSpaceLightDir()

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/NewSurfaceShader8"
{
    Properties
    {
        _SpecularColor("SpecularColor",color)=(1,1,1,1)
        _Shininess("Sphininess",range(1,8))=4
    }
    SubShader
    {
        pass
        {
            tags{"LightMode"="ForwardBase"} 

            CGPROGRAM
            //#pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            #include "Lighting.cginc"
            struct v2f 
            {
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };
            float4 _SpecularColor;
            float _Shininess;
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                

                float3 N=normalize(v.normal);
                N=mul(float4(N,0),unity_WorldToObject).xyz;
                N=normalize(N);

                float3 L=normalize(_WorldSpaceLightPos0);//光照

                //Diffuse Color
                float ndotl=saturate(dot(N,L));
                o.color=_LightColor0*ndotl;//平行光,漫反射


                // float3 wpos=mul(unity_ObjectToWorld,v.vertex).xyz;
                // o.color.rgb+=Shade4PointLights(unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
                //     unity_LightColor[0].rgb,unity_LightColor[1].rgb,unity_LightColor[2].rgb,unity_LightColor[3].rgb,
                //     unity_4LightAtten0,wpos,N);//+点光源

                //镜面反射
                // float3 wpos=mul(unity_ObjectToWorld,v.vertex).xyz;
                // float3 I=wpos-_WorldSpaceLightPos0;
                float3 I=-WorldSpaceLightDir(v.vertex);
                float3 R=reflect(I,N);
                float3 V=WorldSpaceViewDir(v.vertex);
                R=normalize(R);
                V=normalize(V);

                float specularScale=pow(saturate(dot(R,V)),_Shininess);//衰减
                o.color.rgb+=_SpecularColor*specularScale;

                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                return IN.color;//+环境光
            }
            ENDCG
        }

    }
}

课时47:图形学入门-半角向量和BlinnPhong

自己写Reflect函数

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/NewSurfaceShader9"
{
    Properties
    {
        _SpecularColor("SpecularColor",color)=(1,1,1,1)
        _Shininess("Sphininess",range(1,8))=4
    }
    SubShader
    {
        pass
        {
            tags{"LightMode"="ForwardBase"} 

            CGPROGRAM
            //#pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            #include "Lighting.cginc"
            struct v2f 
            {
                float4 pos:POSITION;
                fixed4 color:COLOR;
            };
            float4 _SpecularColor;
            float _Shininess;
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                
                float3 N=UnityObjectToWorldNormal(v.normal);
                float3 L=normalize(WorldSpaceLightDir(v.vertex));//光照

                o.color=UNITY_LIGHTMODEL_AMBIENT;//环境光

                //Diffuse Color
                float ndotl=saturate(dot(N,L));
                o.color+=_LightColor0*ndotl;//平行光,漫反射

                //镜面反射
                float3 I=-WorldSpaceLightDir(v.vertex);
                //float3 R=reflect(I,N);
                float3 R=2 * saturate(dot(N,L))*N - L; //reflect函数
                float3 V=WorldSpaceViewDir(v.vertex);
                R=normalize(R);
                V=normalize(V);

                float specularScale=pow(saturate(dot(R,V)),_Shininess);//衰减
                o.color.rgb+=_SpecularColor*specularScale;

                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                return IN.color;//+环境光
            }
            ENDCG
        }

    }
}

半角向量,设置衰减,避免点积

            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.color=UNITY_LIGHTMODEL_AMBIENT;//环境光

                float3 N=UnityObjectToWorldNormal(v.normal);//法向量
                float3 L=normalize(WorldSpaceLightDir(v.vertex));//光照
                float3 V=normalize(WorldSpaceViewDir(v.vertex));//摄像头
                //Diffuse Color
                float ndotl=saturate(dot(N,L));
                o.color+=_LightColor0*ndotl;//平行光,漫反射
                //Specular Color
                float3 I=-WorldSpaceLightDir(v.vertex);
                float3 H = normalize(L+V);//半角向量
                float specularScale=pow(saturate(dot(H,N)),_Shininess);//衰减
                o.color.rgb+=_SpecularColor*specularScale;
                return o;
            }

L,V,H必须规范化

环境光+漫反射+镜面高光

--------------------------------------------------------------------------------------------------------

课时48:FragmentShader-片段级光照1

顶点函数,性能高,硬件配置比较低,光照效果要求低。

片段函数,细腻的效果,加重GPU负担,现在的硬件设备应该没问题。

            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.normal=UnityObjectToWorldNormal(v.normal);//法向量
                o.lightDir=normalize(WorldSpaceLightDir(v.vertex));//光照
                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                fixed4 color=UNITY_LIGHTMODEL_AMBIENT;

                //Diffuse Color
                //dot(n,l)
                float diffuseScale=saturate(dot(IN.normal,IN.lightDir));
                color+=_LightColor0*diffuseScale;

                return color;//+环境光
            }

一个顶点对应于一片的像素,光栅化处理

vert处理顶点,frag处理像素

插值分割

全面移植

            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.normal=v.normal;//法向量
                o.vertex=v.vertex;//光照
                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                fixed4 color=UNITY_LIGHTMODEL_AMBIENT;//环境光

                //diffuse Color
                float3 N= UnityObjectToWorldNormal(IN.normal);
                float3 L= normalize(WorldSpaceLightDir(IN.vertex));
                float diffuseScale=saturate(dot(N,L));
                color+=_LightColor0*diffuseScale;
                return color;
            }

课时49:FragmentShader-片段级光照2(Specular,PointLight)

完整移植代码

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/NewSurfaceShader10"
{
    Properties
    {
        _MainColor("MainColor",color)=(1,1,1,1)
        _SpecularColor("SpecularColor",color)=(1,1,1,1)
        _Shininess("Sphininess",range(1,8))=4
    }
    SubShader
    {
        pass
        {
            tags{"LightMode"="ForwardBase"} 

            CGPROGRAM
            //#pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag
            #include "unitycg.cginc"
            #include "Lighting.cginc"
            float4 _MainColor;
            float4 _SpecularColor;
            float _Shininess;
            struct v2f 
            {
                float4 pos:POSITION;
                float3 normal:TEXCOORD0;
                fixed4 vertex:COLOR;
            };
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos=UnityObjectToClipPos(v.vertex);
                o.normal=v.normal;//法向量
                o.vertex=v.vertex;//原始坐标
                return o;
            }
            fixed4 frag(v2f IN):COLOR
            {
                fixed4 color=UNITY_LIGHTMODEL_AMBIENT;//环境光

                //diffuse Color
                float3 N= UnityObjectToWorldNormal(IN.normal);
                float3 L= normalize(WorldSpaceLightDir(IN.vertex));
                float diffuseScale=saturate(dot(N,L));
                color+=_MainColor*_LightColor0*diffuseScale;

                //Specular Color
                float3 V= normalize(WorldSpaceViewDir(IN.vertex));
                float3 R= 2*dot(N,L)*N-L;
                float specularScale=saturate(dot(R,V));
                color+=_SpecularColor*pow(specularScale,_Shininess);

                //compute 4 points lighting;
                float3 wpos=mul(unity_ObjectToWorld,IN.vertex).xyz;
                color.rgb+=Shade4PointLights(unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
                    unity_LightColor[0].rgb,unity_LightColor[1].rgb,unity_LightColor[2].rgb,unity_LightColor[3].rgb,
                    unity_4LightAtten0,wpos,N);//+点光源

                return color;
            }
            ENDCG
        }

    }
}

课时50:FragmentShader-片段级光照3

添加阴影

1.投射阴影

shadowmap

添加一个空的pass

        pass
        {
            tags{"LightMode"="shadowcaster"}
        }

和教程不同,这个加了后,2020.1,地面上平行光和点光源的阴影都有了。

或者加上

fallback "Diffuse" //不能小写

这集有些水了,和下一集合并就好了嘛

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值