| struct VertexInput { |
| @location(0) |
| position : vec4<f32>, |
| @location(1) |
| normal : vec3<f32>, |
| @location(2) |
| tangent : vec4<f32>, |
| @location(3) |
| texcoord : vec2<f32>, |
| @location(6) |
| joints : vec4<u32>, |
| @location(7) |
| weights : vec4<f32>, |
| @location(8) |
| instance0 : vec4<f32>, |
| @location(9) |
| instance1 : vec4<f32>, |
| @location(10) |
| instance2 : vec4<f32>, |
| @location(11) |
| instance3 : vec4<f32>, |
| @location(12) |
| instanceColor : vec4<f32>, |
| } |
| |
| struct VertexOutput { |
| @builtin(position) |
| position : vec4<f32>, |
| @location(0) |
| worldPos : vec3<f32>, |
| @location(1) |
| view : vec3<f32>, |
| @location(2) |
| texcoord : vec2<f32>, |
| @location(3) |
| texcoord2 : vec2<f32>, |
| @location(4) |
| color : vec4<f32>, |
| @location(5) |
| instanceColor : vec4<f32>, |
| @location(6) |
| normal : vec3<f32>, |
| @location(7) |
| tangent : vec3<f32>, |
| @location(8) |
| bitangent : vec3<f32>, |
| } |
| |
| struct Camera { |
| projection : mat4x4<f32>, |
| inverseProjection : mat4x4<f32>, |
| view : mat4x4<f32>, |
| position : vec3<f32>, |
| time : f32, |
| outputSize : vec2<f32>, |
| zNear : f32, |
| zFar : f32, |
| } |
| |
| @binding(0) @group(0) var<uniform> camera : Camera; |
| |
| fn getInstanceMatrix(input : VertexInput) -> mat4x4<f32> { |
| return mat4x4(input.instance0, input.instance1, input.instance2, input.instance3); |
| } |
| |
| struct Joints { |
| matrices : array<mat4x4<f32>>, |
| } |
| |
| @binding(1) @group(0) var<storage, read> joint : Joints; |
| |
| @binding(2) @group(0) var<storage, read> inverseBind : Joints; |
| |
| fn getSkinMatrix(input : VertexInput) -> mat4x4<f32> { |
| let joint0 = (joint.matrices[input.joints.x] * inverseBind.matrices[input.joints.x]); |
| let joint1 = (joint.matrices[input.joints.y] * inverseBind.matrices[input.joints.y]); |
| let joint2 = (joint.matrices[input.joints.z] * inverseBind.matrices[input.joints.z]); |
| let joint3 = (joint.matrices[input.joints.w] * inverseBind.matrices[input.joints.w]); |
| let skinMatrix = ((((joint0 * input.weights.x) + (joint1 * input.weights.y)) + (joint2 * input.weights.z)) + (joint3 * input.weights.w)); |
| return skinMatrix; |
| } |
| |
| @vertex |
| fn vertexMain(input : VertexInput) -> VertexOutput { |
| var output : VertexOutput; |
| let modelMatrix = getSkinMatrix(input); |
| output.normal = normalize(((modelMatrix * vec4(input.normal, 0.0))).xyz); |
| output.tangent = normalize(((modelMatrix * vec4(input.tangent.xyz, 0.0))).xyz); |
| output.bitangent = (cross(output.normal, output.tangent) * input.tangent.w); |
| output.color = vec4(1.0); |
| output.texcoord = input.texcoord; |
| output.instanceColor = input.instanceColor; |
| let modelPos = (modelMatrix * input.position); |
| output.worldPos = modelPos.xyz; |
| output.view = (camera.position - modelPos.xyz); |
| output.position = ((camera.projection * camera.view) * modelPos); |
| return output; |
| } |