Backlog/engine/rend/shaders/meshes.vert.hlsl

136 lines
3.7 KiB
HLSL

// I just reuse this one for the shadow mapping right?
uint getCharFromUintArray(uint color, uint index)
{
return uint((color >> 8 * index) & 0xFF);
}
struct Input
{
float3 Position : TEXCOORD0;
float3 Normal : TEXCOORD1;
float4 Color : TEXCOORD2;
float2 UV : TEXCOORD3;
uint Bones : TEXCOORD4;
uint weights : TEXCOORD5;
uint Instance : SV_InstanceID;
};
struct Output
{
float2 TexCoord : TEXCOORD0;
float3 WorldPos : TEXCOORD1;
float3 Normal: TEXCOORD2;
float4 DirectionalShadowFragPos: TEXCOORD3;
uint Instance: TEXCOORD4;
float3 ScreenNormal: TEXCOORD5;
float4 Position : SV_Position;
};
struct Scene
{
float4x4 Model;
uint textureMode; // 0 = regular triple,
// 0x10 = video yuv,
int animation; // -1 means no animation, any non-zero value means an index into the animationBuffer
uint flags; // 0 -> 0: always in front
// 1 -> 1: useAltCamera
uint pad2;
};
StructuredBuffer<Scene> scene: register(t0, space0);
struct BoneTransform
{
float4x4 final;
};
StructuredBuffer<BoneTransform> animationBuffer: register(t1, space0);
cbuffer Uniforms : register(b0, space1)
{
float4x4 ViewProjection;
float4x4 NoTranslateView;
float4x4 ShadowMapProjection;
float time;
};
float4x4 ExtractRotation(float4x4 m)
{
// Extract basis vectors
float3 x = float3(m._11, m._12, m._13);
float3 y = float3(m._21, m._22, m._23);
float3 z = float3(m._31, m._32, m._33);
// Remove scale by normalizing each axis
x = normalize(x);
y = normalize(y);
z = normalize(z);
// Reconstruct rotation matrix
float3x3 m2 = float3x3(x, y, z);
return float4x4(
float4(m2[0][0], m2[0][1], m2[0][2], 0.0),
float4(m2[1][0], m2[1][1], m2[1][2], 0.0),
float4(m2[2][0], m2[2][1], m2[2][2], 0.0),
float4(0.0, 0.0, 0.0, 1.0)
);}
Output main(Input input)
{
Output output;
output.TexCoord = input.UV;
int animation = scene[input.Instance].animation;
float3 vertexPos = input.Position;
if(animation != -1)
{
vertexPos = float3(0.0, 0.0, 0.0);
for(int i = 0; i < 4; i += 1)
{
uint boneIndex = getCharFromUintArray(input.Bones, i);
float weight = float(getCharFromUintArray(input.weights, i)) / 255;
// this will depend on ozz's finals format
BoneTransform boneTransform = animationBuffer[uint(animation) + boneIndex];
vertexPos += weight * ( mul(boneTransform.final, float4(input.Position, 1.0)) ).xyz;
}
}
// float4 pos = float4(input.Position, 1.0);
float4 pos = float4(vertexPos, 1.0);
// pos.x += 0.2 * sin(time * 0.5 ) * pos.y * 0.5;
// pos.y += 0.2 * cos(time * 0.5 ) * pos.z * 0.5;
// todo. maybe all world position values should be
// transformed into screen space
float4 WorldPos = mul(scene[input.Instance].Model, pos);
output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos));
output.WorldPos = WorldPos.xyz;
float4x4 noTranslate = ExtractRotation(scene[input.Instance].Model);
output.Normal = normalize(mul(noTranslate, float4(input.Normal, 1.0))).xyz;
float4x4 noTranslateScreen = mul(NoTranslateView, noTranslate);
output.ScreenNormal = mul(noTranslateScreen, float4(input.Normal, 1.0)).xyz;
// output.ScreenNormal = mul(noTranslateScreen, float4(input.Normal, 1.0)).xyz;
// output.ScreenNormal = input.Normal;
// output.ScreenNormal = float4(input.Normal, 1.0).xyz;
output.DirectionalShadowFragPos = mul(ShadowMapProjection, WorldPos);
output.Instance = input.Instance;
return output;
}