shaderlab报错

  • DX11要求所有顶点着色器输出结构体成员必须显式声明语义(因为要对不同的顶点数据执行不同的插值算法再传入片元)

  • 未声明语义的成员会被视为错误

  1. Unity的自动保护机制

也就是说,当shaderlab检测到结构体的无语义成员时:

会自动在代码里面插入排除代码:#pragma exclude_renderers d3d11

这会导致这个pass无法渲染变成材质丢失的紫色状态,所以修改完毕后记得移除插入的代码

法线

顶点着色器传入的模型空间法线虽然通常已经归一了,但是将其转换到世界坐标系的法线并不一定归一,因此,建议世界坐标法线再次归一化。

法线传入片元着色器

如果你试图把世界坐标法线传入片元着色器以进行某些角度计算,你需要把传入的法线进行一次归一化,因为顶点结构体传入片元的途中会对其进行透视校正插值从而导致结果可能不再是单位向量。

NaN

ShaderLab里面可能出现浮点数为NAN的情况,但是并不会报错,一旦出现这个情况,如果你把这个浮点数和任何fixed3进行运算并传给片元着色器作为颜色返回值,就会导致这个顶点的Untiy的渲染器最终返回一个纯黑的点。

常见于pow:负数底数和浮点数幂的运算

一些令人疑惑的点:

v2_f.color = _LightColor0.rgb * _HightColor * max(0,pow(dot(LookDir, FansheDir), _HightLightPow));

pow(dot(LookDir, FansheDir), _HightLightPow)为nan的时候,理论上应该返回0

对公式max(0,pow(dot(LookDir, FansheDir), _HightLightPow))进行isnan()结果也是false。

但是根据实际结果,我发现v2_f的color的rgb居然都是nan,最终导致顶点图元全部变黑。

怀疑是版本问题,有待调查。

变量3和4的重要性

当涉及到顶点的坐标变换的时候,务必使用float4 half4 fixed4(不推荐,值太小只建议颜色)存储顶点,否则会无法用齐次坐标进行位移!

UV,纹理图,模型空间和切线空间法线贴图

1. UV 图(UV Layout)到底是什么?

  • 本质是“地址模板”:把三维模型表面拆成扁平的拼图(UV 岛),让你能在二维空间里精准地画细节。

  • 为什么会有“缺口”? 因为 UV 之外的区域,就是没贴模型的空白,你画了也没人用。

  • 常见疑问:多个面片共用一个区域?没问题,这就是“UV 重叠”,可节省贴图空间。


2. 纹理图(Texture)和 UV 是怎样对应的?

  • 纹理图 = 完整图片:不管 UV 怎么铺,贴图本身每个像素都有数据。

  • UV 的作用:给顶点/片元一对( u, v ),就像给纹理图打个坐标,告诉引擎“我想取这里的像素值”。

  • 没有一一对应? UV 只是“桥梁”,它指向贴图上的位置;多个 UV 也能取同一个纹理像素(平铺、镜像、Atlas)。


3. 模型空间法线贴图(Model‑space Normal Map)

  • 存的是什么? 每个像素里直接写的模型空间法线向量(X,Y,Z)。

  • 有啥特点?

    1. 像素里的向量是“绝对方向”,不用额外变换就能参与光照。

    2. 只能对烘焙它的那个模型用,拿去别的模型上会出错。


4. 切线空间法线贴图(Tangent‑space Normal Map)

  • 存的是什么? 相对本地切线空间(T,B,N)的微小扰动向量。贴图里 (0.5,0.5,1) 代表“笔直朝外”,其它 RGB 就是偏移。

  • 为什么普遍用它?

    1. 通用性强:只要 TBN 计算对了,任何同 UV 布局模型都能复用贴图。

    2. 贴图小:只记录扰动,不存大体方向,节省内存。

  • Shader 中怎么用?

    // n_ts 从贴图采样,范围[0,1]
    float3 n_tangent = n_ts * 2 - 1;   // 转[-1,1]
    float3 n_world = normalize( mul(float3x3(T, B, N), n_tangent) );

5. 它们之间的联系

  1. UV 布局 → 决定你在哪“画”贴图(无论是漫反射还是法线)。

  2. 纹理图 → 是那张“画布”,在上面存数据(颜色 or 向量)。

  3. 模型空间 vs 切线空间 → 区别在于贴图存的“向量定义域”:

    • 模型空间:绝对方向,贴图大、专用性高。

    • 切线空间:局部扰动,贴图小、复用性好。记录的是某一点的偏移,然后根据模型空间算出来,但是会增加性能损耗

    • 切线空间和模型空间的法线贴图,都是基于UV图直接上色的,但是两边对同一点法线记录数据的方法不同而已


🚀 记住:UV 是“去哪里查”,纹理是“查到什么”,法线贴图存的是“查到的法线怎么用”。