Unity shader学习笔记
3ColorAmbient三重色的环境光(庄懂老师TA课07)
主要思路:通过法线获得模型基于世界坐标的上部,侧面,下部的遮罩,暴露三个颜色调节参数,再用一张AO贴图做对环境光的遮挡。
实现思路
上图,主要是Properties处,要暴露在外部的控制面板的可调节参数,每一句最后不能加分号“;”,不然会报错 “Shader error in ‘shader的名字’: Parse error: syntax error, unexpected $undefined, expecting TVAL_ID or TVAL_VARREF at line 错误行数”
...
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "UnityCG.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma target 3.0
//输入参数
uniform float3 _EnvUpCol;
uniform float3 _EnvMidCol;
uniform float3 _EnvDownCol;
uniform sampler2D _Occlusion; //贴图的输入参数格式是samplerXD xxxx;
//输入结构
struct VertexInput {
float4 vertex : POSITION; //将模型的顶点信息输入进来
float4 normal : NORMAL; //
float2 uv0 : TEXCOORD0; //unity uv也是从0开始使用, 一共有四维,但是一般都是二维的意义,剩下二维装其他东西
};
//输出结构
struct VertexOutput {
float4 pos : SV_POSITION; //由模型顶点信息换算而来的顶点屏幕位置
float3 nDirWS : TEXCOORD0;
float2 uv : TEXCOORD1; //上面有0,这里1,排队
};
//输入结构>>顶点shader>>输出结构
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0; //新建一个输出结构
o.pos = UnityObjectToClipPos( v.vertex ); //变换顶点信息,将其赋给输出结构
o.nDirWS = UnityObjectToWorldNormal(v.normal);
o.uv = v.uv0; //输出的uv 等于 输入的uv:uv0;
return o; //将输出结构输出
}
//输出结构>>>像素
float4 frag(VertexOutput i) : COLOR {
float3 nDir = i.nDirWS; //获得法线方向
float3 upmask = max(nDir.g, 0.0); //向上方向遮罩
float3 downmask = max(-nDir.g, 0.0); //向下方向遮罩 = -向上方向遮罩
float3 midmask = 1 - upmask -downmask; // 侧面遮罩 = 1-向上-向下遮罩
float3 EnvLightCol = upmask * _EnvUpCol + midmask * _EnvMidCol + downmask * _EnvDownCol;// 环境光颜色 =三个方向遮罩分别乘
//采样AO纹理
float occlusion = tex2D(_Occlusion, i.uv);
float3 EnvLighting = EnvLightCol * occlusion;
return float4(EnvLighting,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果如下
学习心得:1.在最后输出结构到像素着色器阶段,每做一步,可以返回一步的结果,在unityconsole里查看有无错误,及时修改,及早发现错误。
2.永远不要在外面改好了shader名字,又在代码里面再改,会导致找不到shader。