Skip to content

Commit

Permalink
feat: improve skin shader
Browse files Browse the repository at this point in the history
  • Loading branch information
matteopolak committed Mar 27, 2024
1 parent 037146a commit 2c893fb
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 48 deletions.
89 changes: 41 additions & 48 deletions crates/skin-renderer/shader.wgsl
Original file line number Diff line number Diff line change
@@ -1,81 +1,74 @@
struct Camera {
view_pos: vec4<f32>,
view_proj: mat4x4<f32>,
viewPos: vec4<f32>,
viewProj: mat4x4<f32>,
};

@group(1) @binding(0)
var<uniform> camera: Camera;
@group(1) @binding(0) var<uniform> camera: Camera;

struct Light {
position: vec3<f32>,
color: vec3<f32>,
}
@group(2) @binding(0)
var<uniform> light: Light;

@group(2) @binding(0) var<uniform> light: Light;

struct VertexInput {
@location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>,
@location(1) texCoords: vec2<f32>,
@location(2) normal: vec3<f32>,
};

struct InstanceInput {
@location(5) model_matrix_0: vec4<f32>,
@location(6) model_matrix_1: vec4<f32>,
@location(7) model_matrix_2: vec4<f32>,
@location(8) model_matrix_3: vec4<f32>,
@location(9) normal_matrix_0: vec3<f32>,
@location(10) normal_matrix_1: vec3<f32>,
@location(11) normal_matrix_2: vec3<f32>,
@location(5) modelMatrix0: vec4<f32>,
@location(6) modelMatrix1: vec4<f32>,
@location(7) modelMatrix2: vec4<f32>,
@location(8) modelMatrix3: vec4<f32>,
@location(9) normalMatrix0: vec3<f32>,
@location(10) normalMatrix1: vec3<f32>,
@location(11) normalMatrix2: vec3<f32>,
}

struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,
@location(1) world_normal: vec3<f32>,
@location(2) world_position: vec3<f32>,
@builtin(position) clipPosition: vec4<f32>,
@location(0) texCoords: vec2<f32>,
@location(1) worldNormal: vec3<f32>,
@location(2) worldPosition: vec3<f32>,
}

@vertex
fn vs_main(model: VertexInput, instance: InstanceInput) -> VertexOutput {
let model_matrix = mat4x4<f32>(
instance.model_matrix_0,
instance.model_matrix_1,
instance.model_matrix_2,
instance.model_matrix_3,
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VertexOutput {
let modelMatrix = mat4x4<f32>(
instance.modelMatrix0, instance.modelMatrix1,
instance.modelMatrix2, instance.modelMatrix3,
);

let normal_matrix = mat3x3<f32>(
instance.normal_matrix_0,
instance.normal_matrix_1,
instance.normal_matrix_2,
let normalMatrix = mat3x3<f32>(
instance.normalMatrix0, instance.normalMatrix1, instance.normalMatrix2,
);

var out: VertexOutput;
var output: VertexOutput;

out.tex_coords = model.tex_coords;
out.world_normal = normal_matrix * model.normal;
out.world_position = (model_matrix * vec4<f32>(model.position, 1.0)).xyz;
out.clip_position = camera.view_proj * vec4<f32>(out.world_position, 1.0);
output.texCoords = vertex.texCoords;
output.worldNormal = normalMatrix * vertex.normal;
output.worldPosition = (modelMatrix * vec4<f32>(vertex.position, 1.0)).xyz;
output.clipPosition = camera.viewProj * vec4<f32>(output.worldPosition, 1.0);

return out;
return output;
}

// Fragment shader
@group(0) @binding(0)
var t_diffuse: texture_2d<f32>;

@group(0)@binding(1)
var s_diffuse: sampler;
@group(0) @binding(0) var tDiffuse: texture_2d<f32>;
@group(0) @binding(1) var sDiffuse: sampler;

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
let light_dir = normalize(light.position - in.world_position);
let ambient_color = 0.1 * light.color;
let diffuse_color = light.color * max(dot(in.world_normal, light_dir), 0.0);
let half_dir = normalize(normalize(camera.view_pos.xyz - in.world_position) + light_dir);
let specular_color = pow(max(dot(in.world_normal, half_dir), 0.0), 32.0) * light.color;
fn fs_main(fragmentInput: VertexOutput) -> @location(0) vec4<f32> {
let objectColor = textureSample(tDiffuse, sDiffuse, fragmentInput.texCoords);
let lightDir = normalize(light.position - fragmentInput.worldPosition);
let ambient = 0.1 * light.color;
let diffuse = max(dot(fragmentInput.worldNormal, lightDir), 0.0) * light.color;
let viewDir = normalize(camera.viewPos.xyz - fragmentInput.worldPosition);
let halfDir = normalize(viewDir + lightDir);
let specular = pow(max(dot(fragmentInput.worldNormal, halfDir), 0.0), 32.0) * light.color;
let color = (ambient + diffuse + specular) * objectColor.xyz;

return vec4<f32>((ambient_color + diffuse_color + specular_color) * object_color.xyz, object_color.a);
return vec4<f32>(color, objectColor.a);
}
11 changes: 11 additions & 0 deletions crates/skin-renderer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ async fn main() {
.get_or_init(skin_renderer::create_renderer)
.await;

// save the output to a file
let output = renderer
.render(
skin_renderer::SkinKind::Classic,
if url == "none" { None } else { Some(url) },
)
.await
.unwrap();

std::fs::write("output.png", output).unwrap();

for _ in 0..1_000 {
// Warmup
let _ = renderer
Expand Down

0 comments on commit 2c893fb

Please sign in to comment.