来一张AI提供的资料
在shader编程中,定义的结构体,有些是会被自动赋值,有些是必须要手动赋值的,这就涉及到了语义,
例如
struct appdata{float4 vertex : POSITION;float vertex2;float2 uv : TEXCOORD0;};
结构体里面定义的两个变量 vertex和uv,后面加了POSITION和TEXCORD0两个语义,就赋予了他们不同的特殊功能,他们会被自动赋值,而vertex2就是一个普通的变量了。
下面是语义表
**
一,坐标空间转换
空间转换中,一般有五个空间转换,模型空间→世界空间→视图空间→裁剪空间→NDC空间(其次坐标空间,执行其次坐标后的空间)→屏幕空间**
核心原则
1,数据依赖原则
当逻辑需要相对坐标系属性(如模型UV、顶点色)时,优先在模型空间处理(如gl_Vertex变换前)
当逻辑依赖全局交互状态(如光照方向、物理碰撞)时,必须转换到世界空间后处理
2,性能优化准则
在顶点着色器阶段处理空间转换(如UNITY_MATRIX_MVP),利用GPU并行性在片段着色器中避免重复坐标转换,通过TEXCOORD传递预处理数据
3,精度控制策略
高精度计算(如物理模拟)应在世界空间使用double类型
视觉效果类计算(如雾效)可在视图空间使用float类型
空间转换代码
Shader "SpaceTransform/BasicChain"{SubShader { Pass { CGPROGRAM#pragma vertex vert #pragma fragment frag#include "UnityCG.cginc"struct appdata {float4 vertex : POSITION;};struct v2f {float4 pos : SV_POSITION;float4 worldPos : TEXCOORD0;float4 viewPos : TEXCOORD1;};v2f vert (appdata v) {v2f o;// 模型空间 → 世界空间 o.worldPos = mul(unity_ObjectToWorld, v.vertex); // 世界空间 → 视图空间 o.viewPos = mul(UNITY_MATRIX_V, o.worldPos); // 视图空间 → 裁剪空间 o.pos = mul(UNITY_MATRIX_P, o.viewPos); return o;}fixed4 frag (v2f i) : SV_Target {return fixed4(1,1,1,1); // 纯白输出 }ENDCG }
}
}
2,顶点动态变化
顶点动态变化日常会使用到的功能如下
-
基础正弦波波动例子(模型空间)
v2f vert (appdata v){v2f o;float4 worldPos = mul(unity_ObjectToWorld, v.vertex);// Y轴波动计算(频率_Hz,振幅_Amp)float wave = _Amp * sin(_Time.y * _Hz + worldPos.x * _WaveDensity);v.vertex.y += wave;o.vertex = UnityObjectToClipPos(v.vertex);return o;}
后续效果相对复杂,这边大概讲入门,就不全部细说