在上篇文章中,我们是实现了Shader中的观察空间推导。
我们在这篇文章中,根据上篇文章的推导,在Shader中实现观察空间矩阵的推导。
Pview = [Wview] * Pworld
Pview = [Vworld]-1 * Pworld
Pview = [Vworld]T * Pworld
在属性面板定义测试使用到的 摄像机坐标 和 测试顶点坐标
_ViewPos(“View Pos”,vector) = (0,0,0,0)
_ViewTarget(“View Target”,vector) = (0,0,0,0)
float3 ViewZ = normalize(_ViewPos - _ViewTarget);
float3 ViewY = float3(0,1,0);
float3 ViewX = cross(ViewZ,ViewY);
ViewY = cross(ViewX,ViewZ);
float4x4 M_viewTemp = float4x4
(
ViewX.x,ViewX.y,ViewX.z,0,
ViewY.x,ViewY.y,ViewY.z,0,
ViewZ.x,ViewZ.y,ViewZ.z,0,
0,0,0,1
);
1 0 0 − T x 0 1 0 − T y 0 0 1 − T z 0 0 0 1 \begin{matrix} 1&0&0&-T~x~\\ 0&1&0&-T~y~\\ 0&0&1&-T~z~\\ 0&0&0&1\\ \end{matrix} 100001000010−T x −T y −T z 1
float4x4 M_viewTranslate = float4x4
(
1,0,0,-_ViewPos.x,
0,1,0,-_ViewPos.y,
0,0,1,-_ViewPos.z,
0,0,0,1
);
float4x4 M_view = mul(M_viewTemp,M_viewTranslate);
float3 vertexWS = TransformObjectToWorld(v.vertexOS);
float3 vertexVS = mul(M_view,float4(vertexWS,1));
o.vertexCS = TransformWViewToHClip(vertexVS);
//平移变换
//缩放变换
//旋转变换(四维)
Shader "MyShader/URP/P3_6_5"
{
Properties
{
_Translate("Translate(XYZ)",Vector) = (0,0,0,0)
_Scale("Scale(XYZ)",Vector)= (1,1,1,1)
_Rotation("Rotation(XYZ)",Vector) = (0,0,0,0)
[Header(View)]
_ViewPos("View Pos",vector) = (0,0,0,0)
_ViewTarget("View Target",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;
float4 _Scale;
float4 _Rotation;
float4 _ViewPos;
float4 _ViewTarget;
CBUFFER_END
Varying 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);
//旋转变换
float4x4 M_rotateX = float4x4
(
1,0,0,0,
0,cos(_Rotation.x),sin(_Rotation.x),0,
0,-sin(_Rotation.x),cos(_Rotation.x),0,
0,0,0,1
);
float4x4 M_rotateY = float4x4
(
cos(_Rotation.y),0,sin(_Rotation.y),0,
0,1,0,0,
-sin(_Rotation.y),0,cos(_Rotation.y),0,
0,0,0,1
);
float4x4 M_rotateZ = float4x4
(
cos(_Rotation.z),sin(_Rotation.z),0,0,
-sin(_Rotation.z),cos(_Rotation.z),0,0,
0,0,1,0,
0,0,0,1
);
v.vertexOS = mul(M_rotateX,v.vertexOS);
v.vertexOS = mul(M_rotateY,v.vertexOS);
v.vertexOS = mul(M_rotateZ,v.vertexOS);
//观察空间矩阵推导
//P_view = [W_view] * P_world
//P_view = [V_world]^-1 * P_world
//P_view = [V_world]^T * P_world
float3 ViewZ = normalize(_ViewPos - _ViewTarget);
float3 ViewY = float3(0,1,0);
float3 ViewX = cross(ViewZ,ViewY);
ViewY = cross(ViewX,ViewZ);
float4x4 M_viewTemp = float4x4
(
ViewX.x,ViewX.y,ViewX.z,0,
ViewY.x,ViewY.y,ViewY.z,0,
ViewZ.x,ViewZ.y,ViewZ.z,0,
0,0,0,1
);
float4x4 M_viewTranslate = float4x4
(
1,0,0,-_ViewPos.x,
0,1,0,-_ViewPos.y,
0,0,1,-_ViewPos.z,
0,0,0,1
);
float4x4 M_view = mul(M_viewTemp,M_viewTranslate);
float3 vertexWS = TransformObjectToWorld(v.vertexOS);
float3 vertexVS = mul(M_view,float4(vertexWS,1));
o.vertexCS = TransformWViewToHClip(vertexVS);
//o.vertexCS = TransformObjectToHClip(v.vertexOS.xyz);
return o;
}
half4 frag (Varying i) : SV_Target
{
return 1;
}
ENDHLSL
}
}
}