Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions assets/shaders/custom_stencil.wesl
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ fn vertex(vertex: Vertex) -> VertexOutput {
// This is how bevy computes the world position
// The vertex.instance_index is very important. Especially if you are using batching and gpu preprocessing
var world_from_local = mesh_functions::get_world_from_local(vertex.instance_index);
@if(VERTEX_POSITIONS_COMPRESSED)
let mesh_uniform = bevy_pbr::render::mesh_bindings::mesh[vertex.instance_index];
@if(VERTEX_POSITIONS_COMPRESSED)
let vertex_position = bevy_render::utils::decompress_vertex_position(vertex.compressed_position, mesh_uniform.aabb_center, mesh_uniform.aabb_half_extents);
@else
@if(VERTEX_POSITIONS_COMPRESSED) {
let mesh_metadata = bevy_pbr::render::mesh_functions::get_metadata(vertex.instance_index);
let vertex_position = bevy_render::utils::decompress_vertex_position(vertex.compressed_position, mesh_metadata.aabb_center, mesh_metadata.aabb_half_extents);
}
@else {
let vertex_position = vertex.position;
}
out.world_position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4(vertex_position, 1.0));
out.clip_position = position_world_to_clip(out.world_position.xyz);
return out;
Expand Down
25 changes: 18 additions & 7 deletions assets/shaders/specialized_mesh_pipeline.wesl
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ struct Vertex {
@else
@location(0) position: vec3<f32>,
// and color at location 1
@if(VERTEX_COLORS)
@location(1) color: vec4<f32>,
};

/// This is the output of the vertex shader and we also use it as the input for the fragment shader
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) world_position: vec4<f32>,
@if(VERTEX_COLORS)
@location(1) color: vec3<f32>,
};

Expand All @@ -35,23 +37,32 @@ fn vertex(vertex: Vertex) -> VertexOutput {
// This is how bevy computes the world position
// The vertex.instance_index is very important. Especially if you are using batching and gpu preprocessing
var world_from_local = mesh_functions::get_world_from_local(vertex.instance_index);
@if(VERTEX_POSITIONS_COMPRESSED)
let mesh_uniform = bevy_pbr::render::mesh_bindings::mesh[vertex.instance_index];
@if(VERTEX_POSITIONS_COMPRESSED)
let vertex_position = bevy_render::utils::decompress_vertex_position(vertex.compressed_position, mesh_uniform.aabb_center, mesh_uniform.aabb_half_extents);
@else
@if(VERTEX_POSITIONS_COMPRESSED) {
Comment thread
beicause marked this conversation as resolved.
let mesh_metadata = bevy_pbr::render::mesh_functions::get_metadata(vertex.instance_index);
let vertex_position = bevy_render::utils::decompress_vertex_position(vertex.compressed_position, mesh_metadata.aabb_center, mesh_metadata.aabb_half_extents);
}
@else {
let vertex_position = vertex.position;
}
out.world_position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4(vertex_position, 1.0));
out.clip_position = position_world_to_clip(out.world_position.xyz);

// We just use the raw vertex color
@if(VERTEX_COLORS)
out.color = vertex.color.rgb;

return out;
}

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
// We just use the raw vertex color if the mesh provides one, otherwise
// we fall back to a hardcoded color (e.g. for the rectangle mesh,
// which has no vertex color attribute).
@if(VERTEX_COLORS)
let color = in.color;
@else
let color = vec3<f32>(1.0, 1.0, 1.0);

// output the color directly
return vec4(in.color, 1.0);
return vec4(color, 1.0);
}
18 changes: 17 additions & 1 deletion examples/shader_advanced/custom_render_phase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::ops::Range;

use bevy::camera::Viewport;
use bevy::core_pipeline::core_3d::TransparentSortingInfo3d;
use bevy::mesh::MeshAttributeCompressionFlags;
use bevy::mesh::{MeshAttributeCompressionFlags, MeshCompressionArgs};
use bevy::pbr::{self, MeshPipelineSystems, SetMeshViewEmptyBindGroup, ViewKeyCache};
use bevy::{
camera::MainPassResolutionOverride,
Expand Down Expand Up @@ -94,6 +94,22 @@ fn setup(
// The circle doesn't have it so it won't be rendered in our pass
DrawStencil,
));
commands.spawn((
Mesh3d(
meshes.add(
Sphere::new(0.5)
.mesh()
.build()
.compressed_mesh(&MeshCompressionArgs::regular())
.unwrap(),
),
),
Comment thread
beicause marked this conversation as resolved.
MeshMaterial3d(materials.add(Color::srgb_u8(124, 255, 144))),
Transform::from_xyz(2.0, 0.5, 0.0),
// This marker component is used to identify which mesh will be used in our custom pass
// The circle doesn't have it so it won't be rendered in our pass
DrawStencil,
));
// light
commands.spawn((
PointLight {
Expand Down
24 changes: 23 additions & 1 deletion examples/shader_advanced/specialized_mesh_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use bevy::{
core_pipeline::core_3d::{Opaque3d, Opaque3dBatchSetKey, Opaque3dBinKey, CORE_3D_DEPTH_FORMAT},
ecs::change_detection::Tick,
math::{vec3, vec4},
mesh::{Indices, MeshAttributeCompressionFlags, MeshVertexBufferLayoutRef, PrimitiveTopology},
mesh::{
Indices, MeshAttributeCompressionFlags, MeshCompressionArgs, MeshVertexBufferLayoutRef,
PrimitiveTopology,
},
pbr::{
DrawMesh, MeshPipeline, MeshPipelineKey, MeshPipelineSystems, MeshPipelineViewLayoutKey,
RenderMeshInstances, SetMeshBindGroup, SetMeshViewBindGroup, SetMeshViewEmptyBindGroup,
Expand Down Expand Up @@ -90,6 +93,24 @@ fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
Transform::from_xyz(x, y, 0.0),
));
}
commands.spawn((
// We use a marker component to identify the mesh that will be rendered
// with our specialized pipeline
CustomRenderedEntity,
// We need to add the mesh handle to the entity
Mesh3d(
meshes.add(
Rectangle::new(0.5, 0.5)
.mesh()
.build()
.with_removed_attribute(Mesh::ATTRIBUTE_NORMAL)
.with_removed_attribute(Mesh::ATTRIBUTE_UV_0)
.compressed_mesh(&MeshCompressionArgs::regular())
.unwrap(),
),
),
Transform::from_xyz(0.0, -1.0 / 3.0, -1.0),
));

// Spawn the camera.
commands.spawn((
Expand Down Expand Up @@ -212,6 +233,7 @@ impl SpecializedMeshPipeline for CustomMeshPipeline {
vertex_attributes.push(Mesh::ATTRIBUTE_POSITION.at_shader_location(0));
}
if layout.0.contains(Mesh::ATTRIBUTE_COLOR) {
shader_defs.push("VERTEX_COLORS".into());
// Make sure this matches the shader location
vertex_attributes.push(Mesh::ATTRIBUTE_COLOR.at_shader_location(1));
}
Expand Down