mirror of
https://github.com/bevyengine/bevy
synced 2024-12-25 20:43:07 +00:00
3f5a090b1b
# Objective - The StandardMaterial always uses ATTRIBUTE_UV_0 for each texture except lightmap. This is not flexible enough for a lot of gltf Files. - Fixes #12496 - Fixes #13086 - Fixes #13122 - Closes #13153 ## Solution - The StandardMaterial gets extended for each texture by an UvChannel enum. It defaults to Uv0 but can also be set to Uv1. - The gltf loader now handles the texcoord information. If the texcoord is not supported it creates a warning. - It uses StandardMaterial shader defs to define which attribute to use. ## Testing This fixes #12496 for example: ![wall_fixed](https://github.com/bevyengine/bevy/assets/688816/bc37c9e1-72ba-4e59-b092-5ee10dade603) For testing of all kind of textures I used the TextureTransformMultiTest from https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/TextureTransformMultiTest Its purpose is to test multiple texture transfroms but it is also a good test for different texcoords. It also shows the issue with emission #13133. Before: ![TextureTransformMultiTest_main](https://github.com/bevyengine/bevy/assets/688816/aa701d04-5a3f-4df1-a65f-fc770ab6f4ab) After: ![TextureTransformMultiTest_texcoord](https://github.com/bevyengine/bevy/assets/688816/c3f91943-b830-4068-990f-e4f2c97771ee)
110 lines
3.1 KiB
WebGPU Shading Language
110 lines
3.1 KiB
WebGPU Shading Language
#import bevy_pbr::{
|
|
mesh_functions,
|
|
skinning,
|
|
morph::morph,
|
|
forward_io::{Vertex, VertexOutput},
|
|
view_transformations::position_world_to_clip,
|
|
}
|
|
|
|
#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 * morph(vertex.index, bevy_pbr::morph::position_offset, i);
|
|
#ifdef VERTEX_NORMALS
|
|
vertex.normal += weight * morph(vertex.index, bevy_pbr::morph::normal_offset, i);
|
|
#endif
|
|
#ifdef VERTEX_TANGENTS
|
|
vertex.tangent += vec4(weight * morph(vertex.index, bevy_pbr::morph::tangent_offset, i), 0.0);
|
|
#endif
|
|
}
|
|
return vertex;
|
|
}
|
|
#endif
|
|
|
|
@vertex
|
|
fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
|
|
var out: VertexOutput;
|
|
|
|
#ifdef MORPH_TARGETS
|
|
var vertex = morph_vertex(vertex_no_morph);
|
|
#else
|
|
var vertex = vertex_no_morph;
|
|
#endif
|
|
|
|
#ifdef SKINNED
|
|
var model = 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 = 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
|
|
vertex_no_morph.instance_index
|
|
);
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef VERTEX_POSITIONS
|
|
out.world_position = mesh_functions::mesh_position_local_to_world(model, vec4<f32>(vertex.position, 1.0));
|
|
out.position = position_world_to_clip(out.world_position.xyz);
|
|
#endif
|
|
|
|
#ifdef VERTEX_UVS_A
|
|
out.uv = vertex.uv;
|
|
#endif
|
|
#ifdef VERTEX_UVS_B
|
|
out.uv_b = vertex.uv_b;
|
|
#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
|
|
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 = vertex_no_morph.instance_index;
|
|
#endif
|
|
|
|
#ifdef VISIBILITY_RANGE_DITHER
|
|
out.visibility_range_dither = mesh_functions::get_visibility_range_dither_level(
|
|
vertex_no_morph.instance_index, model[3]);
|
|
#endif
|
|
|
|
return out;
|
|
}
|
|
|
|
@fragment
|
|
fn fragment(
|
|
mesh: VertexOutput,
|
|
) -> @location(0) vec4<f32> {
|
|
#ifdef VERTEX_COLORS
|
|
return mesh.color;
|
|
#else
|
|
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
|
|
#endif
|
|
}
|