#import bevy_pbr::mesh_functions as mesh_functions #import bevy_pbr::skinning #import bevy_pbr::morph #import bevy_pbr::mesh_bindings mesh #import bevy_pbr::mesh_vertex_output MeshVertexOutput #import bevy_render::instance_index get_instance_index struct Vertex { @builtin(instance_index) instance_index: u32, #ifdef VERTEX_POSITIONS @location(0) position: vec3, #endif #ifdef VERTEX_NORMALS @location(1) normal: vec3, #endif #ifdef VERTEX_UVS @location(2) uv: vec2, #endif // (Alternate UVs are at location 3, but they're currently unused here.) #ifdef VERTEX_TANGENTS @location(4) tangent: vec4, #endif #ifdef VERTEX_COLORS @location(5) color: vec4, #endif #ifdef SKINNED @location(6) joint_indices: vec4, @location(7) joint_weights: vec4, #endif #ifdef MORPH_TARGETS @builtin(vertex_index) index: u32, #endif }; #ifdef MORPH_TARGETS fn morph_vertex(vertex_in: Vertex) -> Vertex { var vertex = vertex_in; let weight_count = bevy_pbr::morph::layer_count(); for (var i: u32 = 0u; i < weight_count; i ++) { let weight = bevy_pbr::morph::weight_at(i); if weight == 0.0 { continue; } vertex.position += weight * bevy_pbr::morph::morph(vertex.index, bevy_pbr::morph::position_offset, i); #ifdef VERTEX_NORMALS vertex.normal += weight * bevy_pbr::morph::morph(vertex.index, bevy_pbr::morph::normal_offset, i); #endif #ifdef VERTEX_TANGENTS vertex.tangent += vec4(weight * bevy_pbr::morph::morph(vertex.index, bevy_pbr::morph::tangent_offset, i), 0.0); #endif } return vertex; } #endif @vertex fn vertex(vertex_no_morph: Vertex) -> MeshVertexOutput { var out: MeshVertexOutput; #ifdef MORPH_TARGETS var vertex = morph_vertex(vertex_no_morph); #else var vertex = vertex_no_morph; #endif #ifdef SKINNED var model = bevy_pbr::skinning::skin_model(vertex.joint_indices, vertex.joint_weights); #else // Use vertex_no_morph.instance_index instead of vertex.instance_index to work around a wgpu dx12 bug. // See https://github.com/gfx-rs/naga/issues/2416 . var model = mesh_functions::get_model_matrix(vertex_no_morph.instance_index); #endif #ifdef VERTEX_NORMALS #ifdef SKINNED out.world_normal = bevy_pbr::skinning::skin_normals(model, vertex.normal); #else out.world_normal = mesh_functions::mesh_normal_local_to_world( vertex.normal, // Use vertex_no_morph.instance_index instead of vertex.instance_index to work around a wgpu dx12 bug. // See https://github.com/gfx-rs/naga/issues/2416 get_instance_index(vertex_no_morph.instance_index) ); #endif #endif #ifdef VERTEX_POSITIONS out.world_position = mesh_functions::mesh_position_local_to_world(model, vec4(vertex.position, 1.0)); out.position = mesh_functions::mesh_position_world_to_clip(out.world_position); #endif #ifdef VERTEX_UVS out.uv = vertex.uv; #endif #ifdef VERTEX_TANGENTS out.world_tangent = mesh_functions::mesh_tangent_local_to_world( model, vertex.tangent, // Use vertex_no_morph.instance_index instead of vertex.instance_index to work around a wgpu dx12 bug. // See https://github.com/gfx-rs/naga/issues/2416 get_instance_index(vertex_no_morph.instance_index) ); #endif #ifdef VERTEX_COLORS out.color = vertex.color; #endif #ifdef VERTEX_OUTPUT_INSTANCE_INDEX // Use vertex_no_morph.instance_index instead of vertex.instance_index to work around a wgpu dx12 bug. // See https://github.com/gfx-rs/naga/issues/2416 out.instance_index = get_instance_index(vertex_no_morph.instance_index); #endif return out; } @fragment fn fragment( mesh: MeshVertexOutput, ) -> @location(0) vec4 { #ifdef VERTEX_COLORS return mesh.color; #else return vec4(1.0, 0.0, 1.0, 1.0); #endif }