Files
WebGPU-Framework/shaders/triangle-list-texture.wgsl
2025-11-17 15:06:39 +01:00

93 lines
2.6 KiB
WebGPU Shading Language

@group(0) @binding(0)
var<uniform> viewProjectionMatrix : mat4x4<f32>;
@group(0) @binding(1)
var<storage, read> instancePositions : array<vec4<f32>>;
@group(0) @binding(2)
var<uniform> cameraPosition : vec3<f32>;
@group(0) @binding(3)
var myTexture : texture_2d<f32>;
@group(0) @binding(4)
var mySampler : sampler;
struct VertexOutput {
@builtin(position) position : vec4<f32>,
@location(0) worldPosition : vec3<f32>,
@location(1) worldNormal : vec3<f32>,
@location(2) uv : vec2<f32>,
};
@vertex
fn vertexEntryPoint(
@location(0) position : vec3<f32>,
@location(1) normal : vec3<f32>,
@location(2) uv : vec2<f32>,
@builtin(instance_index) instanceIndex : u32
) -> VertexOutput {
var output : VertexOutput;
let instanceOffset = instancePositions[instanceIndex].xyz;
let worldPosition = position + instanceOffset;
output.worldPosition = worldPosition;
output.worldNormal = normalize(normal);
output.position = viewProjectionMatrix * vec4<f32>(worldPosition, 1.0);
output.uv = uv;
return output;
}
@fragment
fn fragmentEntryPoint(
@location(0) worldPosition : vec3<f32>,
@location(1) worldNormal : vec3<f32>,
@location(2) uv : vec2<f32>
) -> @location(0) vec4<f32> {
// For test: encode UV as color (no texture sampling)
//let baseColor = vec3<f32>(uv, 0.0);
let baseColor = textureSample(myTexture, mySampler, uv).rgb;
let pi = 3.14159265;
let invPi = 0.318309886;
let N = normalize(worldNormal);
let V = normalize(cameraPosition - worldPosition);
let L = normalize(vec3<f32>(0.5, 1.0, 0.3));
let H = normalize(V + L);
let metallic = 0.2;
let roughness = 0.4;
let rough2 = roughness * roughness;
let lightColor = vec3<f32>(1.0);
let NdotV = max(dot(N, V), 0.001);
let NdotL = max(dot(N, L), 0.001);
let NdotH = max(dot(N, H), 0.001);
let HdotV = max(dot(H, V), 0.001);
let F0 = mix(vec3<f32>(0.04), baseColor, metallic);
let f = pow(1.0 - HdotV, 5.0);
let F = F0 + (1.0 - F0) * f;
let a2 = rough2 * rough2;
let NdotH2 = NdotH * NdotH;
let denom = NdotH2 * (a2 - 1.0) + 1.0;
let NDF = a2 / (pi * denom * denom);
let k = (roughness + 1.0);
let k2 = (k * k) / 8.0;
let Gv = NdotV / (NdotV * (1.0 - k2) + k2);
let Gl = NdotL / (NdotL * (1.0 - k2) + k2);
let G = Gv * Gl;
let spec = (NDF * G * F) / (4.0 * NdotV * NdotL + 0.001);
let kd = (vec3<f32>(1.0) - F) * (1.0 - metallic);
let diff = kd * baseColor * invPi;
let color = (diff + spec) * lightColor * NdotL + vec3<f32>(0.03) * baseColor;
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), 1.0);
}