记录编写 Unity Shader 过程中的一些零散条目,备忘,不定时更新。
-
SubShader 一定要指定Tag : "LightMode" = "ForwardBase",否则使用内置变量 _WorldSpaceLightPos0 将不正确
-
需要使用 #include "Lighting.cginc" 来引入光照相关的内置变量如 _LightColor0
-
模型法线变换到世界坐标,需要用M矩阵的逆转置矩阵,变换代码如下
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);// 法线变换
-
当用矩阵变换3维向量时,要使用
(float3x3)
进行强转,否则计算结果可能不正确 -
TRANSFORM_TEX
用来计算 TEXCOORD0的值 和纹理的 Trilling 和 Offset ,获得最终实际的 uv 坐标,在 Unity.cginc 中可以看到如下定义:
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
也就是说下面这两句代码是等价的
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw;
- Unity Shader 中使用 Vector 类型属性和变量
Properties
{
_Vec("Vector", Vector) = (0, 1, 0, 1)
}
-
片元着色器 frag 输入的 v2f 中的
vertex.xy
表示的是片元的屏幕坐标,取值范围在 [0, _ScreenParam.x] 和 [0, _ScreenParam.y] 之间,_ScreenParam
是内置变量,表示屏幕宽高 -
clamp
需要指定3个参数,即使是将目标限制在[0, 1] 也需要将0和1作为第2和3个参数传递 -
可以使用
lerp(a, b, x)
在x
取值为0或1(大部分时候通过step
和clamp
处理后)时,达到if-else
的效果 -
当你在 frag 中返回颜色的
a
通道不生效时,比如如下的代码
fixed4 frag(v2f i) : SV_TARGET
{
return fixed4(0, 1, 0, 0);
}
ENDCG
没有透明时,需要在 Shader 中开启混合,在 SubShader 中使用如下的语句
Blend SrcAlpha OneMinusSrcAlpha
网友评论