文章目录
- 前言
- 一、直接相乘缩放
- 1、在属性面板定义一个四维变量,用xyz分别控制在xyz轴上的缩放
- 2、在常量缓存区申明该变量
- 3、在顶点着色器对其进行相乘,来缩放变换
- 4、我们来看看效果
- 二、使用矩阵乘法代替直接相乘缩放的原理
- 1、我们按如下格式得到缩放矩阵
- 2、把我们需要平移的点变为列矩阵
- 3、M~scale~* P 得到缩放变换后的结果
- 4、我们在图形计算器中看看效果
- 三、在URP Shader中实现
- 1、在属性面板定义一个四维变量,用xyz分别控制在xyz轴上的缩放
- 2、在常量缓存区申明该变量
- 3、在顶点着色器中得到缩放矩阵
- 4、因为Attribute接收顶点格式为(x,y,z,1)且mul相乘规则的原因。所以,我们的列矩阵就是 vertexOS
- 5、相乘得到结果
- 6、我们来看看效果
- 四、测试代码
前言
在Shader中,我们对于顶点经常使用到缩放变换。我们在这篇文章中,用点的缩放看一下缩放变换的缩放矩阵。
一、直接相乘缩放
P1 = P*S
P1 = (Px * Sx,Py * Sy,Pz * Sz)
1、在属性面板定义一个四维变量,用xyz分别控制在xyz轴上的缩放
_Scale(“Scale(XYZ)”,Vector)= (1,1,1,1)
2、在常量缓存区申明该变量
CBUFFER_START(UnityPerMaterial)
float4 _Scale;
CBUFFER_END
3、在顶点着色器对其进行相乘,来缩放变换
v.vertexOS *= _Scale;
4、我们来看看效果
二、使用矩阵乘法代替直接相乘缩放的原理
1、我们按如下格式得到缩放矩阵
扩维到四维的原因:因为平移矩阵是4维的,使缩放矩阵变成同一维度,在之后可以合并变换矩阵
- Scale(a,b,c)
2、把我们需要平移的点变为列矩阵
- P(x,y,z)
3、Mscale* P 得到缩放变换后的结果
4、我们在图形计算器中看看效果
三、在URP Shader中实现
1、在属性面板定义一个四维变量,用xyz分别控制在xyz轴上的缩放
_Scale(“Scale(XYZ)”,Vector)= (1,1,1,1)
2、在常量缓存区申明该变量
CBUFFER_START(UnityPerMaterial)
float4 _Scale;
CBUFFER_END
3、在顶点着色器中得到缩放矩阵
float4x4 M_Scale = float4x4
(
_Scale.x,0,0,0,
0,_Scale.y,0,0,
0,0,_Scale.z,0,
0,0,0,1
);
4、因为Attribute接收顶点格式为(x,y,z,1)且mul相乘规则的原因。所以,我们的列矩阵就是 vertexOS
5、相乘得到结果
v.vertexOS = mul(M_Scale,v.vertexOS);
6、我们来看看效果
四、测试代码
//平移变换
Shader "MyShader/URP/P3_5_3"
{Properties{_Translate("Translate(XYZ)",Vector) = (0,0,0,0)_Scale("Scale(XYZ)",Vector)= (1,1,1,1)}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;float4 _Scale;CBUFFER_ENDVarying vert (Attribute v){Varying o;//平移变换float4x4 M_Translate = float4x4(1,0,0,_Translate.x,0,1,0,_Translate.y,0,0,1,_Translate.z,0,0,0,1);v.vertexOS = mul(M_Translate,v.vertexOS);//缩放交换float4x4 M_Scale = float4x4(_Scale.x,0,0,0,0,_Scale.y,0,0,0,0,_Scale.z,0,0,0,0,1);v.vertexOS = mul(M_Scale,v.vertexOS);o.vertexCS = TransformObjectToHClip(v.vertexOS.xyz);return o;}half4 frag (Varying i) : SV_Target{return 1;}ENDHLSL}}
}