在Shader中,我们对于顶点经常使用到平移变换。我们在这篇文章中,用点的平移看一下平移矩阵。
P(x,y,z)
A(x1,y1,z1)
P` = P + A =(x + x1,y + y1,z + z1)
_Translate(“Translate(XYZ)”,Vector) = (0,0,0,0)
CBUFFER_START(UnityPerMaterial)
float4 _Translate;
CBUFFER_END
v.vertexOS += _Translate.xyz;
在多种图形变换时,我们可以把多次的图形变换合并到一个矩阵中。
最后,对顶点只进行一次计算就可得出所有变换后的结果。
_Translate(“Translate(XYZ)”,Vector) = (0,0,0,0)
CBUFFER_START(UnityPerMaterial)
float4 _Translate;
CBUFFER_END
float4x4 T = float4x4
(
1,0,0,_Translate.x,
0,1,0,_Translate.y,
0,0,1,_Translate.z,
0,0,0,1
);
v.vertexOS = mul(T,v.vertexOS);
对于mul函数(我们这里默认使用了第一种相乘方法):
OpenGL(图形接口): 按列存储矩阵(column-major)。调用API形成的矩阵用来和一个列向量相乘,矩阵在左,列向量在右,即mul(M,v)
GLSL(着色器语言): 矩阵的存储方式和OpenGL相同(column-major)
DirectX(图形接口): 按行存储矩阵(row-major)。调用API形成的矩阵用来和一个行向量相乘,矩阵在右,行向量在左,即mul(v, M)
HLSL(着色器语言): 矩阵存储方式和DirectX相反(column-major)
//平移变换
Shader "Unlit/P3_5_1"
{
Properties
{
_Translate("Translate(XYZ)",Vector) = (0,0,0,0)
}
SubShader
{
Tags
{
"PenderPipeline"="UniversalPipeline"
"RenderType"="Opaque"
"Queue"="Geometry"
}
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attribute
{
float4 vertexOS : POSITION;
};
struct Varying
{
float4 vertexCS : SV_POSITION;
};
CBUFFER_START(UnityPerMaterial)
float4 _Translate;
CBUFFER_END
Varying vert (Attribute v)
{
Varying o;
float4x4 T = float4x4
(
1,0,0,_Translate.x,
0,1,0,_Translate.y,
0,0,1,_Translate.z,
0,0,0,1
);
v.vertexOS = mul(T,v.vertexOS);
o.vertexCS = TransformObjectToHClip(v.vertexOS.xyz);
return o;
}
half4 frag (Varying i) : SV_Target
{
return 1;
}
ENDHLSL
}
}
}