Add textured OBJ model rendering

This commit is contained in:
lenn
2026-06-25 17:41:18 +08:00
parent ec46e53c75
commit 156df50d33
14 changed files with 1777 additions and 20 deletions

View File

@@ -8,6 +8,12 @@ struct MatrixUniform {
@group(0) @binding(0)
var<uniform> u: MatrixUniform;
@group(1) @binding(0)
var model_texture: texture_2d<f32>;
@group(1) @binding(1)
var model_sampler: sampler;
fn saturate(value: f32) -> f32 {
return clamp(value, 0.0, 1.0);
}
@@ -305,4 +311,48 @@ fn fs_dot(in: DotVertexOutput) -> @location(0) vec4f {
let alpha = max(core, glow);
return vec4f(color, alpha);
}
}
// model
struct ModelVertexInput {
@location(0) position: vec3f,
@location(1) tex_coords: vec2f,
@location(2) normal: vec3f,
@location(5) model_0: vec4f,
@location(6) model_1: vec4f,
@location(7) model_2: vec4f,
@location(8) model_3: vec4f,
}
struct ModelVertexOutput {
@builtin(position) clip_position: vec4f,
@location(0) world_normal: vec3f,
@location(1) world_position: vec3f,
@location(2) tex_coords: vec2f,
}
@vertex
fn vs_model(vertex: ModelVertexInput) -> ModelVertexOutput {
let model = mat4x4f(vertex.model_0, vertex.model_1, vertex.model_2, vertex.model_3);
let world_position = model * vec4f(vertex.position, 1.0);
let normal_matrix = mat3x3f(model[0].xyz, model[1].xyz, model[2].xyz);
var out: ModelVertexOutput;
out.clip_position = u.view_proj * world_position;
out.world_position = world_position.xyz;
out.world_normal = normalize(normal_matrix * vertex.normal);
out.tex_coords = vec2f(vertex.tex_coords.x, 1.0 - vertex.tex_coords.y);
return out;
}
@fragment
fn fs_model(in: ModelVertexOutput) -> @location(0) vec4f {
let light_dir = normalize(vec3f(-0.35, 0.85, 0.45));
let normal = normalize(in.world_normal);
let diffuse = max(dot(normal, light_dir), 0.0);
let rim = pow(1.0 - saturate(abs(normal.y)), 2.0) * 0.16;
let base = textureSample(model_texture, model_sampler, in.tex_coords).rgb;
let color = base * (0.28 + diffuse * 0.72) + vec3f(0.14, 0.24, 0.32) * rim;
return vec4f(color, 1.0);
}