138 lines
4.0 KiB
HLSL
138 lines
4.0 KiB
HLSL
// I just reuse this one for the shadow mapping right?
|
|
|
|
uint getCharFromUintArray(uint color, uint index)
|
|
{
|
|
return uint((color >> 8 * index) & 0xFF);
|
|
}
|
|
|
|
#include "vertexShared.hlsli"
|
|
#include "sceneShared.hlsli"
|
|
|
|
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 ViewTransform;
|
|
float4x4 ShadowMapProjection;
|
|
float4 cameraPosition;
|
|
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;
|
|
int billboard = scene[input.Instance].flags & 0x4;
|
|
|
|
float4 WorldPos;
|
|
|
|
if(billboard > 0)
|
|
{
|
|
float3 billboardPosition = mul(scene[input.Instance].Model, float4(0,0,0,1)).xyz;
|
|
float3 toCamera = normalize(cameraPosition.xyz - billboardPosition);
|
|
|
|
float3 up = float3(0,1,0);
|
|
float3 right = normalize(cross(up, toCamera));
|
|
up = cross(toCamera, right);
|
|
//toCamera = float3(0, 0, -1);
|
|
|
|
float d = length(cameraPosition.xyz - billboardPosition);
|
|
float perspectiveScale = 1.0f; // adjust multiplier as needed
|
|
|
|
float finalSize = scene[input.Instance].float0 * perspectiveScale;
|
|
|
|
float3 wp = billboardPosition +
|
|
mul(mul(right, -input.Position.x), finalSize) +
|
|
mul(mul(up, input.Position.y), finalSize);
|
|
|
|
WorldPos = float4(wp, 1.0);
|
|
|
|
output.Position = mul(ViewProjection, WorldPos);
|
|
output.WorldPos = WorldPos.xyz;
|
|
|
|
output.Normal = toCamera;
|
|
output.ScreenNormal = float3(0, 0, 1);
|
|
}
|
|
else
|
|
{
|
|
// todo. maybe all world position values should be
|
|
// transformed into screen space
|
|
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;
|
|
}
|