68 lines
1.9 KiB
WebGPU Shading Language
68 lines
1.9 KiB
WebGPU Shading Language
struct CameraUniform {
|
|
view_proj: mat4x4<f32>,
|
|
model: mat4x4<f32>,
|
|
camera_pos: vec3<f32>,
|
|
alpha: f32,
|
|
};
|
|
|
|
struct LightUniform {
|
|
direction: vec3<f32>,
|
|
_pad0: f32,
|
|
color: vec3<f32>,
|
|
ambient_strength: f32,
|
|
};
|
|
|
|
@group(0) @binding(0) var<uniform> camera: CameraUniform;
|
|
@group(0) @binding(1) var<uniform> light: LightUniform;
|
|
|
|
@group(1) @binding(0) var t_diffuse: texture_2d<f32>;
|
|
@group(1) @binding(1) var s_diffuse: sampler;
|
|
|
|
struct VertexInput {
|
|
@location(0) position: vec3<f32>,
|
|
@location(1) normal: vec3<f32>,
|
|
@location(2) uv: vec2<f32>,
|
|
@location(3) tangent: vec4<f32>,
|
|
};
|
|
|
|
struct VertexOutput {
|
|
@builtin(position) clip_position: vec4<f32>,
|
|
@location(0) world_normal: vec3<f32>,
|
|
@location(1) world_pos: vec3<f32>,
|
|
@location(2) uv: vec2<f32>,
|
|
};
|
|
|
|
@vertex
|
|
fn vs_main(in: VertexInput) -> VertexOutput {
|
|
var out: VertexOutput;
|
|
let world_pos = camera.model * vec4<f32>(in.position, 1.0);
|
|
out.world_pos = world_pos.xyz;
|
|
out.world_normal = normalize((camera.model * vec4<f32>(in.normal, 0.0)).xyz);
|
|
out.clip_position = camera.view_proj * world_pos;
|
|
out.uv = in.uv;
|
|
return out;
|
|
}
|
|
|
|
@fragment
|
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
|
let tex_color = textureSample(t_diffuse, s_diffuse, in.uv);
|
|
let normal = normalize(in.world_normal);
|
|
let light_dir = normalize(-light.direction);
|
|
|
|
// Diffuse
|
|
let ndotl = max(dot(normal, light_dir), 0.0);
|
|
let diffuse = light.color * ndotl;
|
|
|
|
// Specular (Blinn-Phong)
|
|
let view_dir = normalize(camera.camera_pos - in.world_pos);
|
|
let half_dir = normalize(light_dir + view_dir);
|
|
let spec = pow(max(dot(normal, half_dir), 0.0), 32.0);
|
|
let specular = light.color * spec * 0.5;
|
|
|
|
// Ambient
|
|
let ambient = light.color * light.ambient_strength;
|
|
|
|
let lit = (ambient + diffuse + specular) * tex_color.rgb;
|
|
return vec4<f32>(lit, camera.alpha);
|
|
}
|