CookTorrance与Blinn-Phone光照模型的一些区别

时间:2023-03-21   阅读次数:

不仔细看时,在某些情形下区别不太明显,但把粗糙度或是光泽度做调整时,就能明显感觉到变化还是比较大的。如下图,翅膀的高光变化,右图只能调光泽无法把光分布到周边。

1679373135884119.png

在调整翅膀的效果时,右侧图只能收窄高光度


shader_cooktorrance1.png

把粗糙度调低时,怪物身上的效果对比就非常明显


Properties
    {
        [Enum(Off,0,On,1)]_ZWriteMode("ZWriteMode",float)=1
        [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("SrcBlend",float)=1
        [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("DstBlend",float)=0
        [Space(30)]
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}

        _DiffColor("Color",Color)=(1,1,1,1)
        [Normal]_BumpMap("BumpMap",2D)="white"{}
        _BumpScale("BumpScale",Range(0,1))=1
        [Header(___Specular___)]
        [Space(10)]
        _SpecularColor("SpecularColor",Color)=(1,1,1,1)
       
        [Header(Fresnel)]
        _FresnelScale("FresnelScale",Range(0,1))=0.5
        _Mm("光泽度",Range(0,1))=0.5
    }
    SubShader
    {
        Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
        Pass
        {
            Tags{"LightMode"="ForwardBase"}
            ZWrite [_ZWriteMode]
            Blend [_SrcBlend] [_DstBlend]
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal:NORMAL;
                float4 tangent:TANGENT;
            };

            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                float4 wwt0:TEXCOORD1;
                float4 wwt1:TEXCOORD2;
                float4 wwt2:TEXCOORD3;
                float4 mask:TEXCOORD4;
            };

            sampler2D _MainTex,_BumpMap;
            float4 _MainTex_ST,_BumpMap_ST;
            float4 _DiffColor,_SpecularColor;
            float _BumpScale,_FresnelScale;
            float _Mm;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv.xy = TRANSFORM_TEX(v.uv,_MainTex);
                o.uv.zw = TRANSFORM_TEX(v.uv,_BumpMap);

                float3 wPos=mul(unity_ObjectToWorld,v.vertex).xyz;
                float3 wN=UnityObjectToWorldNormal(v.normal);
                float3 wT=UnityObjectToWorldDir(v.tangent).xyz;
                float3 wB=cross(wN,wT)*v.tangent.w;
                o.wwt0=float4(wT.x,wB.x,wN.x,wPos.x);
                o.wwt1=float4(wT.y,wB.y,wN.y,wPos.y);
                o.wwt2=float4(wT.z,wB.z,wN.z,wPos.z);
                return o;
            }


            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col=1;
                fixed3 wP=float3(i.wwt0.w,i.wwt1.w,i.wwt2.w);
                fixed3 L=normalize(UnityWorldSpaceLightDir(wP));
                fixed3 V=normalize(UnityWorldSpaceViewDir(wP));
                fixed4 mainTex = tex2D(_MainTex, i.uv.xy); //贴图
                fixed4 bumpTex=tex2D(_BumpMap,i.uv.zw);
                fixed3 texN=UnpackNormal(bumpTex);
                //法线贴图
                texN.xy*=_BumpScale;
                texN.z=sqrt(1-saturate(dot(texN.xy,texN.xy)));
                texN=normalize(half3(dot(i.wwt0.xyz,texN),dot(i.wwt1.xyz,texN),dot(i.wwt2.xyz,texN)));
                float3 wN=texN;
               
                float nl=max(dot(L,wN),0);
                fixed3 dif=_LightColor0.rgb*_DiffColor.rgb * nl *0.5+0.5; //漫反射
                dif*=mainTex.rgb;

                fixed3 H=normalize(L+V);
                float3 specular=float3(0.0,0.0,0.0);
                float nv=dot(wN,V);
                bool back=(nv>0) && (nl>0);
                if(back){
                    float nh=dot(wN,H);
                    float temp=(nh*nh-1)/(_Mm*_Mm*nh*nh);
                    float roughness=(exp(temp))/(pow(_Mm,2)*pow(nh,4.0));   //粗糙度

                    float vh=dot(V,H);
                    float a=(2*nh*nv)/vh;
                    float b=(2*nh*nl)/vh;
                    float geometric=min(a,b);
                    geometric=min(1,geometric); //几何衰减

                    float fresnelCoe=_FresnelScale+(1-_FresnelScale)*pow(1-vh,5.0); //Fresnel 反射
                    float rs=(fresnelCoe*geometric*roughness)/nv*nl;
                    specular=rs*_LightColor0.rgb*nl*_SpecularColor.rgb;
                }

                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;    //环境光

                col.rgb=dif+specular+ambient;
                col.a=mainTex.a;
                return fixed4(col);
            }
            ENDCG
        }
    }


代码原型:《GPU编程与CG语言之阳春白雪下里巴人》

其它文章