Article Directory
Uh-huh, this is the last section of my AP01 course. I watched the content after episode 21 about LightingMap. I don’t think it’s needed yet. In addition, LightingMap is also used in a project I participated in before.
The following is also a brief record of the things in the get out of class. In fact, the whole class seems to be half-understood. The content of this lesson is more of a simple record, and I don't understand some parts very well, so let's start directly.
SD part
I didn't follow the SD part, because I plan to find an online course to study systematically later.
- The model needs vertex color, because the base does not need to be changed, so the vertex color is all black, and the change is the part above the base, so it is all white.
- Two UVs are also needed. The first UV is used to generally sample the textures of the main texture, normal, highlight and self-illumination. The second chapter UV is to prepare for the follow-up special effects.
- To make a UV grid map, this part is to import the model into sd, and then bake it to obtain a UV grid map.
And to get two pictures in SD:
-
_EffMap01. This one is used to store the mesh, face random grayscale, and face slope (gray gradient on the face).
-
_EffMap02. This one is used to store noise, which will be used later in special effects.
-
Why not stuff this grayscale into the A channel of the red and green image above?
When it comes to optimization issues, RGB and RGBA pictures, the compressed size of these two pictures in Unity is not 1/4 more, but doubled. So if a picture can be added without alpha, it looks like there is one more channel, but in fact it takes up a lot more memory.
Shader code part
Shader "shader forge/L21_OldSchoolPlusWithMeshAnim"
{
Properties
{
[Header(Texture)]
_MainTex ("Main Tex RGB:Base Color A:EnvMask", 2D) = "white" {
}
_normal ("normal", 2D) = "bump" {
}
_SpecTex ("Spec Tex RGB:Spec Color A:Spec Pow", 2D) = "white" {
}
_EmittTex ("Emitt Tex RGB:Env Tex", 2D) = "black" {
}
_cubemap ("cubemap", Cube) = "_Skybox" {
}
[Header(Diffuse)]
_MainCol ("Main Color", Color) = (0.5,0.5,0.5,1.0)
_EnvDiffInt ("Env Diff Int", Range(0, 1)) = 0.2
_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)]
[PowerSlider(2)] _SpecPow ("Spec Pow", Range(1, 90)) = 30
_EnvSpecInt ("Env_SpecInt", Range(0, 5)) = 0.7826087
_fresnel_exp ("fresnel_exp", Range(0, 90)) = 0.6956522
_mipmap_level ("Env Mipmap", Range(0, 7)) = 0
[Header(Emission)]
_EmittInt ("Emitt Int", Range(1,10)) = 1
[Header(Clock)]
_EffMap01 ("Effect Tex1", 2D) = "gray" {
}
_EffMap02 ("Effect Tex2", 2D) = "gray" {
}
_EffCol ("Effect Color", color) = (0.0,0.0,0.0,0.0)
_EffParams ("Wave Prop X:Int Y:Speed Z:ChaosInt W:FadeInt", vector) = (0.03,3.0,0.3,2.5)
}
SubShader
{
Tags {
"Queue" = "Transparent"
"RenderType"="Transparent"
}
LOD 100
Pass
{
Name "FORWARD"
Tags{
"LightMode" = "ForwardBase"
}
Blend One OneMinusSrcAlpha //AB
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;
float2 uv1 : TEXCOORD1; //特效网格UV信息
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR; //顶点色信息
};
struct v2f
{
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD2;
float3 nDirWS : TEXCOORD3;
float3 tDirWS : TEXCOORD4;
float3 biDirWS : TEXCOORD5;
float4 effectMask : TEXCOORD6;
LIGHTING_COORDS(7,8) //投影相关
};
//Texture
uniform sampler2D _MainTex;
uniform sampler2D _normal;
uniform sampler2D _SpecTex;
uniform sampler2D _EmittTex;
uniform samplerCUBE _cubemap;
//Diffuse
uniform float3 _MainCol;
uniform float _EnvDiffInt;
uniform float3 _E_Lambert_UpColor;
uniform float3 _E_Lambert_DownColor;
uniform float3 _E_Lambert_MidColor;
//Specular
uniform float _SpecPow;
uniform float _EnvSpecInt;
uniform float _fresnel_exp;
uniform float _mipmap_level;
//Emitt
uniform float _EmittInt;
//Effect
uniform sampler2D _EffMap01;
uniform sampler2D _EffMap02;
uniform float3 _EffCol;
uniform float4 _EffParams;
#define TWO_PI 3.1415926*2
//动画方法 inout顶点信息 返回effect相关遮罩
float4 CyberpunkAnim(float noise, float mask, float3 normal, inout float3 vertex){
//生成锯齿波Mask
float baseMask = abs(frac(vertex.y * _EffParams.x - _Time.x * _EffParams.y) - 0.5) *2.0;
//float baseMask1 = abs(frac(vertex.y) - 0.5) * 2.0;
//让白色的时间更多,黑色的时间更少
baseMask = min(1.0, baseMask * 2.0);
//用Noise偏移锯齿波,noise的取值范围为0到1,减去0.5使其有正有负
baseMask += (noise - 0.5) * _EffParams.z;
//smoothstep算出各级Mask
float4 effectMask = float4(0.0,0.0,0.0,0.0);
effectMask.x = smoothstep(0.0,0.9,baseMask);
effectMask.y = smoothstep(0.2,0.7,baseMask);
effectMask.z = smoothstep(0.4,0.5,baseMask);
//将顶点色遮罩存入effectMask
effectMask.w = mask;
//计算顶点动画
vertex.xz += normal.xz * (1.0 - effectMask.x) * _EffParams.w * mask;
//返回effectMask
return effectMask;
//return float4(baseMask1,baseMask1,baseMask1,1.0);
}
v2f vert (appdata v)
{
//采样纹理
float noise = tex2Dlod(_EffMap02, float4(v.uv1, 0.0, 0.0)).r;
//float noise = tex2Dlod(_EffMap02,v.uv1).r;
v2f o;
o.effectMask = CyberpunkAnim(noise, v.color.r, v.normal.xyz, v.vertex.xyz);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv0 = v.uv0;
o.uv1 = v.uv1;
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;
//向量准备
float3x3 TBN_Matrix = float3x3(i.tDirWS,i.biDirWS,i.nDirWS);
float3 nDirWS_FT = normalize(mul(nDirTS, TBN_Matrix));
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 lrDirWS = normalize(reflect(-lightDir, nDirWS_FT));
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
float3 halfDir = normalize(lightDir + viewDir);
float3 vrDir = normalize(reflect(-viewDir,nDirWS_FT));
//准备点积结果
float NoL = max(0.0,dot(lightDir,nDirWS_FT));
float NoH = max(0.0,dot(nDirWS_FT,halfDir));
float NoV = max(0.0,dot(nDirWS_FT,viewDir));
float VoR = max(0.0,dot(viewDir, lrDirWS));
//采样纹理
float4 var_MainTex = tex2D(_MainTex,i.uv0);
float4 var_SpecTex = tex2D(_SpecTex,i.uv0);
float3 var_EmitTex = tex2D(_EmittTex,i.uv0);
//光照模型(直接光照部分)
float3 baseCol = var_MainTex.rgb * _MainCol;
float lambert = max(0.0,NoL);
float specCol = var_SpecTex.rgb;
float specPow = lerp(1, _SpecPow,var_SpecTex.a);
float phong = pow(max(0.0, lrDirWS), specPow);
float shadow = LIGHT_ATTENUATION(i);
float3 dirLighting = (baseCol * lambert + specCol * phong) * _LightColor0 * shadow;
//光照模型(环境光照部分)
//使用3Col环境色方法
/*下面是环境光的漫反射部分,也就是三色环境光*/
//上层光
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;
/*环境光的漫反射部分 三色环境光*/
float3 env_diff_all = clamp(upColor + downColor + midColor,0.0,1.0);
/*下面是环境镜面反射光部分*/
//cubemap
float3 cubemap_Dir = vrDir;
float3 cubemap_color = texCUBElod(_cubemap,float4(cubemap_Dir,_mipmap_level));
//fresnel
float OneMinusNoV = 1 - NoV;
float fresnel = pow(OneMinusNoV,_fresnel_exp);
float occlusion = var_MainTex.a;
float3 envLighting = (baseCol * env_diff_all * _EnvDiffInt + cubemap_color * fresnel * _EnvSpecInt * var_SpecTex.a) * occlusion;
//光照模型(自发光部分)
float3 emission = var_EmitTex * _EmittInt * (sin(_Time.z) * 0.5 + 0.5);
//特效部分
//采样EffMap01
float3 _EffMap01_var = tex2D(_EffMap01,i.uv1).xyz;
float meshMask = _EffMap01_var.x; //网格遮罩
float faceRandomMask = _EffMap01_var.y; //面上的随即灰度遮罩
float faceSlopeMask = _EffMap01_var.z; //面上的坡度(灰度渐变)遮罩
//获取EffectMask
float smallMask = i.effectMask.x;
float midMask = i.effectMask.y;
float bigMask = i.effectMask.z;
float baseMask = i.effectMask.w;
//计算Opacity
float midOpacity = saturate(floor(min(faceRandomMask, 0.999999) + midMask));
float bigOpacity = saturate(floor(min(faceSlopeMask, 0.999999) + midMask));
float opacity = lerp(1.0, min(bigOpacity, midOpacity), baseMask);
//叠加自发光
float meshEmitInt = (bigMask - smallMask) * meshMask;
meshEmitInt = meshEmitInt * meshEmitInt;
emission += _EffCol * meshEmitInt * baseMask;
///返回结果
float3 finalRGB = dirLighting + envLighting + emission;
return float4(finalRGB * opacity, opacity);
//return bigOpacity;
}
ENDCG
}
}
FallBack "Diffuse"
}