Files
game_engine/crates/voltex_renderer/src/instanced_shader.wgsl
2026-03-26 15:14:12 +09:00

82 lines
2.3 KiB
WebGPU Shading Language

struct CameraUniform {
view_proj: mat4x4<f32>,
model: mat4x4<f32>,
camera_pos: vec3<f32>,
_pad: 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 InstanceInput {
@location(4) model_0: vec4<f32>,
@location(5) model_1: vec4<f32>,
@location(6) model_2: vec4<f32>,
@location(7) model_3: vec4<f32>,
@location(8) color: 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>,
@location(3) inst_color: vec4<f32>,
};
@vertex
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VertexOutput {
let inst_model = mat4x4<f32>(
instance.model_0,
instance.model_1,
instance.model_2,
instance.model_3,
);
var out: VertexOutput;
let world_pos = inst_model * vec4<f32>(vertex.position, 1.0);
out.world_pos = world_pos.xyz;
out.world_normal = normalize((inst_model * vec4<f32>(vertex.normal, 0.0)).xyz);
out.clip_position = camera.view_proj * world_pos;
out.uv = vertex.uv;
out.inst_color = instance.color;
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);
let ndotl = max(dot(normal, light_dir), 0.0);
let diffuse = light.color * ndotl;
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.3;
let ambient = light.color * light.ambient_strength;
let lit = (ambient + diffuse + specular) * tex_color.rgb * in.inst_color.rgb;
return vec4<f32>(lit, tex_color.a * in.inst_color.a);
}