struct Configuration { viewProj: mat4x4f, lightViewProj: mat4x4f, lightPosition: vec4f, eyePosition: vec4f, }; @group(0) @binding(0) var config: Configuration; @group(0) @binding(1) var nodeMatrix: array; @group(0) @binding(2) var linearSampler: sampler; @group(0) @binding(3) var colorTexture: texture_2d; /* 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, @location(2) texture: vec2f, @location(3) lightPosition: vec3f, @location(4) eyePosition: 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.viewProj * position; output.positionWorld = (position).xyz; output.normal = (normal).xyz; output.texture = input.texture; output.lightPosition = config.lightPosition.xyz; output.eyePosition = config.eyePosition.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, lightPosition: vec3f, eyePosition: vec3f, normal: vec3f) -> vec3f { 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: VertexOutput) -> @location(0) vec4f { let intensity = lighting(input.positionWorld, input.lightPosition, input.eyePosition, normalize(input.normal)); let color = textureSample(colorTexture, linearSampler, input.texture); return vec4(color.xyz * intensity, 1.0); }