庄懂的TA笔记(八)<OldSchoolPlus+案例讲解+法线使用>
案例解析:
0、创意作业展示
PS:
shader 当中 ,不写if ,不写循环,一般用 shaderFeature , multiCompile;
1、 上期 作业 讲解、(OldSchoolPlus)***
1、 OldSchoolPlus 的光照模型 构成。
OldSchoolPlus = OldchoolPhong + 3ColAmbient + shadow
2、带着写 >> 准备 模板 :
1、参考准备,phong 3colEvn shadow SF 和 SL 不同版本的准备。
2、开始编写 Lambert phong 3cutEvn shadow 等光照模型。
PS:(unity 支持 的一个模型UV 有 4 套 UV1 UV2 UV3 UV4)。
3、fragment(输出结构>>像素环节)
//光照模型
这里分为:光照模型(直接光照) Dir 光照模型(环境光照)
//光照模型(直接光照) Dir
1、DirLighting = (_BaseCol * Lambert +Phong) * _LightCol * shadow;
注意:posCS 需要 默认为 Pos 的默认名字。
//光照模型(环境光照)
2、EnvLight = 3CutEnvCol * _BaseCol * occlushion (Ao);
//最终输出
3、FinalRGB = DirLighting +EnvLight ;
Return float4(FinalRGB ,1);
2 、作业案例2讲解
镭射 甲翘 的 Shader Forge 实现:
实现思路:
镭射虫=(Lambert + Phong<高光> + Ramp Tex<渐变贴图>) + 1UpCutEnvCol * 菲涅尔<黑盒>
3 、作业案例3讲解
thickness AO 图
上图中,RGB中分别存放了:
R==厚度图(厚度薄的地方是黑色)
G == AO图
B = ----- 没说。
实现思路:(未讲完)
phong01 phong02 菲涅尔 lamber mask贴图 shadow lerp() 巴拉巴拉......
这个案例,修改到 简明一些后,庄懂在发到 工程文件里面去。
3 、作业案例3讲解
实现思路:
MASK 图,同样用了 RGB 通道存储 信息。
(mask 贴图)。
(RGBA 不同通道 的 像素块信息)。
用这张mask 区分不同出4块不同的材质,然后对不同通道色块,设置不同的环境光颜色。
皮卡丘shader = (环境色01(R) + 环境色02(G) + 环境色03(B) + 环境色04(A) ) * AO + Phong + Lambert + LightColor +Outline width + Outline Color。
正菜:法线的应用使用:
0、概念普及讲解:
原理:
1、采样法线贴图 并 解码。(法线是经过,编码,在解码的过程的)
2、构建TBN矩阵(切线空间)
3、将切线空间下的法线,转到世界空间,并归一化。
4、输出 世界空间下的法线信息。
知识点>>PS: 我们常用的normal 贴图 ,属于 切线空间法线,而,在SL中和SF中的"法线nDir"是属于世界空间下的法线信息。
所以,我们在使用 编码烘焙 出来的 法线贴图(切线法线)的时候,需要解码,转成SL,SF中的世界空间法线信息,这样,法线信息才可以和光向量等做点乘
世界空间下的法线贴图 是这样的。(SL SF 可以直接 点积 用)
图先欠着 切线空间下的法线贴图。(编码后的法线>>解码为世界空间法线贴图可用)
关键词:
对象空间法线 切线空间法线(TBN) 世界空间法线
TBN矩阵 = T + B + N T =Tangent Dir + B =BiTangent Dir + N =Normal Dir
TBN矩阵 = T + B + N Tdir 切线方向 + Bdir 副切线方向 + Ndir 法线方向
1、SF中法线如何使用:
2、SL中法线如何使用:
lamboert 为基础模板,观察,编写 normal 的使用
PS:采样信息的 声明 格式,采用var_NormalMap 或 nDirTS.
因为拿到的法线贴图还是 切线空间法线,所以需要进行解码 。
var_NormalMap = UnPackNormal(tex2D(_NormalMap , i.uv0)); //解码后可用的法线信息得到。
//构建TBN矩阵
float3*3 TBN = float 3*3 (i.tDirWS,i.bDirWS ,i.nDirWS);
flaot3 nDirWS =normallize(mul(nDirTS , TBN));
完整代码示例:
Shader "Unlit/Sc08_NormalMap01"
{
Properties
{
_NormalMap("法线贴图",2D) = "bump"{}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass {
Name "FORWARD"
Tags {
"LightMode"="ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma target 3.0
UNITY_INSTANCING_BUFFER_START( Props )
// UNITY_DEFINE_INSTANCED_PROP( float4, _Color)
UNITY_INSTANCING_BUFFER_END( Props )
uniform sampler2D _NormalMap;
//输入结构
struct VertexInput
{
float4 vertex : POSITION;
float2 uv0 : TEXCOORD0; //需要UV坐标,采样法线贴图
float4 normal : NORMAL; //法线信息
float4 tangent : TANGENT; //构建切线空间需要模型切线信息
};
//顶点输出结构
struct VertexOutput
{
float4 pos : SV_POSITION;
float2 uv0 : TEXCOORD0; //UV信息
float3 nDirWS : TEXCOORD1; //世界空间法线信息
float3 tDirWS : TEXCOORD2; //世界空间切线信息
float3 bDirWS : TEXCOORD3; //世界空间切线信息
};
//输出结构>>>顶点shader>>>输出结构
VertexOutput vert (VertexInput v)
{
VertexOutput o = (VertexOutput)0; //新建一个输出结构
o.pos = UnityObjectToClipPos(v.vertex);
o.uv0 = v.uv0; //传递UV信息
o.nDirWS = UnityObjectToWorldNormal(v.normal); //世界空间法线信息
//T世界空间切线信息
o.tDirWS = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0)).xyz);
//BT世界空间切线信息
o.bDirWS = normalize(cross(o.nDirWS,o.tDirWS)* v.tangent.w);
return o;
}
//色彩输出结构
float4 frag(VertexOutput i) : COLOR
{
//准备向量
//获取nDir
//采样法线纹理并解码 切线空间 nDir;
float3 var_NormalMap = UnpackNormal(tex2D(_NormalMap,i.uv0)).rgb;
//构建TBN矩阵
float3x3 TBN = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
//世界空间下的 nDir;
float3 ndir = normalize(mul(var_NormalMap,TBN));
//获取ldir
float3 ldir = _WorldSpaceLightPos0.xyz;
//点积结果
float ndotl = dot(ndir,ldir);
//光照模型公式
float Lambert = max(0,ndotl *0.5+0.5);
//返回结果
return float4(Lambert,Lambert,Lambert,1.0f);//输出最终颜色
}
ENDCG
}
}
FallBack "Diffuse"
}
查询关于shader Lab 使用的符号 释义 的网站,例如 mul(A,B) cross (A,B)