Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StandardMaterial Light Transmission #8015

Merged
merged 229 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 194 commits
Commits
Show all changes
229 commits
Select commit Hold shift + click to select a range
140f0c4
Expose both main `Texture`s and `TextureView`s in `ViewTarget`.
coreh Mar 8, 2023
d068a57
Introduce `ViewTransmissionTexture`
coreh Mar 8, 2023
52233b3
Expose `ViewTransmissionTexture` in mesh view uniforms
coreh Mar 8, 2023
675913d
Copy main texture to transmission texture before transparent phase
coreh Mar 8, 2023
af53dfe
Add missing `use` items
coreh Mar 8, 2023
3e0ef1a
Add rudimentary light transmission implementation in PBR shader
coreh Mar 8, 2023
b1d4667
Clean up light transmission shader implementation with more proper ma…
coreh Mar 10, 2023
2999947
Move `transmissive_light()` function to `pbr_lighting.wgsl`
coreh Mar 10, 2023
d0265bc
Enable filtering for transmission texture
coreh Mar 10, 2023
714f40a
Use consistent naming to refer to the view transmission texture
coreh Mar 10, 2023
12b845a
Fix comment capitalization
coreh Mar 10, 2023
c0ec1e3
Expose transmission-related properties in `StandardMaterial`
coreh Mar 10, 2023
e040fc8
Make transmitted light blurry when material is rough, using dither + …
coreh Mar 10, 2023
c9db7aa
Unconditionally import tonemapping utils, ensuring dither is present
coreh Mar 10, 2023
27c9285
Add transmission example
coreh Mar 10, 2023
13f59bf
Make number of taps increase faster with perceptual roughness
coreh Mar 10, 2023
24359e6
Tweak initial camera position
coreh Mar 10, 2023
dc0b25d
Remove redundant else branch
coreh Mar 10, 2023
93377bc
Merge branch 'main' into transmission
coreh Mar 25, 2023
4c408d0
Fix deprecation warning
coreh Mar 25, 2023
bb69138
Improve refraction math by propagating refracted ray through world sp…
coreh Mar 27, 2023
7a2752c
Tweak transmissive background blur so that it looks correct with the …
coreh Mar 27, 2023
fb49029
Merge branch 'main' into transmission
coreh Apr 9, 2023
3bc0a01
Split `Transmissive3d` into a separate pass
coreh Apr 10, 2023
41a74c0
Remove redundant clone
coreh Apr 10, 2023
d158e73
Rename `transmissive` to `is_transmissive`
coreh Apr 10, 2023
2458e8f
Add missing example link to examples/README.md
coreh Apr 10, 2023
0a11954
Merge branch 'main' into transmission
coreh Apr 15, 2023
0feafb2
Add `diffuse_transmission` property to `StandardMaterial`
coreh Apr 15, 2023
cfd5859
Allow transmission with `AlphaMode::Opaque` materials
coreh Apr 15, 2023
e2b816b
Add second Lambertian lobe-based diffuse transmission to PBR shader
coreh Apr 16, 2023
927cfa2
Add ability to independently suppress shadows in diffuse transmission…
coreh Apr 16, 2023
cd1976d
Add update example showcasing both diffuse and specular transmission
coreh Apr 16, 2023
fa26e79
Tweak camera height and enable HDR by default
coreh Apr 16, 2023
18bfd50
Make candle light and flame flicker
coreh Apr 16, 2023
0827aa1
Fix lint error
coreh Apr 16, 2023
b7a6ff4
Fix documentation link
coreh Apr 16, 2023
08e7416
Fix additional documentation links
coreh Apr 16, 2023
272b696
Add transmission, thickness and diffuse transmission textures
coreh Apr 16, 2023
1747412
Add ability to load transmission, thickness and ior from glTF
coreh Apr 16, 2023
727a89d
Add support for a configurable number of transmissive steps
coreh Apr 16, 2023
5d7f619
Increase `all_tuples` limit to avoid error in `queue_mesh_view_bind_g…
coreh Apr 16, 2023
13b1e59
Scale thickness with mesh transform (using average of X, Y and Z scales)
coreh Apr 16, 2023
294a677
Introduce `FallbackImageZero`
coreh Apr 16, 2023
5bfe6bb
Fallback to (specular) transmitted environment light when there's no …
coreh Apr 16, 2023
fd65d4b
Make refraction math for environment map more accurate
coreh Apr 16, 2023
e911b58
Update example to showcase transmissive steps option
coreh Apr 16, 2023
2ffc871
Limit transmissive steps to 4, as there are only four transmissive ob…
coreh Apr 16, 2023
545019a
Fix lint error
coreh Apr 16, 2023
0dadf4e
Improve documentation for `Camera3d::transmissive_steps`
coreh Apr 16, 2023
ef04bad
Add documentation aliases
coreh Apr 16, 2023
c38255e
Improve `diffuse_transmission` documentation
coreh Apr 16, 2023
adf2f0f
Merge branch 'main' into transmission
coreh Apr 16, 2023
b1db977
Use depth prepass data to reject values that are in front of the curr…
coreh Apr 19, 2023
3d55cce
Add ability to toggle Depth Prepass to example
coreh Apr 19, 2023
23711c8
Add `attenuation_distance` and `attenuation_color` material attributes
coreh Apr 25, 2023
50b32da
Modify fog functions to take fog as an argument
coreh Apr 25, 2023
580f4af
Reuse fog implementation to implement transmission attenuation
coreh Apr 25, 2023
948bced
Hook up attenuation distance and color to glTF loader
coreh Apr 25, 2023
3862e82
Merge branch 'main' into transmission
coreh Apr 25, 2023
e25b7fe
Update section on texture packing
coreh Apr 25, 2023
95a15d5
Update index of refraction docs
coreh Apr 25, 2023
94e3099
Correctly use `min()` instead of `max()` to avoid 300 texture taps
coreh Apr 25, 2023
a0535de
Use `interleaved_gradient_noise()` instead of `screen_space_dither()`
coreh Apr 25, 2023
8ac3ef1
Clear motion vector to 0.0, fixing artifacts against the background
coreh Apr 26, 2023
d47fe5b
Add one more sample offset
coreh Apr 26, 2023
5f2516d
Add additional quality tweaks to mask the firefly artifacts
coreh Apr 26, 2023
8d39b8a
Enable TAA by default in example
coreh Apr 26, 2023
ae687eb
Mention TAA being tied to Depth Prepass in instructions
coreh Apr 26, 2023
447a0a1
Merge branch 'main' into transmission
coreh May 2, 2023
20b223c
Merge branch 'main' into transmission
coreh May 11, 2023
0d817e0
Add `TAA` shaderdef, don't vary noise with time if TAA is disabled
coreh May 11, 2023
44da726
Allow multiple rotated spiral taps, extract max taps constant
coreh May 11, 2023
0dbec52
Only compute `interleaved_gradient_noise()` once
coreh May 11, 2023
54cfc26
Make number of taps increase faster with blur intensity
coreh May 11, 2023
c81c57c
Make blur 50% less blurry
coreh May 11, 2023
a1e06c7
Move pixel mesh out of loop, don't vary it by frame if TAA is disabled
coreh May 11, 2023
1b33381
Make blur radius scale correctly with distance
coreh May 11, 2023
dfd204a
Tweak color normalization to work properly with new blur intensity ca…
coreh May 11, 2023
9650ee9
Remove note about conditionally disabling normalization with TAA (doe…
coreh May 11, 2023
721ce68
Tweak how fast number of taps grows with blur intensity
coreh May 11, 2023
cd3e7f1
Rename sample offsets to spiral offsets for clarity, use upper case n…
coreh May 11, 2023
da772b8
Make each consecutive spiral smaller
coreh May 11, 2023
cc22775
Reduce MAX_TRANSMISSIVE_TAPS to 16
coreh May 11, 2023
16c3d04
Grow amount of taps slightly faster with intensity
coreh May 11, 2023
0ef74ed
Merge branch 'main' into transmission
coreh May 17, 2023
e2b76ae
Merge branch 'main' into transmission
coreh May 20, 2023
5214260
Merge branch 'main' into transmission
coreh May 28, 2023
0a47196
Hold both `TextureView`s and `Texture`s on `MainTargetTextures`
coreh May 28, 2023
eadb217
Clear motion vector to 0.0, fixing TAA artifacts against the background
coreh May 28, 2023
348e2ce
Expose TAA as a shader def
coreh May 28, 2023
a12419d
Introduce `FallbackImageZero`
coreh May 28, 2023
77b94e4
Add `RenderPhase<I>::render_range()` method
coreh May 28, 2023
a39364f
Take `fog` as an argument instead of relying on `fog` uniform
coreh May 28, 2023
b5ddbd7
Define `E` constant in `bevy_pbr::utils`
coreh May 28, 2023
ac820b4
Allow usage of main textures as copy sources
coreh May 28, 2023
b6e564a
Bump system tuple param limits
coreh May 28, 2023
d17871d
Merge branch 'before-transmission' into transmission
coreh May 28, 2023
cec61c9
Apply PR feedback
coreh May 28, 2023
0aac272
Revert "Bump system tuple param limits"
coreh May 29, 2023
6103ec0
Rename argument to avoid accidental confusion with uniform
coreh May 29, 2023
e61f78d
Use `Option<CachedTexture>` type, making invalid states not represent…
coreh May 29, 2023
2106a53
Do not silently ignore out of bounds ranges
coreh May 29, 2023
d756c0d
Merge branch 'before-transmission' into transmission
coreh May 29, 2023
5affd29
Consolidate *-`Meta` resources in a tuple to avoid deriving `SystemPa…
coreh May 29, 2023
96c36ef
Merge branch 'main' into transmission
coreh Jun 1, 2023
68b0e5d
Merge branch 'main' into transmission
coreh Jun 3, 2023
c15bd4a
Apply PR feedback to documentation
coreh Jun 6, 2023
d95d580
Rename `is_transmissive` to `reads_view_transmission_texture`
coreh Jun 6, 2023
f798c16
Add comments about transmissive steps
coreh Jun 6, 2023
14d4a85
Add note about future heuristics
coreh Jun 6, 2023
6573485
Add shaderdef preventing crash on WebGL for non-transmission examples
coreh Jun 7, 2023
fa57d38
Add capabilities-based depth texture ifdef guards
coreh Jun 19, 2023
5d75225
Gate `StandardMaterial` transmission-related textures behind the `pbr…
coreh Jun 20, 2023
1ebe0f7
Add guards to enable transmission example to run under WebGL
coreh Jun 20, 2023
efc935d
Merge branch 'main' into transmission
coreh Jun 20, 2023
f698949
Only add `NORMAL_PREPASS` key to meshes that participate in prepass
coreh Jun 20, 2023
f221d31
Move transmissive prepass check earlier in queuing function for consi…
coreh Jun 20, 2023
a51352d
Add `pbr_transmission_textures` to cargo features documentation
coreh Jun 20, 2023
716b6ba
Update comment to match new `ambient_light()` occlusion argument type
coreh Jun 20, 2023
c353b41
Merge branch 'main' into transmission
coreh Jul 18, 2023
3e9f74d
Qualify module path of functions and bindings
coreh Jul 18, 2023
d38aec1
Use `.add_plugins()` instead of `.add_plugin()`
coreh Jul 18, 2023
592a6c9
Simplify `PREPASS_DEPTH_SUPPORTED` shader def logic, remove condition…
coreh Jul 18, 2023
a48a313
Add additional module path qualification
coreh Jul 18, 2023
cbafe43
Add note about average being calculated to scale thickness
coreh Jul 18, 2023
3542dc0
Remove redundant `mut`
coreh Jul 18, 2023
eb41464
Merge branch 'main' into transmission
coreh Jul 26, 2023
25147d4
Replace `TAA` shader def with `TEMPORAL_JITTER`
coreh Jul 26, 2023
5e7ae92
Rename `temporal_noise` to `temporal_jitter` for consistency
coreh Jul 26, 2023
4e75436
Also remove/insert `TemporalJitter` when toggling `DepthPrepass`
coreh Jul 26, 2023
9608094
Merge branch 'main' into transmission
coreh Sep 21, 2023
9189f49
Add missing instance index
coreh Sep 21, 2023
420b6d6
Add `Transmissive3d` entities to `prepare_mesh_uniforms()`
coreh Sep 21, 2023
d3d73ec
Fix `TemporalJitter` import
coreh Sep 21, 2023
a5ba675
Mirror loading logic from other textures
coreh Sep 21, 2023
c157a25
Merge branch 'main' into transmission
coreh Sep 24, 2023
4c0b6a1
Make `Transparent3d` phase work again with batching changes
coreh Sep 24, 2023
12c2d43
Improve/fix comments based on PR feedback
coreh Sep 24, 2023
e3487e3
Add missing `min_filter`
coreh Sep 24, 2023
0adc5da
Add a material flag to enable attenuation, removing need for non-port…
coreh Sep 24, 2023
2da4542
Remove mentions of texture packing
coreh Sep 24, 2023
45a37eb
Use `view_z` to scale specular transmission blur
coreh Sep 24, 2023
1edab11
Tweak camera controls, move roughness to `E`/`R`
coreh Sep 24, 2023
f02bba3
Flip horizontal camera controls
coreh Sep 24, 2023
46715e6
Rename `pixel_mesh` to `pixel_checkboard`, improve comments
coreh Sep 24, 2023
20bced8
Use default font in example
coreh Sep 24, 2023
8a17bb7
Make `pbr_transmission_textures` description shorter, update docs
coreh Sep 24, 2023
15ebf76
Add comment on disabled MSAA
coreh Sep 24, 2023
e973e17
Rename `transmission` to `specular_transmission`
coreh Sep 26, 2023
6558dbb
Remove outdated TODO comment
coreh Sep 26, 2023
d4cc7b8
Inline spiral values, use a fixed number of taps for now (for loop un…
coreh Sep 26, 2023
e2b017f
Add `TransmissiveQuality` enum to control number of taps
coreh Sep 26, 2023
0b51e12
Add transmissive quality controls
coreh Sep 26, 2023
f2b34dc
Add missing use statement
coreh Sep 26, 2023
3dfe796
Fix indentation of comments
coreh Sep 26, 2023
1e4e4f7
Add a fast codepath for fetching background with zero roughness
coreh Sep 26, 2023
ca62069
Fix spiral scaling calculation to not leave a hole
coreh Sep 26, 2023
fd58c77
Apply PR feedback to documentation
coreh Oct 8, 2023
3925745
Use full channel names instead o R/G/B/A
coreh Oct 8, 2023
5fe0258
Apply additional feedback on names and comments
coreh Oct 8, 2023
e4d133a
Apply additional renames for consistency
coreh Oct 8, 2023
5c4f00b
Rename the blur taps shader def
coreh Oct 8, 2023
14e3753
Simplify blur taps code to use a nested match expression
coreh Oct 8, 2023
30eec56
Use `SCREEN_SPACE_SPECULAR_TRANSMISSION_*` name (kinda verbose?)
coreh Oct 8, 2023
1d68885
Apply feedback to comments
coreh Oct 8, 2023
94e1557
Update name left behind by previous refactor
coreh Oct 8, 2023
0296023
Additional improvements and PR feedback on comments
coreh Oct 8, 2023
402518f
Improve comment about switch statement
coreh Oct 8, 2023
f8db1a6
Use De Morgan's laws to make `#[cfg()]` more readable
coreh Oct 8, 2023
7231b0c
Apply feedback to demo
coreh Oct 8, 2023
3b6a8ca
Consolidate controls and display in the same UI element
coreh Oct 8, 2023
1099a42
Improve camera initial position, limit distance
coreh Oct 8, 2023
6742c5d
Do not prepare transmission texture if there are not transmissive ite…
coreh Oct 8, 2023
c8b1923
Replace `Option<With<T>>` with `Has<T>`
coreh Oct 8, 2023
32e9a9c
Merge branch 'main' into transmission
coreh Oct 9, 2023
5d317f4
Do not override shadow map size
coreh Oct 9, 2023
8cab969
Use a smaller shadow map resolution
coreh Oct 9, 2023
4a36cb7
Update features documentation
coreh Oct 9, 2023
29691db
Rename more instances of transmission to specular transmission
coreh Oct 9, 2023
21cddc6
Fix shader compilation error when running with `pbr_transmission_text…
coreh Oct 9, 2023
6b76ada
Allow `clippy::type_complexity` in transmission example
coreh Oct 9, 2023
c8e1097
Merge branch 'main' into transmission
coreh Oct 11, 2023
59c9bcd
Merge branch 'main' into transmission
coreh Oct 15, 2023
912defb
Use new `WEBGL2` shader def, remove `PREPASS_DEPTH_SUPPORTED` shader def
coreh Oct 15, 2023
50faf11
Merge branch 'main' into transmission
coreh Oct 18, 2023
d4ad625
Properly pass `reads_view_transmission_texture()` through `ExtendedMa…
coreh Oct 18, 2023
4e4d790
Fix clippy error
coreh Oct 18, 2023
42eaf1b
Fix documentation links
coreh Oct 18, 2023
af291b1
Merge branch 'main' into transmission
coreh Oct 19, 2023
6e6f283
Extract transmission functions to their own file
coreh Oct 19, 2023
dff2f3f
Fix bad merge, replace `frag_coord` with `mesh.position`
coreh Oct 19, 2023
2e226bf
Extract `interleaved_gradient_noise()` to `utils.wgsl`
coreh Oct 19, 2023
27faa49
Extract spiral offsets as constants
coreh Oct 19, 2023
4ed2100
Revert portion of commit that accidentally included TAA PR changes
coreh Oct 20, 2023
b44f2a3
Use `saturate()` instead of `clamp(_, 0.0, 1.0)`
coreh Oct 20, 2023
0a89ee2
Add missing comments about bind group layout entries
coreh Oct 20, 2023
964340c
Take reflectance into account when calculating specular transmission
coreh Oct 21, 2023
7064f98
Add reflectance controls to transmission example
coreh Oct 21, 2023
70cb302
Make comment a little bit more clear/consistent with code
coreh Oct 21, 2023
08acedb
Reorder spiral indexes for better results at lowest quality
coreh Oct 21, 2023
21da603
Merge branch 'main' into transmission
coreh Oct 21, 2023
7832f8e
Cleanup imports to use new Rust-like syntax
coreh Oct 21, 2023
7a273ae
Improve documentation comment based on PR feedback
coreh Oct 21, 2023
bffc330
Use an associated constant to disable automatic batching for `Transmi…
coreh Oct 21, 2023
f3281b3
Account for non-uniform scaling when scaling the thickness
coreh Oct 21, 2023
9f00def
Add separate controls for TAA and Depth Prepass
coreh Oct 21, 2023
9fe2599
Properly reject values in front of fragment in `fetch_transmissive_ba…
coreh Oct 21, 2023
7230601
Add auto camera movement to example
coreh Oct 21, 2023
8ac35c2
Merge branch 'main' into transmission
coreh Oct 25, 2023
553a5cf
Use `OpaqueRendererMethod::Forward` instead of `Auto` when `diffuse_t…
coreh Oct 25, 2023
c669389
Make transmitted shadows opt-in rather than opt-out
coreh Oct 25, 2023
a64be59
Fix the handling of `AlphaMode::Mask(_)` materials with transmission
coreh Oct 25, 2023
4b96679
Remove redundant `#ifndef WEBGL2`s
coreh Oct 28, 2023
dc2f593
Include mention to Bloom in HDR toggle
coreh Oct 28, 2023
3308596
Add `approximate_inverse_tone_mapping()` and use it to improve non-HD…
coreh Oct 28, 2023
fae6dc6
Add explicit mention to HDR being off
coreh Oct 28, 2023
28a9049
Move comment about clear color, rephrase it
coreh Oct 28, 2023
0b5fa68
Fix typo (“to the whatever” -> “to whatever”)
coreh Oct 28, 2023
eeeca2c
Fix markdown heading formatting
coreh Oct 28, 2023
33a672e
Add comment about order of specular transmission and alpha blending
coreh Oct 28, 2023
7a14a28
Merge branch 'main' into transmission
coreh Oct 28, 2023
2c09dc0
Update comment (“Best” -> “Better”)
coreh Oct 28, 2023
52f75f3
Fix spacing
coreh Oct 28, 2023
3908cd6
Remove `continue` to ensure predictable control flow in `for` loop
coreh Oct 29, 2023
ad7a892
Remove `DEPTH_PREPASS` guard from `show_prepass` shader
coreh Oct 29, 2023
98ef3e5
Fix overly dark environment map fallback for transmission with zero s…
coreh Oct 31, 2023
9d50dd1
Fix documentation link lint error
coreh Oct 31, 2023
5dc4387
Merge branch 'main' into transmission
coreh Oct 31, 2023
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
39 changes: 35 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ bevy_asset = ["bevy_internal/bevy_asset"]
bevy_audio = ["bevy_internal/bevy_audio"]

# Provides cameras and other basic render pipeline features
bevy_core_pipeline = ["bevy_internal/bevy_core_pipeline", "bevy_asset", "bevy_render"]
bevy_core_pipeline = [
"bevy_internal/bevy_core_pipeline",
"bevy_asset",
"bevy_render",
]

# Plugin for dynamic loading (using [libloading](https://crates.io/crates/libloading))
bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"]
Expand All @@ -83,7 +87,12 @@ bevy_gilrs = ["bevy_internal/bevy_gilrs"]
bevy_gltf = ["bevy_internal/bevy_gltf", "bevy_asset", "bevy_scene", "bevy_pbr"]

# Adds PBR rendering
bevy_pbr = ["bevy_internal/bevy_pbr", "bevy_asset", "bevy_render", "bevy_core_pipeline"]
bevy_pbr = [
"bevy_internal/bevy_pbr",
"bevy_asset",
"bevy_render",
"bevy_core_pipeline",
]

# Provides rendering functionality
bevy_render = ["bevy_internal/bevy_render"]
Expand All @@ -98,7 +107,12 @@ bevy_sprite = ["bevy_internal/bevy_sprite", "bevy_render", "bevy_core_pipeline"]
bevy_text = ["bevy_internal/bevy_text", "bevy_asset", "bevy_sprite"]

# A custom ECS-driven UI framework
bevy_ui = ["bevy_internal/bevy_ui", "bevy_core_pipeline", "bevy_text", "bevy_sprite"]
bevy_ui = [
"bevy_internal/bevy_ui",
"bevy_core_pipeline",
"bevy_text",
"bevy_sprite",
]

# winit window and input backend
bevy_winit = ["bevy_internal/bevy_winit"]
Expand All @@ -113,7 +127,11 @@ trace_chrome = ["trace", "bevy_internal/trace_chrome"]
trace_tracy = ["trace", "bevy_internal/trace_tracy"]

# Tracing support, with memory profiling, exposing a port for Tracy
trace_tracy_memory = ["trace", "bevy_internal/trace_tracy", "bevy_internal/trace_tracy_memory"]
trace_tracy_memory = [
"trace",
"bevy_internal/trace_tracy",
"bevy_internal/trace_tracy_memory",
]

# Tracing support
trace = ["bevy_internal/trace"]
Expand Down Expand Up @@ -241,6 +259,9 @@ shader_format_glsl = ["bevy_internal/shader_format_glsl"]
# Enable support for shaders in SPIR-V
shader_format_spirv = ["bevy_internal/shader_format_spirv"]

# Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs
pbr_transmission_textures = ["bevy_internal/pbr_transmission_textures"]
coreh marked this conversation as resolved.
Show resolved Hide resolved

# Enable some limitations to be able to use WebGL2. If not enabled, it will default to WebGPU in Wasm. Please refer to the [WebGL2 and WebGPU](https://github.com/bevyengine/bevy/tree/latest/examples#webgl2-and-webgpu) section of the examples README for more information on how to run Wasm builds with WebGPU.
webgl2 = ["bevy_internal/webgl"]

Expand Down Expand Up @@ -778,6 +799,16 @@ description = "Demonstrates transparency in 3d"
category = "3D Rendering"
wasm = true

[[example]]
name = "transmission"
path = "examples/3d/transmission.rs"

[package.metadata.example.transmission]
name = "Transmission"
description = "Showcases light transmission in the PBR material"
category = "3D Rendering"
wasm = true

[[example]]
name = "two_passes"
path = "examples/3d/two_passes.rs"
Expand Down
4 changes: 4 additions & 0 deletions assets/shaders/show_prepass.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ fn fragment(
let sample_index = 0u;
#endif
if settings.show_depth == 1u {
#ifdef WEBGL2
let depth = 0.0;
#else
let depth = bevy_pbr::prepass_utils::prepass_depth(mesh.position, sample_index);
#endif
return vec4(depth, depth, depth, 1.0);
} else if settings.show_normals == 1u {
let normal = bevy_pbr::prepass_utils::prepass_normal(mesh.position, sample_index);
Expand Down
55 changes: 55 additions & 0 deletions crates/bevy_core_pipeline/src/core_3d/camera_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,33 @@ use serde::{Deserialize, Serialize};
#[reflect(Component)]
pub struct Camera3d {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any doc comments for this type that reference transmission, lets link back to the StandardMaterial transmission docs.

Copy link
Contributor Author

@coreh coreh Jun 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tried to, but couldn't figure out how to link to bevy_pbr from bevy_core_pipeline 😕 Is there a way of linking to some crate which we do not depend on?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah didn't think of that, no there's not :/. Best we can do is write out the full type, but not use an actual link.

/// The clear color operation to perform for the main 3d pass.
///
/// **Note:** When [`Camera3d::screen_space_specular_transmission_steps`] > `0`, a fully opaque clear
/// color will “cover” the environment map light's texture, preventing it from
/// being refracted “through” transmissive objects, even if there are no opaque
/// objects behind them. To work around this issue, consider using a clear color
/// with an alpha value of `0.0`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we change the default clear colour, or just use the rgb of the color instead of the rgba? is there any reason to use a clear colour with alpha? if there is a reason, we should mention that here as well.

Copy link
Contributor Author

@coreh coreh Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I don't think we should change the default clear color, as depending on the platform and window settings (and I think by default for canvas on the web), this could result in a semitransparent window which could be surprising/undesirable.

The main reason is only to ensure the environment map can cover portions of the transmitted image that would otherwise be obscured by the clear color. This only really makes sense in test scenes without a skybox or a significant scene that would cover the entire viewport.

If the comment is confusing, I can try to rephrase it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if 0 alpha has bad side effects maybe we shouldn't suggest it. maybe better to suggest a skybox instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit confusing, but I don't feel like we need to block on improving this comment.

Copy link
Contributor Author

@coreh coreh Oct 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this to screen_space_specular_transmission_steps, and entirely rephrased it, so I believe it now makes more sense in context. I also added a note about the potential issues of using transparent clear colors:

/// How many individual steps should be performed in the [`Transmissive3d`](crate::core_3d::Transmissive3d) pass.
///
/// Roughly corresponds to how many “layers of transparency” are rendered for screen space
/// specular transmissive objects. Each step requires making one additional
/// texture copy, so it's recommended to keep this number to a resonably low value. Defaults to `1`.
///
/// ### Notes
///
/// - No copies will be performed if there are no transmissive materials currently being rendered,
///   regardless of this setting.
/// - Setting this to `0` disables the screen-space refraction effect entirely, and falls
///   back to refracting only the environment map light's texture.
/// - If set to more than `0`, any opaque [`clear_color`](Camera3d::clear_color) will obscure the environment
///   map light's texture, preventing it from being visible “through” transmissive materials. If you'd like
///   to still have the environment map show up in your refractions, you can set the clear color's alpha to `0.0`.
///   Keep in mind that depending on the platform and your window settings, this may cause the window to become
///   transparent.
pub screen_space_specular_transmission_steps: usize,

pub clear_color: ClearColorConfig,
/// The depth clear operation to perform for the main 3d pass.
pub depth_load_op: Camera3dDepthLoadOp,
/// The texture usages for the depth texture created for the main 3d pass.
pub depth_texture_usages: Camera3dDepthTextureUsage,
/// How many individual steps should be performed in the [`Transmissive3d`](crate::core_3d::Transmissive3d) pass.
///
/// Roughly corresponds to how many “layers of transparency” are rendered for screen space
/// specular transmissive objects. Each step requires making one additional
/// texture copy, so it's recommended to keep this number to a resonably low value. Defaults to `1`.
///
coreh marked this conversation as resolved.
Show resolved Hide resolved
/// Setting this to `0` disables the screen-space refraction effect entirely, and falls
/// back to refracting only the environment map light's texture.
pub screen_space_specular_transmission_steps: usize,
/// The quality of the screen space specular transmission blur effect, applied to the whatever's “behind” transmissive
cart marked this conversation as resolved.
Show resolved Hide resolved
/// objects when their `roughness` is greater than `0.0`.
///
/// Higher qualities are more GPU-intensive.
///
/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
pub screen_space_specular_transmission_quality: ScreenSpaceTransmissionQuality,
}

impl Default for Camera3d {
Expand All @@ -33,6 +55,8 @@ impl Default for Camera3d {
clear_color: ClearColorConfig::Default,
depth_load_op: Default::default(),
depth_texture_usages: TextureUsages::RENDER_ATTACHMENT.into(),
screen_space_specular_transmission_steps: 1,
screen_space_specular_transmission_quality: Default::default(),
}
}
}
Expand Down Expand Up @@ -77,6 +101,37 @@ impl From<Camera3dDepthLoadOp> for LoadOp<f32> {
}
}

/// The quality of the screen space transmission blur effect, applied to the whatever's “behind” transmissive
cart marked this conversation as resolved.
Show resolved Hide resolved
/// objects when their `roughness` is greater than `0.0`.
///
/// Higher qualities are more GPU-intensive.
///
/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
#[derive(Resource, Default, Clone, Copy, Reflect, PartialEq, PartialOrd, Debug)]
#[reflect(Resource)]
pub enum ScreenSpaceTransmissionQuality {
/// Best performance at the cost of quality. Suitable for lower end GPUs. (e.g. Mobile)
///
/// `num_taps` = 4
Low,

/// A balanced option between quality and performance.
///
/// `num_taps` = 8
#[default]
Medium,

/// Best quality. Suitable for high end GPUs. (e.g. Desktop)
///
/// `num_taps` = 16
High,

/// The highest quality, suitable for non-realtime rendering. (e.g. Pre-rendered cinematics and photo mode)
///
/// `num_taps` = 32
Ultra,
}

#[derive(Bundle)]
pub struct Camera3dBundle {
pub camera: Camera,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use super::{Camera3d, ViewTransmissionTexture};
use crate::core_3d::Transmissive3d;
use bevy_ecs::{prelude::*, query::QueryItem};
use bevy_render::{
camera::ExtractedCamera,
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
render_phase::RenderPhase,
render_resource::{
Extent3d, LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor,
},
renderer::RenderContext,
view::{ViewDepthTexture, ViewTarget},
};
#[cfg(feature = "trace")]
use bevy_utils::tracing::info_span;
use std::ops::Range;

/// A [`bevy_render::render_graph::Node`] that runs the [`Transmissive3d`] [`RenderPhase`].
#[derive(Default)]
pub struct MainTransmissivePass3dNode;

impl ViewNode for MainTransmissivePass3dNode {
type ViewQuery = (
&'static ExtractedCamera,
&'static Camera3d,
&'static RenderPhase<Transmissive3d>,
&'static ViewTarget,
Option<&'static ViewTransmissionTexture>,
&'static ViewDepthTexture,
);

fn run(
&self,
graph: &mut RenderGraphContext,
render_context: &mut RenderContext,
(camera, camera_3d, transmissive_phase, target, transmission, depth): QueryItem<
Self::ViewQuery,
>,
world: &World,
) -> Result<(), NodeRunError> {
let view_entity = graph.view_entity();

let physical_target_size = camera.physical_target_size.unwrap();

let render_pass_descriptor = RenderPassDescriptor {
label: Some("main_transmissive_pass_3d"),
// NOTE: The transmissive pass loads the color buffer as well as overwriting it where appropriate.
color_attachments: &[Some(target.get_color_attachment(Operations {
load: LoadOp::Load,
store: true,
}))],
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
view: &depth.view,
// NOTE: The transmissive main pass loads the depth buffer and possibly overwrites it
depth_ops: Some(Operations {
load: LoadOp::Load,
store: true,
}),
stencil_ops: None,
}),
};

// Run the transmissive pass, sorted back-to-front
// NOTE: Scoped to drop the mutable borrow of render_context
#[cfg(feature = "trace")]
let _main_transmissive_pass_3d_span = info_span!("main_transmissive_pass_3d").entered();

if !transmissive_phase.items.is_empty() {
let screen_space_specular_transmission_steps =
camera_3d.screen_space_specular_transmission_steps;
if screen_space_specular_transmission_steps > 0 {
let transmission =
transmission.expect("`ViewTransmissionTexture` should exist at this point");

// `transmissive_phase.items` are depth sorted, so we split them into N = `screen_space_specular_transmission_steps`
// ranges, rendering them back-to-front in multiple steps, allowing multiple levels of transparency.
//
// Note: For the sake of simplicity, we currently split items evenly among steps. In the future, we
// might want to use a more sophisticated heuristic (e.g. based on view bounds, or with an exponential
// falloff so that nearby objects have more levels of transparency available to them)
for range in split_range(
0..transmissive_phase.items.len(),
screen_space_specular_transmission_steps,
) {
coreh marked this conversation as resolved.
Show resolved Hide resolved
// Copy the main texture to the transmission texture, allowing to use the color output of the
// previous step (or of the `Opaque3d` phase, for the first step) as a transmissive color input
render_context.command_encoder().copy_texture_to_texture(
target.main_texture().as_image_copy(),
transmission.texture.as_image_copy(),
Extent3d {
width: physical_target_size.x,
height: physical_target_size.y,
depth_or_array_layers: 1,
},
);

let mut render_pass =
render_context.begin_tracked_render_pass(render_pass_descriptor.clone());

if let Some(viewport) = camera.viewport.as_ref() {
render_pass.set_camera_viewport(viewport);
}

// render items in range
transmissive_phase.render_range(&mut render_pass, world, view_entity, range);
}
} else {
let mut render_pass =
render_context.begin_tracked_render_pass(render_pass_descriptor);

if let Some(viewport) = camera.viewport.as_ref() {
render_pass.set_camera_viewport(viewport);
}

transmissive_phase.render(&mut render_pass, world, view_entity);
}
}

Ok(())
}
}

/// Splits a [`Range`] into at most `max_num_splits` sub-ranges without overlaps
///
/// Properly takes into account remainders of inexact divisions (by adding extra
/// elements to the initial sub-ranges as needed)
fn split_range(range: Range<usize>, max_num_splits: usize) -> impl Iterator<Item = Range<usize>> {
let len = range.end - range.start;
assert!(len > 0, "to be split, a range must not be empty");
assert!(max_num_splits > 0, "max_num_splits must be at least 1");
let num_splits = max_num_splits.min(len);
let step = len / num_splits;
let mut rem = len % num_splits;
let mut start = range.start;

(0..num_splits).map(move |_| {
let extra = if rem > 0 {
rem -= 1;
1
} else {
0
};
let end = (start + step + extra).min(range.end);
let result = start..end;
start = end;
result
})
}
Loading
Loading