庄懂11/12课作业 食人魔例子

庄懂老师https://space.bilibili.com/6373917?spm_id_from=333.788.b_765f7570696e666f.1

先分析资源

通用的cubemap和fresnel。把透贴放到贴图的alpha里,把R:高光强度,G:边缘光强度,B:高光染色,A高光次幂放到一起

分析光照模型

最终效果和代码

Shader "Unlit/NewUnlitShader" {
    Properties {
    [Header(TEX)]
    _MainTex          ("RGB:颜色,A透明贴图",2d)="white"{}
    _MaskTex          ("R:高光强度,G:边缘光强度,B:高光染色,A高光次幂",2d)="black"{}
    _NormalTex        ("RGB:法线贴图",2d)="bump"{}
    _MatelnessMask    ("金属度贴图",2d)="balck"{}
    _EmissionMask     ("自发光遮罩",2d)="black"{}
    _DiffWarpMask     ("颜色Warp",2d)="gray"{}
    _FresWarpTex      ("菲涅尔Warp",2d)="gray"{}
    _CubeMap          ("环境球",cube)="_Skybox"{}
    [Header(Dirdiff)]
    _LightCol         ("光颜色",color)=(1,1,1,1)
    _EnvCol           ("环境光颜色",color)=(1,1,1,1)
    _EnvInt           ("环境漫反射强度",range(0,5))=0.5
    [Header(Dirspec)]
    _SpecPow          ("高光次幂",range(1,90))=90
    _SpecInt          ("高光强度",range(1,10))=10
    _EnvSpecInt       ("环境镜面反射强度",range(0,10))=1
    [Header(otherl)]
    [HDR]_RimCOl      ("轮廓光强度",color)=(1,1,1,1)
    _EmitInt          ("自发光强度",range(0,10))=1 
    [HideInInspector] 
    _Cutoff           ("Alpha cutoff",range(0,1))=0.5
    _Color            ("Main Color",color)=(1,1,1,1)

    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        LOD 100
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            Cull off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #include "Lighting.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma multi_compile_fog
            #pragma target 3.0
            //输入参数
            //Texture
            uniform sampler2D _MainTex;
            uniform sampler2D _MaskTex;
            uniform sampler2D _NormalTex;
            uniform sampler2D _MatelnessMask;
            uniform sampler2D _EmissionMask;
            uniform sampler2D _DiffWarpMask;
            uniform sampler2D _FresWarpTex;
            uniform samplerCUBE _CubeMap;
            //Dirdiff
            uniform half3 _LightCol;  
            uniform half3 _EnvCol;
            uniform half _EnvInt;
            //Dirspec
            uniform half  _SpecPow; 
            uniform half  _SpecInt;  
            uniform half _EnvSpecInt;
            //自发光和轮廓光
            uniform half3 _RimCOl;
            uniform half _EmitInt;
            uniform half _Cutoff;



            //输入结构
            struct VertexInput {
                float4 vertex : POSITION; //输入模型顶点信息
                float2 uv:TEXCOORD0;
                float4 tangent:TANGENT;
                float3 normal : NORMAL; //输入模型法线信息
            };
            //输出结构
            struct VertexOutput {
                float4 pos : SV_POSITION;   //由模型顶点信息换算的顶点屏幕位置
                float4 posWS : TEXCOORD1;//由模型顶点信息换算的世界顶点信息(vDir =归一化(摄像机位置- posWS))
                float3 nDirWS : TEXCOORD0;   //由模型法线信息换算来的世界空间法线信息
                float2 uv:TEXCOORD2;
                float3 bDirWS :TEXCOORD3;
                float3 tDirWS :TEXCOORD4;
                LIGHTING_COORDS(5, 6)
            };
            //输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;                   //新建输出结构
                o.pos = UnityObjectToClipPos( v.vertex );         //
                o.posWS = mul(unity_ObjectToWorld, v.vertex);       
                o.nDirWS = UnityObjectToWorldNormal(v.normal);      //把模型法线转换成世界空间法线信息
                o.tDirWS = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
                o.bDirWS = normalize(cross(o.nDirWS, o.tDirWS) * v.tangent.w);
                o.uv = v.uv;
                TRANSFER_VERTEX_TO_FRAGMENT(o)


                return o;
            }
            //输出结构>>>像素
            float4 frag(VertexOutput i) : COLOR {
                //向量准备
            half3 nDirTS = UnpackNormal(tex2D(_NormalTex, i.uv));
            half3x3 TBN = half3x3(i.tDirWS,i.bDirWS,i.nDirWS);
            half3 nDirWS = normalize(mul(nDirTS,TBN));
            half3 lDirWS= _WorldSpaceLightPos0.xyz;
            half3 lrDirWS=reflect(-lDirWS,nDirWS);
            half3 vDirWS=normalize(_WorldSpaceCameraPos.xyz - i.posWS);

            half3 vrDirWS=reflect(-vDirWS,nDirWS);
                //中间量准备
            half ndotl =dot(nDirWS,lDirWS);
            half lrdotv=dot(lrDirWS,vDirWS);
            half ndotv=dot(nDirWS,vDirWS);
            //采样纹理
            float4 var_MainTex=tex2D(_MainTex,i.uv);
            float4 var_MaskTex=tex2D(_MaskTex,i.uv);
            float var_MatelnessMask=tex2D(_MatelnessMask,i.uv).r;
            float var_EmissionMask=tex2D(_EmissionMask,i.uv).r;
            float3 var_FresWarpTex=tex2D(_FresWarpTex,ndotv).rgb;//菲涅尔reamtex
            half3 var_CubeMap = texCUBElod(_CubeMap, float4(vrDirWS, lerp(8.0, 0.0, var_MaskTex.a))).rgb;
            //提取信息
            half3 baseCol =var_MainTex.rgb;
            half opacity =var_MainTex.a;
            half specInt =var_MaskTex.r;
            half rimInt =var_MaskTex.g;
            half specTint=var_MaskTex.b;
            half specPow =var_MaskTex.a;
            half matellic=var_MatelnessMask;
            half emitInt=var_EmissionMask;
            half3 envCube=var_CubeMap;
            half shadow = LIGHT_ATTENUATION(i);//投影
            //光照模型
            //漫反射颜色
            half3 diffCol =lerp(baseCol,half3(0,0,0),matellic);//以金属度作为遮罩
            //镜面反射颜色
            half3 specCol =lerp(baseCol,half3(0.3,0.3,0.3),specTint)*specInt;//高光染色做遮罩,再用高光强度叠加
            //菲涅尔
            half3 fresnel =lerp(var_FresWarpTex,0,matellic);//考虑金属,非金属的菲涅尔特性,用金属度做遮罩对Fresnel值做Lerp操作;削弱金属部分Fresnel;
            half fresnelCol =fresnel.r;//无实际用途
            half fresnelRim =fresnel.g;//轮廓光用Fresnel
            half fresnelSpec=fresnel.b;//镜面反射用Fresnel
            //光源漫反射
            half halfLambert =ndotl*0.5+0.5;//半兰伯特
            half3 var_DiffWarpTex =tex2D(_DiffWarpMask,half2(halfLambert,0.2));//半兰伯特构造rampuv,采样ramptex
            half3 dirDiff =diffCol*var_DiffWarpTex*_LightCol;//混合漫反射颜色主光颜色和ramp结果
            //主光镜面反射
            half phone =pow(max(0,lrdotv),specPow*_SpecPow);//高光次幂贴图范围0-1,power使其效果更明显
            half spec =phone*max(0,ndotl);//让兰伯特黑色部分镜面反射也弱一点
            spec =max(spec,fresnelSpec);//和菲涅尔的高光取最大
            spec=spec*_SpecInt;//乘以整体镜面反射强度
            half3 dirSpec=spec*specCol*_LightCol;//和镜面反射颜色(金属染色其余几乎不染色)相乘最后乘光颜色
            //环境漫反射
            half3 envDiff=_EnvCol*_EnvInt*diffCol;//单色环境漫反射*强度*漫反射颜色
            //环境镜面反射
            half reflect =max(fresnelSpec,matellic)*specInt;//用菲涅尔高光和金属度计算整体反射度*镜面反射的遮罩
            half3 envSpec=specCol*reflect*envCube*_EnvSpecInt;//镜面反射颜色*反射度*环境球*环境反射强度
            //轮廓光
            half3 rimLight =_RimCOl*fresnelRim*rimInt*max(0,nDirWS.g);//轮廓光颜色*菲涅尔轮廓光*轮廓光强度*法线的上下遮罩(只取上半部分)
            //自发光
            half3 emission =_EmitInt*diffCol*emitInt;//自发光强度*漫反射颜色*自发光遮罩
            //混合
            half3 finalRGB =(dirDiff+dirSpec)*shadow+envDiff+envSpec+rimLight+emission;//主光部分相加,乘以投影,再依次加上环境光部分,轮廓光,自发光;
            //透明剪切
            clip(opacity-_Cutoff);


            return float4(finalRGB, 1.0);
            }
            ENDCG
        }
    }
    //申明回退Shader
    FallBack "Legacy Shaders/Transparent/Cutout/VertexLit"
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值