// 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: register(t0, space0); struct BoneTransform { float4x4 final; }; StructuredBuffer 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; }