Skip to content

Commit 4ecbe00

Browse files
Add a custom render phase example (#16916)
# Objective - It's currently very hard for beginners and advanced users to get a full understanding of a complete render phase. ## Solution - Implement a full custom render phase - The render phase in the example is intended to show a custom stencil phase that renders the stencil in red directly on the screen --- ## Showcase <img width="1277" alt="image" src="https://github.com/user-attachments/assets/e9dc0105-4fb6-463f-ad53-0529b575fd28" /> ## Notes More docs to explain what is going on is still needed but the example works and can already help some people. We might want to consider using a batched phase and cold specialization in the future, but the example is already complex enough as it is. --------- Co-authored-by: Christopher Biscardi <[email protected]>
1 parent 8e84b46 commit 4ecbe00

File tree

4 files changed

+684
-0
lines changed

4 files changed

+684
-0
lines changed

Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ http-body-util = "0.1"
518518
anyhow = "1"
519519
macro_rules_attribute = "0.2"
520520
accesskit = "0.17"
521+
nonmax = "0.5"
521522

522523
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
523524
smol = "2"
@@ -2728,6 +2729,18 @@ description = "A shader that renders a mesh multiple times in one draw call usin
27282729
category = "Shaders"
27292730
wasm = true
27302731

2732+
[[example]]
2733+
name = "custom_render_phase"
2734+
path = "examples/shader/custom_render_phase.rs"
2735+
doc-scrape-examples = true
2736+
2737+
[package.metadata.example.custom_render_phase]
2738+
name = "Custom Render Phase"
2739+
description = "Shows how to make a complete render phase"
2740+
category = "Shaders"
2741+
wasm = true
2742+
2743+
27312744
[[example]]
27322745
name = "automatic_instancing"
27332746
path = "examples/shader/automatic_instancing.rs"

assets/shaders/custom_stencil.wgsl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//! A shader showing how to use the vertex position data to output the
2+
//! stencil in the right position
3+
4+
// First we import everything we need from bevy_pbr
5+
// A 2d shader would be vevry similar but import from bevy_sprite instead
6+
#import bevy_pbr::{
7+
mesh_functions,
8+
view_transformations::position_world_to_clip
9+
}
10+
11+
struct Vertex {
12+
// This is needed if you are using batching and/or gpu preprocessing
13+
// It's a built in so you don't need to define it in the vertex layout
14+
@builtin(instance_index) instance_index: u32,
15+
// Like we defined for the vertex layout
16+
// position is at location 0
17+
@location(0) position: vec3<f32>,
18+
};
19+
20+
// This is the output of the vertex shader and we also use it as the input for the fragment shader
21+
struct VertexOutput {
22+
@builtin(position) clip_position: vec4<f32>,
23+
@location(0) world_position: vec4<f32>,
24+
};
25+
26+
@vertex
27+
fn vertex(vertex: Vertex) -> VertexOutput {
28+
var out: VertexOutput;
29+
// This is how bevy computes the world position
30+
// The vertex.instance_index is very important. Especially if you are using batching and gpu preprocessing
31+
var world_from_local = mesh_functions::get_world_from_local(vertex.instance_index);
32+
out.world_position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4(vertex.position, 1.0));
33+
out.clip_position = position_world_to_clip(out.world_position.xyz);
34+
return out;
35+
}
36+
37+
@fragment
38+
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
39+
// Output a red color to represent the stencil of the mesh
40+
return vec4(1.0, 0.0, 0.0, 1.0);
41+
}

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ Example | Description
434434
[Animated](../examples/shader/animate_shader.rs) | A shader that uses dynamic data like the time since startup
435435
[Array Texture](../examples/shader/array_texture.rs) | A shader that shows how to reuse the core bevy PBR shading functionality in a custom material that obtains the base color from an array texture.
436436
[Compute - Game of Life](../examples/shader/compute_shader_game_of_life.rs) | A compute shader that simulates Conway's Game of Life
437+
[Custom Render Phase](../examples/shader/custom_render_phase.rs) | Shows how to make a complete render phase
437438
[Custom Vertex Attribute](../examples/shader/custom_vertex_attribute.rs) | A shader that reads a mesh's custom vertex attribute
438439
[Custom phase item](../examples/shader/custom_phase_item.rs) | Demonstrates how to enqueue custom draw commands in a render phase
439440
[Extended Material](../examples/shader/extended_material.rs) | A custom shader that builds on the standard material

0 commit comments

Comments
 (0)