-
Notifications
You must be signed in to change notification settings - Fork 428
/
Copy pathinstanced_mesh.wgsl
95 lines (76 loc) · 2.92 KB
/
instanced_mesh.wgsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#import <./types.wgsl>
#import <./global_bindings.wgsl>
#import <./mesh_vertex.wgsl>
#import <./utils/srgb.wgsl>
@group(1) @binding(0)
var albedo_texture: texture_2d<f32>;
// Keep in sync with gpu_data::MaterialUniformBuffer in mesh.rs
struct MaterialUniformBuffer {
albedo_factor: Vec4,
};
@group(1) @binding(1)
var<uniform> material: MaterialUniformBuffer;
struct VertexOut {
@builtin(position)
position: Vec4,
@location(0)
color: Vec4, // 0-1 linear space with unmultiplied/separate alpha
@location(1)
texcoord: Vec2,
@location(2)
normal_world_space: Vec3,
@location(3) @interpolate(flat)
additive_tint_rgb: Vec3, // 0-1 linear space
@location(4) @interpolate(flat)
outline_mask_ids: UVec2,
@location(5) @interpolate(flat)
picking_layer_id: UVec4,
};
@vertex
fn vs_main(in_vertex: VertexIn, in_instance: InstanceIn) -> VertexOut {
let world_position = Vec3(
dot(in_instance.world_from_mesh_row_0.xyz, in_vertex.position) + in_instance.world_from_mesh_row_0.w,
dot(in_instance.world_from_mesh_row_1.xyz, in_vertex.position) + in_instance.world_from_mesh_row_1.w,
dot(in_instance.world_from_mesh_row_2.xyz, in_vertex.position) + in_instance.world_from_mesh_row_2.w,
);
let world_normal = Vec3(
dot(in_instance.world_from_mesh_normal_row_0.xyz, in_vertex.normal),
dot(in_instance.world_from_mesh_normal_row_1.xyz, in_vertex.normal),
dot(in_instance.world_from_mesh_normal_row_2.xyz, in_vertex.normal),
);
var out: VertexOut;
out.position = frame.projection_from_world * Vec4(world_position, 1.0);
out.color = linear_from_srgba(in_vertex.color);
out.texcoord = in_vertex.texcoord;
out.normal_world_space = world_normal;
out.additive_tint_rgb = linear_from_srgb(in_instance.additive_tint_srgb.rgb);
out.outline_mask_ids = in_instance.outline_mask_ids;
out.picking_layer_id = in_instance.picking_layer_id;
return out;
}
@fragment
fn fs_main_shaded(in: VertexOut) -> @location(0) Vec4 {
let albedo = textureSample(albedo_texture, trilinear_sampler, in.texcoord).rgb
* in.color.rgb
* material.albedo_factor.rgb
+ in.additive_tint_rgb;
if all(in.normal_world_space == Vec3(0.0, 0.0, 0.0)) {
// no normal, no shading
return Vec4(albedo, 1.0);
} else {
// Hardcoded lambert lighting. TODO(andreas): Some microfacet model.
let light_dir = normalize(vec3(1.0, 2.0, 0.0)); // TODO(andreas): proper lighting
let normal = normalize(in.normal_world_space);
let shading = clamp(dot(normal, light_dir), 0.0, 1.0) + 0.2;
let radiance = albedo * shading;
return Vec4(radiance, 1.0);
}
}
@fragment
fn fs_main_picking_layer(in: VertexOut) -> @location(0) UVec4 {
return in.picking_layer_id;
}
@fragment
fn fs_main_outline_mask(in: VertexOut) -> @location(0) UVec2 {
return in.outline_mask_ids;
}