|  | 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; | 
|  | } |