Chicken shader: L6 character material base model and three transparent special effects AC, AB and AD

character base model

insert image description here

  • Here is the homework assigned by the teacher. It is required to combine all the models learned before to form a basic character material model.
  • During the homework class here, the teacher used several stickers, which are useless for me, and my art skills are not enough (damn it!) Later, I still need to find some tutorials to learn more about art, at least to learn how to draw stickers.

Unity practice to see the realization

Let’s take a look at the Lianliankan of unity:
the first is the processing of the normal map, which will be used as the subsequent normal:
insert image description here

Then there is the diffuse reflection and specular reflection part of the light source part, and the projection part needs to be added:
insert image description here

  • Here we need to explain, in fact, ambient light does not have light attenuation. We use shader forge to see that the material looks shadowed. It should be because the code generated by shader forge has written two passes. One pass is our material realization, and the other pass is purely for realizing the shadow of the model.
  • After reading lesson 12, I said that it seems to be because of the fallback added in the second pass, and at present, only the double pass method can add projection to the object illuminated by direct light.
    insert image description here

Then there is the diffuse reflection part of the ambient light, that is, the three-color ambient light model:
insert image description here
then there is the specular reflection part of the ambient light, which is the cubemap part learned before, and the fresnel part needs to be added:
insert image description here

Finally, the Lianliankan processing of the two parts of lighting and environment:
insert image description here

Code

Code implemented by myself:

Shader "shader forge/L10_OldSchoolWithCubemap"
{
    
    
    Properties
    {
    
    
        //_MainTex ("Base Texture", 2D) = "white" {}
        [Header(Texture)]
        _AO_Tex ("AO_Tex", 2D) = "white" {
    
    }
        _normal ("normal", 2D) = "bump" {
    
    }
        _cubemap ("cubemap", Cube) = "_Skybox" {
    
    }

        [Header(Lighting)]
        _L_Lambert_Color ("L_Lambert_Color", Color) = (0.5,0.5,0.5,1)
        _L_Specular_Color ("L_Specular_Color", Color) = (0.5,0.5,0.5,1)
        _Light_Color ("Light_Color", Color) = (0.5,0.5,0.5,1)

        [Header(Diffuse)]
        _E_Lambert_UpColor ("E_Lambert_UpColor", Color) = (0.8679245,0.5444998,0.5444998,1)
        _E_Lambert_DownColor ("E_Lambert_DownColor", Color) = (0.4400143,0.6626909,0.9056604,1)
        _E_Lambert_MidColor ("E_Lambert_MidColor", Color) = (0.4800081,0.8962264,0.4016109,1)

        [Header(Specular)]
        _mipmap_level ("mipmap_level", Range(0, 7)) = 0
        _fresnel_exp ("fresnel_exp", Range(0, 90)) = 0.6956522
        _Env_SpecInt ("Env_SpecInt", Range(0, 5)) = 0.7826087
        _Phong_Int ("Phong_Int", Range(0, 90)) = 5
    }
    SubShader
    {
    
    
        Tags {
    
     "RenderType"="Opaque" }
        LOD 100

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
             #include "AutoLight.cginc"
            #include "Lighting.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

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

            struct v2f
            {
    
    
                float2 uv0 : TEXCOORD0;                
                float4 pos : SV_POSITION;
                float4 posWorld : TEXCOORD1;
                float3 nDirWS : TEXCOORD2;
                float3 tDirWS : TEXCOORD3;
                float3 biDirWS : TEXCOORD4;
                LIGHTING_COORDS(5,6)
            };

            //Texture
            uniform sampler2D _AO_Tex;
            uniform sampler2D _normal;
            uniform samplerCUBE _cubemap;
            //Lighting
            uniform float4 _L_Lambert_Color;
            uniform float4 _L_Specular_Color;
            uniform float4 _Light_Color;
            //Diffuse
            uniform float4 _E_Lambert_UpColor;
            uniform float4 _E_Lambert_DownColor;
            uniform float4 _E_Lambert_MidColor;
            //Specular
            uniform float _mipmap_level;
            uniform float _fresnel_exp;
            uniform float _Env_SpecInt;
            uniform float _Phong_Int;


            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv0 = v.uv0;
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                o.nDirWS = UnityObjectToWorldNormal(v.normal);
                o.tDirWS = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0.0)).xyz);
                o.biDirWS = normalize(cross(o.nDirWS,o.tDirWS) * v.tangent.w);
                TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                //贴图采样
                float3 nDirTS = UnpackNormal(tex2D(_normal,i.uv0)).rgb;
                float AO_R = tex2D(_AO_Tex,i.uv0);            

                //向量准备
                float3x3 TBN_Matrix = float3x3(i.tDirWS,i.biDirWS,i.nDirWS);
                float3 nDirWS_FT = normalize(mul(nDirTS, TBN_Matrix));
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float3 halfDir = normalize(lightDir + viewDir);
                float3 vrDir = normalize(reflect(-viewDir,nDirWS_FT));

                //中间量准备
                /*下面是光照的漫反射和镜面反射部分*/
                //diffuse
                float NoL = max(0.0,dot(lightDir,nDirWS_FT));
                float3 L_diff = NoL * _L_Lambert_Color;

                //specular
                float NoH = max(0.0,dot(nDirWS_FT,halfDir));
                float3 L_spec = pow(NoH * _L_Specular_Color,_Phong_Int);

                //光衰部分
                float attenuation = LIGHT_ATTENUATION(i);
                //UNITY_LIGHT_ATTENUATION(attenuation, i, i.posWorld.xyz);
                float3 attenColor = attenuation * _LightColor0.xyz;

                /*下面是环境光的漫反射部分,也就是三色环境光*/
                //上层光
                float upNor = clamp(nDirWS_FT.g,0.0,1.0);
                float3 upColor = upNor * _E_Lambert_UpColor;
                //下层光
                float downNor = clamp(nDirWS_FT.g * -1,0.0,1.0);
                float3 downColor = downNor * _E_Lambert_DownColor;
                //中层光
                float midNor = clamp(1 - upNor - downNor,0.0,1.0);
                float3 midColor = midNor * _E_Lambert_MidColor;

                /*下面是环境镜面反射光部分*/
                //cubemap
                float3 cubemap_Dir = vrDir;
                float3 cubemap_color = texCUBElod(_cubemap,float4(cubemap_Dir,_mipmap_level));

                //fresnel
                float NoV = max(0.0,dot(nDirWS_FT,viewDir));
                float OneMinusNoV = 1 - NoV;
                float fresnel = pow(OneMinusNoV,_fresnel_exp);

                //光照模型
                /*光照的漫反射和镜面反射*/
                float3 light_all = (L_diff + L_spec) * _Light_Color * attenColor;

                /*环境光的漫反射部分  三色环境光*/
                float3 env_diff_all = clamp(upColor + downColor + midColor,0.0,1.0);

                /*环境光的镜面反射部分  cubemap和fresnel部分*/
                float3 env_spec_all = cubemap_color * fresnel * _Env_SpecInt;

                /*环境光的漫反射和镜面反射的总和*/
                float3 env_all = clamp(env_diff_all + env_spec_all,0.0,1.0) * AO_R;

                float3 finalColor = clamp(env_all + light_all,0.0,1.0);

                //后处理

                //返回值
                return float4(finalColor,1.0);

                //return float4(0.0,1.0,0.0,1.0);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

final effect

insert image description here

Transparent effects

insert image description here

  • AC : Alpha Test(Alpha Cutout)
  • AB : Alpha Blend
  • AD : Additive
  • Custom blending methods: List the blending methods on the property panel, allowing users to choose and experiment with the effect.

AC

insert image description here
insert image description here

  • Transparent cut, alpha cutout, also called alpha test, is also AC. On the left side, we can see that the edge is softer, and on the right side there are more sawtooth, the front and back of alpha blend are disordered, and the front and back of alpha test are correct, and the use of AC is shown in the PPT.
  • Alpha Test is very straightforward. It is to judge whether the Alpha value of a fragment meets our given threshold. If the condition is not met, the fragment will be directly discarded and will not participate in subsequent tests. The result of the Alpha Test is that a fragment is either completely opaque, or discarded so that it cannot be seen at all.
  • So it is actually not a serious transparency effect, it just discards the fragments that do not meet the conditions, resulting in the effect of only displaying a part of the fragments.

Code:

Shader "shader forge/L13_AC"
{
    
    
    Properties
    {
    
    
        _MainTex ("Base Color With A", 2D) = "white" {
    
    }
        _CutOff ("CutOff",Range(0.0,1.0))  = 0.5	//透明度阈值

    }
    SubShader
    {
    
    
        Tags {
    
    
            "RenderType"="TransparentCutout" 
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        LOD 100

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv0 : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            uniform sampler2D _MainTex;
            uniform float4 _MainTex_ST;	//我们的贴图偏移选项
            uniform float _CutOff;

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv0 = TRANSFORM_TEX(v.uv0, _MainTex);    //加上贴图偏移            
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                fixed4 var_MainTex = tex2D(_MainTex, i.uv0);
                //这是我们要做的主要步骤,如果贴图的透明度不大于我们的阈值,就直接裁剪抛弃掉
                clip(var_MainTex.a - _CutOff);	
                return var_MainTex;
            }
            ENDCG
        }
    }
}

Show results

insert image description here

insert image description here
insert image description here

AB

insert image description here
insert image description here

  • In contrast, ab, although it has a sorting problem (as shown in the figure, is disordered), is often used for objects that do not consider intermediate details and have complex outlines.
  • It is very commonly used in special effects as a base. A common routine is to use ab to make a base layer, and then use ad to brighten a layer.

Code:

Shader "shader forge/L13_AB"
{
    
    
    Properties
    {
    
    
        _MainTex ("Base Color With A", 2D) = "white" {
    
    }
    }
    SubShader
    {
    
    
    	//主要做的
        Tags {
    
    
            "Queue"="Transparent" 
            "RenderType" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }

        Blend SrcAlpha OneMinusSrcAlpha		//主要做的

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv0 : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	//我们的贴图偏移选项

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv0 = TRANSFORM_TEX(v.uv0, _MainTex);		//加上贴图偏移
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                fixed4 var_MainTex = tex2D(_MainTex, i.uv0);
                return var_MainTex;
            }
            ENDCG
        }
    }
}

Show results

insert image description here

  • Comparing it with the AC above, you will find that the edges of this model will be softer.

AD

insert image description here
insert image description here

  • AD is the soul of special effects. It often expresses illuminants. Special effects often use multiple transparent sheets to superimpose, so that each pixel needs to be calculated several times, which will cause a performance gap.
  • Pay attention to prevent the superimposition of multi-layer transparent films, and AD can also be gradually replaced by post-processing + bloom.

Code:

Shader "shader forge/L13_AD"
{
    
    
    Properties
    {
    
    
        _MainTex ("Base Color With A", 2D) = "white" {
    
    }
    }
    SubShader
    {
    
    
    	//主要做的
        Tags {
    
    
            "RenderType"="Transparent" 
            "Queue" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        
        Blend One One	//主要做的

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	//我们的贴图偏移选项

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);	//加上贴图偏移
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                fixed4 var_MainTex = tex2D(_MainTex, i.uv);
                return var_MainTex;
            }
            ENDCG
        }
    }
}

Show results

insert image description here

  • One and one are superimposed, and it becomes brighter directly.

custom blend mode

insert image description here
insert image description here
insert image description here

  • This time we want to achieve what the left side of the picture above looks like.

insert image description here

  • [Enum (enumeration type)], this line of definition means to draw a drop-down list in the property panel, and the content in the list is the content in the enumeration type.
  • The result calculated in this shader is the source src.
  • The background before this shader starts to calculate is the target src.

Code:

Shader "shader forge/L13_BlendMode"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        [Enum(UnityEngine.Rendering.BlendMode)]
        _BlendSrc ("Blend source factor",int) = 0
        [Enum(UnityEngine.Rendering.BlendMode)]
        _BlendDst ("Blend destination factor",int) = 0
        [Enum(UnityEngine.Rendering.BlendOp)]
        _BlendOp ("Blend Operation", int) = 0
    }
    SubShader
    {
    
    
    	//主要做的
        Tags {
    
    
            "RenderType"="Transparent" 
            "Queue" = "Transparent"
            "ForceNoShadowCasting" = "True"
            "IgnoreProjector" = "True"
        }
        
        //下面两行是主要做的
        BlendOp [_BlendOp]
        Blend [_BlendSrc] [_BlendDst]

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;	//我们的贴图偏移选项

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);	//加上贴图偏移
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                // sample the texture
                fixed4 var_MainTex = tex2D(_MainTex, i.uv);
                return var_MainTex;
            }
            ENDCG
        }
    }
}

Show results

The property panel made by the code:
insert image description here

Model display:

  • The operators are srcalpha and OneMinusSrcAlpha:
    insert image description here
  • The operators are One and OneMinusSrcAalpha:
    insert image description here
  • Operators are One and One:
    insert image description here

Guess you like

Origin blog.csdn.net/weixin_43789369/article/details/131471142