struct Configuration { matrix: mat4x4f, matrixWorld: mat4x4f, }; @group(0) @binding(0) var config: Configuration; @group(0) @binding(1) var nodeMatrix: array; /* struct Imm { nodeIndex: i32, }; var imm: Imm; */ struct VertexInput { @location(0) position: vec3f, @location(1) normal: vec3f, @location(2) texture: vec2f, @builtin(instance_index) instance: u32, }; struct VertexOutput { @builtin(position) position: vec4f, @location(0) positionWorld: vec3f, @location(1) normal: vec3f, }; struct FragmentInput { @location(0) positionWorld: vec3f, @location(1) normal: vec3f, }; @vertex fn vertexMain(input: VertexInput) -> VertexOutput { let position = nodeMatrix[input.instance] * vec4f(input.position, 1); //let position = vec4f(input.position, 1); let normal = vec4f(input.normal, 0.0f); var output: VertexOutput; output.position = config.matrix * position; output.positionWorld = (config.matrixWorld * position).xyz; output.normal = (config.matrixWorld * normal).xyz; return output; } fn schlickFresnel(R0: vec3f, normal: vec3f, lightVector: vec3f) -> vec3f { let incidentAngle = saturate(dot(normal, lightVector)); let f0 = 1.0 - incidentAngle; let reflectPercent = R0 + (1.0f - R0) * (f0 * f0 * f0 * f0 * f0); return reflectPercent; } fn blinnPhong(ndotl: f32, lightVector: vec3f, normal: vec3f, toEye: vec3f) -> vec3f { let roughness = 0.1; let m = roughness * 256.0; let halfVec = normalize(toEye + lightVector); let roughnessFactor = (m + 8.0) * pow(ndotl, m) / 8.0f; let fresnelR0 = vec3f(0.95f, 0.95f, 0.95f); let fresnelFactor = schlickFresnel(fresnelR0, normal, lightVector); let specular = fresnelFactor * roughnessFactor; return specular; } fn lighting(position: vec3f, normal: vec3f) -> vec3f { let d = 0.9; let eyePosition = vec3f(d, d / 2, d); let lightPosition = vec3f(1, 1, 1); let lightVector = normalize(lightPosition - position); let ndotl = max(dot(lightVector, normal), 0.0); let intensity = (ndotl + 0.3) / 1.3; let toEye = normalize(eyePosition - position); return (1.0 + blinnPhong(ndotl, lightVector, normal, toEye)) * intensity; } @fragment fn fragmentMain(input: FragmentInput) -> @location(0) vec4f { let intensity = lighting(input.positionWorld, normalize(input.normal)); return vec4(intensity, 1.0); }