Address feedback naming
This commit is contained in:
parent
4f28f38f14
commit
937c738591
@ -197,22 +197,6 @@ impl Image {
|
||||
})
|
||||
.map(DynamicImage::ImageRgba8)
|
||||
}
|
||||
TextureFormat::Rgba16Float => {
|
||||
use half::f16;
|
||||
let pixel_count = (width * height) as usize;
|
||||
let mut rgba32f_data = Vec::<f32>::with_capacity(pixel_count * 4);
|
||||
for rgba16f in data.chunks_exact(8) {
|
||||
let r = f16::from_bits(u16::from_le_bytes([rgba16f[0], rgba16f[1]])).to_f32();
|
||||
let g = f16::from_bits(u16::from_le_bytes([rgba16f[2], rgba16f[3]])).to_f32();
|
||||
let b = f16::from_bits(u16::from_le_bytes([rgba16f[4], rgba16f[5]])).to_f32();
|
||||
let a = f16::from_bits(u16::from_le_bytes([rgba16f[6], rgba16f[7]])).to_f32();
|
||||
rgba32f_data.push(r);
|
||||
rgba32f_data.push(g);
|
||||
rgba32f_data.push(b);
|
||||
rgba32f_data.push(a);
|
||||
}
|
||||
ImageBuffer::from_raw(width, height, rgba32f_data).map(DynamicImage::ImageRgba32F)
|
||||
}
|
||||
// Throw and error if conversion isn't supported
|
||||
texture_format => return Err(IntoDynamicImageError::UnsupportedFormat(texture_format)),
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -45,7 +45,6 @@ use bevy_ecs::{
|
||||
schedule::IntoScheduleConfigs,
|
||||
system::{lifetimeless::Read, Query},
|
||||
};
|
||||
use bevy_image::Image;
|
||||
use bevy_math::{UVec2, UVec3, Vec3};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||
use bevy_render::{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#import bevy_render::maths::{PI, PI_2};
|
||||
#import bevy_pbr::lighting::perceptualRoughnessToRoughness;
|
||||
|
||||
struct PrefilterConstants {
|
||||
struct FilteringConstants {
|
||||
mip_level: f32,
|
||||
sample_count: u32,
|
||||
roughness: f32,
|
||||
@ -11,7 +11,7 @@ struct PrefilterConstants {
|
||||
@group(0) @binding(0) var input_texture: texture_2d_array<f32>;
|
||||
@group(0) @binding(1) var input_sampler: sampler;
|
||||
@group(0) @binding(2) var output_texture: texture_storage_2d_array<rgba16float, write>;
|
||||
@group(0) @binding(3) var<uniform> constants: PrefilterConstants;
|
||||
@group(0) @binding(3) var<uniform> constants: FilteringConstants;
|
||||
@group(0) @binding(4) var blue_noise_texture: texture_2d<f32>;
|
||||
|
||||
// Tonemapping functions to reduce fireflies
|
||||
@ -196,11 +196,12 @@ fn hammersley_2d(i: u32, n: u32) -> vec2f {
|
||||
}
|
||||
|
||||
// Blue noise randomization
|
||||
fn blue_noise_offset(pixel_coords: vec2u) -> vec2f {
|
||||
fn sample_noise(pixel_coords: vec2u) -> vec4f {
|
||||
// Get a stable random offset for this pixel
|
||||
let noise_size = vec2u(u32(constants.blue_noise_size.x), u32(constants.blue_noise_size.y));
|
||||
let noise_coords = pixel_coords % noise_size;
|
||||
return textureSampleLevel(blue_noise_texture, input_sampler, vec2f(noise_coords) / constants.blue_noise_size, 0.0).rg;
|
||||
let uv = vec2f(noise_coords) / constants.blue_noise_size;
|
||||
return textureSampleLevel(blue_noise_texture, input_sampler, uv, 0.0);
|
||||
}
|
||||
|
||||
// GGX/Trowbridge-Reitz normal distribution function (D term)
|
||||
@ -279,7 +280,7 @@ fn generate_radiance_map(@builtin(global_invocation_id) global_id: vec3u) {
|
||||
let roughness = constants.roughness;
|
||||
|
||||
// Get blue noise offset for stratification
|
||||
let blue_noise = blue_noise_offset(coords);
|
||||
let vector_noise = sample_noise(coords);
|
||||
|
||||
var radiance = vec3f(0.0);
|
||||
var total_weight = 0.0;
|
||||
@ -297,7 +298,7 @@ fn generate_radiance_map(@builtin(global_invocation_id) global_id: vec3u) {
|
||||
for (var i = 0u; i < sample_count; i++) {
|
||||
// Get sample coordinates from Hammersley sequence with blue noise offset
|
||||
var xi = hammersley_2d(i, sample_count);
|
||||
xi = fract(xi + blue_noise); // Apply Cranley-Patterson rotation
|
||||
xi = fract(xi + vector_noise.rg); // Apply Cranley-Patterson rotation
|
||||
|
||||
// Sample the GGX distribution to get a half vector
|
||||
let half_vector = importance_sample_ggx(xi, roughness, normal);
|
||||
@ -370,9 +371,6 @@ fn generate_irradiance_map(@builtin(global_invocation_id) global_id: vec3u) {
|
||||
// Create tangent space matrix
|
||||
let tangent_frame = calculate_tangent_frame(normal);
|
||||
|
||||
// Get blue noise offset for stratification
|
||||
let blue_noise = blue_noise_offset(coords);
|
||||
|
||||
var irradiance = vec3f(0.0);
|
||||
var total_weight = 0.0;
|
||||
|
||||
@ -419,9 +417,6 @@ fn generate_irradiance_map(@builtin(global_invocation_id) global_id: vec3u) {
|
||||
irradiance = irradiance / total_weight * PI;
|
||||
}
|
||||
|
||||
// Add some low-frequency ambient term to avoid completely dark areas
|
||||
irradiance = max(irradiance, vec3f(0.01, 0.01, 0.01));
|
||||
|
||||
// Write result to output texture
|
||||
textureStore(output_texture, coords, face, vec4f(irradiance, 1.0));
|
||||
}
|
||||
|
||||
@ -30,33 +30,36 @@ use bevy_render::{
|
||||
Extract,
|
||||
};
|
||||
|
||||
use crate::atmosphere;
|
||||
use crate::light_probe::environment_map::EnvironmentMapLight;
|
||||
|
||||
/// A handle to the SPD (Single Pass Downsampling) shader.
|
||||
/// Single Pass Downsampling (SPD) shader handle
|
||||
pub const SPD_SHADER_HANDLE: Handle<Shader> = weak_handle!("5dcf400c-bcb3-49b9-8b7e-80f4117eaf82");
|
||||
|
||||
/// A handle to the environment filter shader.
|
||||
/// Environment Filter shader handle
|
||||
pub const ENVIRONMENT_FILTER_SHADER_HANDLE: Handle<Shader> =
|
||||
weak_handle!("3110b545-78e0-48fc-b86e-8bc0ea50fc67");
|
||||
|
||||
/// Labels for the prefiltering nodes
|
||||
/// Sphere Cosine Weighted Irradiance shader handle
|
||||
pub const STBN_SPHERE: Handle<Image> = weak_handle!("3110b545-78e0-48fc-b86e-8bc0ea50fc67");
|
||||
pub const STBN_VEC2: Handle<Image> = weak_handle!("3110b545-78e0-48fc-b86e-8bc0ea50fc67");
|
||||
|
||||
/// Labels for the environment map generation nodes
|
||||
#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash, RenderLabel)]
|
||||
pub enum PrefilterNode {
|
||||
GenerateMipmap,
|
||||
RadianceMap,
|
||||
IrradianceMap,
|
||||
pub enum GeneratorNode {
|
||||
Mipmap,
|
||||
Radiance,
|
||||
Irradiance,
|
||||
}
|
||||
|
||||
/// Stores the bind group layouts for the prefiltering process
|
||||
/// Stores the bind group layouts for the environment map generation pipelines
|
||||
#[derive(Resource)]
|
||||
pub struct PrefilterBindGroupLayouts {
|
||||
pub struct GeneratorBindGroupLayouts {
|
||||
pub spd: BindGroupLayout,
|
||||
pub radiance: BindGroupLayout,
|
||||
pub irradiance: BindGroupLayout,
|
||||
}
|
||||
|
||||
impl FromWorld for PrefilterBindGroupLayouts {
|
||||
impl FromWorld for GeneratorBindGroupLayouts {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
|
||||
@ -178,7 +181,7 @@ impl FromWorld for PrefilterBindGroupLayouts {
|
||||
StorageTextureAccess::WriteOnly,
|
||||
),
|
||||
), // Output specular map
|
||||
(3, uniform_buffer::<PrefilterConstants>(false)), // Uniforms
|
||||
(3, uniform_buffer::<FilteringConstants>(false)), // Uniforms
|
||||
(4, texture_2d(TextureSampleType::Float { filterable: true })), // Blue noise texture
|
||||
),
|
||||
),
|
||||
@ -202,7 +205,7 @@ impl FromWorld for PrefilterBindGroupLayouts {
|
||||
StorageTextureAccess::WriteOnly,
|
||||
),
|
||||
), // Output irradiance map
|
||||
(3, uniform_buffer::<PrefilterConstants>(false)), // Uniforms
|
||||
(3, uniform_buffer::<FilteringConstants>(false)), // Uniforms
|
||||
(4, texture_2d(TextureSampleType::Float { filterable: true })), // Blue noise texture
|
||||
),
|
||||
),
|
||||
@ -216,18 +219,18 @@ impl FromWorld for PrefilterBindGroupLayouts {
|
||||
}
|
||||
}
|
||||
|
||||
/// Samplers for the prefiltering process
|
||||
/// Samplers for the environment map generation pipelines
|
||||
#[derive(Resource)]
|
||||
pub struct PrefilterSamplers {
|
||||
pub struct GeneratorSamplers {
|
||||
pub linear: Sampler,
|
||||
}
|
||||
|
||||
impl FromWorld for PrefilterSamplers {
|
||||
impl FromWorld for GeneratorSamplers {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
|
||||
let linear = render_device.create_sampler(&SamplerDescriptor {
|
||||
label: Some("prefilter_linear_sampler"),
|
||||
label: Some("generator_linear_sampler"),
|
||||
address_mode_u: AddressMode::ClampToEdge,
|
||||
address_mode_v: AddressMode::ClampToEdge,
|
||||
address_mode_w: AddressMode::ClampToEdge,
|
||||
@ -241,19 +244,19 @@ impl FromWorld for PrefilterSamplers {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pipelines for the prefiltering process
|
||||
/// Pipelines for the environment map generation pipelines
|
||||
#[derive(Resource)]
|
||||
pub struct PrefilterPipelines {
|
||||
pub struct GeneratorPipelines {
|
||||
pub spd_first: CachedComputePipelineId,
|
||||
pub spd_second: CachedComputePipelineId,
|
||||
pub radiance: CachedComputePipelineId,
|
||||
pub irradiance: CachedComputePipelineId,
|
||||
}
|
||||
|
||||
impl FromWorld for PrefilterPipelines {
|
||||
impl FromWorld for GeneratorPipelines {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let pipeline_cache = world.resource::<PipelineCache>();
|
||||
let layouts = world.resource::<PrefilterBindGroupLayouts>();
|
||||
let layouts = world.resource::<GeneratorBindGroupLayouts>();
|
||||
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
let features = render_device.features();
|
||||
@ -317,16 +320,16 @@ impl FromWorld for PrefilterPipelines {
|
||||
}
|
||||
|
||||
#[derive(Component, Clone, Reflect, ExtractComponent)]
|
||||
pub struct FilteredEnvironmentMapLight {
|
||||
pub struct GeneratedEnvironmentMapLight {
|
||||
pub environment_map: Handle<Image>,
|
||||
pub intensity: f32,
|
||||
pub rotation: Quat,
|
||||
pub affects_lightmapped_mesh_diffuse: bool,
|
||||
}
|
||||
|
||||
impl Default for FilteredEnvironmentMapLight {
|
||||
impl Default for GeneratedEnvironmentMapLight {
|
||||
fn default() -> Self {
|
||||
FilteredEnvironmentMapLight {
|
||||
GeneratedEnvironmentMapLight {
|
||||
environment_map: Handle::default(),
|
||||
intensity: 0.0,
|
||||
rotation: Quat::IDENTITY,
|
||||
@ -335,18 +338,18 @@ impl Default for FilteredEnvironmentMapLight {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_prefilter_entities(
|
||||
prefilter_query: Extract<
|
||||
pub fn extract_generator_entities(
|
||||
query: Extract<
|
||||
Query<(
|
||||
RenderEntity,
|
||||
&FilteredEnvironmentMapLight,
|
||||
&GeneratedEnvironmentMapLight,
|
||||
&EnvironmentMapLight,
|
||||
)>,
|
||||
>,
|
||||
mut commands: Commands,
|
||||
render_images: Res<RenderAssets<GpuImage>>,
|
||||
) {
|
||||
for (entity, filtered_env_map, env_map_light) in prefilter_query.iter() {
|
||||
for (entity, filtered_env_map, env_map_light) in query.iter() {
|
||||
let env_map = render_images
|
||||
.get(&filtered_env_map.environment_map)
|
||||
.expect("Environment map not found");
|
||||
@ -389,12 +392,12 @@ pub struct RenderEnvironmentMap {
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct PrefilterTextures {
|
||||
pub struct IntermediateTextures {
|
||||
pub environment_map: CachedTexture,
|
||||
}
|
||||
|
||||
/// Prepares textures needed for prefiltering
|
||||
pub fn prepare_prefilter_textures(
|
||||
/// Prepares textures needed for single pass downsampling
|
||||
pub fn prepare_intermediate_textures(
|
||||
light_probes: Query<Entity, With<RenderEnvironmentMap>>,
|
||||
render_device: Res<RenderDevice>,
|
||||
mut texture_cache: ResMut<TextureCache>,
|
||||
@ -405,7 +408,7 @@ pub fn prepare_prefilter_textures(
|
||||
let environment_map = texture_cache.get(
|
||||
&render_device,
|
||||
TextureDescriptor {
|
||||
label: Some("prefilter_environment_map"),
|
||||
label: Some("intermediate_environment_map"),
|
||||
size: Extent3d {
|
||||
width: 512,
|
||||
height: 512,
|
||||
@ -424,7 +427,7 @@ pub fn prepare_prefilter_textures(
|
||||
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(PrefilterTextures { environment_map });
|
||||
.insert(IntermediateTextures { environment_map });
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,41 +440,45 @@ pub struct SpdConstants {
|
||||
_padding: u32,
|
||||
}
|
||||
|
||||
/// Constants for prefiltering
|
||||
/// Constants for filtering
|
||||
#[derive(Clone, Copy, ShaderType)]
|
||||
#[repr(C)]
|
||||
pub struct PrefilterConstants {
|
||||
pub struct FilteringConstants {
|
||||
mip_level: f32,
|
||||
sample_count: u32,
|
||||
roughness: f32,
|
||||
blue_noise_size: Vec2,
|
||||
}
|
||||
|
||||
/// Stores bind groups for the prefiltering process
|
||||
/// Stores bind groups for the environment map generation pipelines
|
||||
#[derive(Component)]
|
||||
pub struct PrefilterBindGroups {
|
||||
pub struct GeneratorBindGroups {
|
||||
pub spd: BindGroup,
|
||||
pub radiance: Vec<BindGroup>, // One per mip level
|
||||
pub irradiance: BindGroup,
|
||||
}
|
||||
|
||||
/// Prepares bind groups for prefiltering
|
||||
pub fn prepare_prefilter_bind_groups(
|
||||
/// Prepares bind groups for environment map generation pipelines
|
||||
pub fn prepare_generator_bind_groups(
|
||||
light_probes: Query<
|
||||
(Entity, &PrefilterTextures, &RenderEnvironmentMap),
|
||||
(Entity, &IntermediateTextures, &RenderEnvironmentMap),
|
||||
With<RenderEnvironmentMap>,
|
||||
>,
|
||||
render_device: Res<RenderDevice>,
|
||||
queue: Res<RenderQueue>,
|
||||
layouts: Res<PrefilterBindGroupLayouts>,
|
||||
samplers: Res<PrefilterSamplers>,
|
||||
layouts: Res<GeneratorBindGroupLayouts>,
|
||||
samplers: Res<GeneratorSamplers>,
|
||||
render_images: Res<RenderAssets<GpuImage>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
// Get blue noise texture
|
||||
let blue_noise_texture = render_images
|
||||
.get(&atmosphere::shaders::BLUENOISE_TEXTURE)
|
||||
.expect("Blue noise texture not loaded");
|
||||
let sphere_cosine_weights = render_images
|
||||
.get(&STBN_SPHERE)
|
||||
.expect("Sphere cosine weights texture not loaded");
|
||||
|
||||
let vector2_uniform = render_images
|
||||
.get(&STBN_VEC2)
|
||||
.expect("Vector2 uniform texture not loaded");
|
||||
|
||||
for (entity, textures, env_map_light) in &light_probes {
|
||||
// Create SPD bind group
|
||||
@ -571,13 +578,13 @@ pub fn prepare_prefilter_bind_groups(
|
||||
128
|
||||
};
|
||||
|
||||
let radiance_constants = PrefilterConstants {
|
||||
let radiance_constants = FilteringConstants {
|
||||
mip_level: mip as f32,
|
||||
sample_count,
|
||||
roughness,
|
||||
blue_noise_size: Vec2::new(
|
||||
blue_noise_texture.size.width as f32,
|
||||
blue_noise_texture.size.height as f32,
|
||||
vector2_uniform.size.width as f32,
|
||||
vector2_uniform.size.height as f32,
|
||||
),
|
||||
};
|
||||
|
||||
@ -597,7 +604,7 @@ pub fn prepare_prefilter_bind_groups(
|
||||
(1, &samplers.linear),
|
||||
(2, &mip_storage_view),
|
||||
(3, &radiance_constants_buffer),
|
||||
(4, &blue_noise_texture.texture_view),
|
||||
(4, &vector2_uniform.texture_view),
|
||||
)),
|
||||
);
|
||||
|
||||
@ -605,13 +612,13 @@ pub fn prepare_prefilter_bind_groups(
|
||||
}
|
||||
|
||||
// Create irradiance bind group
|
||||
let irradiance_constants = PrefilterConstants {
|
||||
let irradiance_constants = FilteringConstants {
|
||||
mip_level: 0.0,
|
||||
sample_count: 64,
|
||||
roughness: 1.0,
|
||||
blue_noise_size: Vec2::new(
|
||||
blue_noise_texture.size.width as f32,
|
||||
blue_noise_texture.size.height as f32,
|
||||
sphere_cosine_weights.size.width as f32,
|
||||
sphere_cosine_weights.size.height as f32,
|
||||
),
|
||||
};
|
||||
|
||||
@ -636,11 +643,11 @@ pub fn prepare_prefilter_bind_groups(
|
||||
(1, &samplers.linear),
|
||||
(2, &irradiance_map),
|
||||
(3, &irradiance_constants_buffer),
|
||||
(4, &blue_noise_texture.texture_view),
|
||||
(4, &sphere_cosine_weights.texture_view),
|
||||
)),
|
||||
);
|
||||
|
||||
commands.entity(entity).insert(PrefilterBindGroups {
|
||||
commands.entity(entity).insert(GeneratorBindGroups {
|
||||
spd: spd_bind_group,
|
||||
radiance: radiance_bind_groups,
|
||||
irradiance: irradiance_bind_group,
|
||||
@ -667,7 +674,7 @@ fn create_storage_view(texture: &Texture, mip: u32, _render_device: &RenderDevic
|
||||
pub struct SpdNode {
|
||||
query: QueryState<(
|
||||
Entity,
|
||||
Read<PrefilterBindGroups>,
|
||||
Read<GeneratorBindGroups>,
|
||||
Read<RenderEnvironmentMap>,
|
||||
)>,
|
||||
}
|
||||
@ -692,7 +699,7 @@ impl Node for SpdNode {
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
let pipeline_cache = world.resource::<PipelineCache>();
|
||||
let pipelines = world.resource::<PrefilterPipelines>();
|
||||
let pipelines = world.resource::<GeneratorPipelines>();
|
||||
|
||||
// First pass (mips 0-5)
|
||||
let Some(spd_first_pipeline) = pipeline_cache.get_compute_pipeline(pipelines.spd_first)
|
||||
@ -708,7 +715,7 @@ impl Node for SpdNode {
|
||||
|
||||
for (entity, bind_groups, env_map_light) in self.query.iter_manual(world) {
|
||||
// Copy original environment map to mip 0 of the intermediate environment map
|
||||
let textures = world.get::<PrefilterTextures>(entity).unwrap();
|
||||
let textures = world.get::<IntermediateTextures>(entity).unwrap();
|
||||
|
||||
render_context.command_encoder().copy_texture_to_texture(
|
||||
env_map_light.environment_map.texture.as_image_copy(),
|
||||
@ -764,7 +771,7 @@ impl Node for SpdNode {
|
||||
|
||||
/// Radiance map node for generating specular environment maps
|
||||
pub struct RadianceMapNode {
|
||||
query: QueryState<(Entity, Read<PrefilterBindGroups>)>,
|
||||
query: QueryState<(Entity, Read<GeneratorBindGroups>)>,
|
||||
}
|
||||
|
||||
impl FromWorld for RadianceMapNode {
|
||||
@ -787,7 +794,7 @@ impl Node for RadianceMapNode {
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
let pipeline_cache = world.resource::<PipelineCache>();
|
||||
let pipelines = world.resource::<PrefilterPipelines>();
|
||||
let pipelines = world.resource::<GeneratorPipelines>();
|
||||
|
||||
let Some(radiance_pipeline) = pipeline_cache.get_compute_pipeline(pipelines.radiance)
|
||||
else {
|
||||
@ -824,7 +831,7 @@ impl Node for RadianceMapNode {
|
||||
|
||||
/// Irradiance Convolution Node
|
||||
pub struct IrradianceMapNode {
|
||||
query: QueryState<(Entity, Read<PrefilterBindGroups>)>,
|
||||
query: QueryState<(Entity, Read<GeneratorBindGroups>)>,
|
||||
}
|
||||
|
||||
impl FromWorld for IrradianceMapNode {
|
||||
@ -847,7 +854,7 @@ impl Node for IrradianceMapNode {
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
let pipeline_cache = world.resource::<PipelineCache>();
|
||||
let pipelines = world.resource::<PrefilterPipelines>();
|
||||
let pipelines = world.resource::<GeneratorPipelines>();
|
||||
|
||||
let Some(irradiance_pipeline) = pipeline_cache.get_compute_pipeline(pipelines.irradiance)
|
||||
else {
|
||||
@ -874,11 +881,11 @@ impl Node for IrradianceMapNode {
|
||||
}
|
||||
}
|
||||
|
||||
/// System that creates an `EnvironmentMapLight` component from the prefiltered textures
|
||||
pub fn create_environment_map_from_prefilter(
|
||||
/// System that generates an `EnvironmentMapLight` component based on the `GeneratedEnvironmentMapLight` component
|
||||
pub fn generate_environment_map_light(
|
||||
mut commands: Commands,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
query: Query<(Entity, &FilteredEnvironmentMapLight), Without<EnvironmentMapLight>>,
|
||||
query: Query<(Entity, &GeneratedEnvironmentMapLight), Without<EnvironmentMapLight>>,
|
||||
) {
|
||||
for (entity, filtered_env_map) in &query {
|
||||
// Create a placeholder for the irradiance map
|
||||
@ -126,7 +126,7 @@
|
||||
//!
|
||||
//! [Blender]: http://blender.org/
|
||||
//!
|
||||
//! [baking tool]: https://docs.blender.org/manual/en/latest/render/eevee/render_settings/indirect_lighting.html
|
||||
//! [baking tool]: https://docs.blender.org/manual/en/latest/render/eevee/light_probes/volume.html
|
||||
//!
|
||||
//! [`bevy-baked-gi`]: https://github.com/pcwalton/bevy-baked-gi
|
||||
//!
|
||||
|
||||
@ -31,10 +31,10 @@ use bevy_render::{
|
||||
Extract, ExtractSchedule, Render, RenderApp, RenderSystems,
|
||||
};
|
||||
use bevy_transform::{components::Transform, prelude::GlobalTransform};
|
||||
use prefilter::{
|
||||
create_environment_map_from_prefilter, extract_prefilter_entities,
|
||||
prepare_prefilter_bind_groups, prepare_prefilter_textures, FilteredEnvironmentMapLight,
|
||||
PrefilterPipelines, SpdNode,
|
||||
use generate::{
|
||||
extract_generator_entities, generate_environment_map_light, prepare_generator_bind_groups,
|
||||
prepare_intermediate_textures, GeneratedEnvironmentMapLight, GeneratorPipelines, SpdNode,
|
||||
STBN_SPHERE, STBN_VEC2,
|
||||
};
|
||||
use tracing::error;
|
||||
|
||||
@ -45,8 +45,8 @@ use crate::light_probe::environment_map::{EnvironmentMapIds, EnvironmentMapLight
|
||||
use self::irradiance_volume::IrradianceVolume;
|
||||
|
||||
pub mod environment_map;
|
||||
pub mod generate;
|
||||
pub mod irradiance_volume;
|
||||
pub mod prefilter;
|
||||
|
||||
/// The maximum number of each type of light probe that each view will consider.
|
||||
///
|
||||
@ -350,8 +350,8 @@ impl Plugin for LightProbePlugin {
|
||||
app.register_type::<LightProbe>()
|
||||
.register_type::<EnvironmentMapLight>()
|
||||
.register_type::<IrradianceVolume>()
|
||||
.add_plugins(ExtractComponentPlugin::<FilteredEnvironmentMapLight>::default())
|
||||
.add_systems(Update, create_environment_map_from_prefilter);
|
||||
.add_plugins(ExtractComponentPlugin::<GeneratedEnvironmentMapLight>::default())
|
||||
.add_systems(Update, generate_environment_map_light);
|
||||
}
|
||||
|
||||
fn finish(&self, app: &mut App) {
|
||||
@ -363,19 +363,19 @@ impl Plugin for LightProbePlugin {
|
||||
.add_plugins(ExtractInstancesPlugin::<EnvironmentMapIds>::new())
|
||||
.init_resource::<LightProbesBuffer>()
|
||||
.init_resource::<EnvironmentMapUniformBuffer>()
|
||||
.init_resource::<PrefilterBindGroupLayouts>()
|
||||
.init_resource::<PrefilterSamplers>()
|
||||
.init_resource::<PrefilterPipelines>()
|
||||
.add_render_graph_node::<SpdNode>(Core3d, PrefilterNode::GenerateMipmap)
|
||||
.add_render_graph_node::<RadianceMapNode>(Core3d, PrefilterNode::RadianceMap)
|
||||
.add_render_graph_node::<IrradianceMapNode>(Core3d, PrefilterNode::IrradianceMap)
|
||||
.init_resource::<GeneratorBindGroupLayouts>()
|
||||
.init_resource::<GeneratorSamplers>()
|
||||
.init_resource::<GeneratorPipelines>()
|
||||
.add_render_graph_node::<SpdNode>(Core3d, GeneratorNode::Mipmap)
|
||||
.add_render_graph_node::<RadianceMapNode>(Core3d, GeneratorNode::Radiance)
|
||||
.add_render_graph_node::<IrradianceMapNode>(Core3d, GeneratorNode::Irradiance)
|
||||
.add_render_graph_edges(
|
||||
Core3d,
|
||||
(
|
||||
Node3d::EndPrepasses,
|
||||
PrefilterNode::GenerateMipmap,
|
||||
PrefilterNode::RadianceMap,
|
||||
PrefilterNode::IrradianceMap,
|
||||
GeneratorNode::Mipmap,
|
||||
GeneratorNode::Radiance,
|
||||
GeneratorNode::Irradiance,
|
||||
Node3d::StartMainPass,
|
||||
),
|
||||
)
|
||||
@ -384,7 +384,7 @@ impl Plugin for LightProbePlugin {
|
||||
.add_systems(ExtractSchedule, gather_light_probes::<IrradianceVolume>)
|
||||
.add_systems(
|
||||
ExtractSchedule,
|
||||
extract_prefilter_entities.after(create_environment_map_from_prefilter),
|
||||
extract_generator_entities.after(generate_environment_map_light),
|
||||
)
|
||||
.add_systems(
|
||||
Render,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
@ -39,8 +39,8 @@ enum ReflectionMode {
|
||||
// Both a world environment map and a reflection probe are present. The
|
||||
// reflection probe is shown in the sphere.
|
||||
ReflectionProbe = 2,
|
||||
// A prefiltered environment map is shown.
|
||||
PrefilteredEnvironmentMap = 3,
|
||||
// A generated environment map is shown.
|
||||
GeneratedEnvironmentMap = 3,
|
||||
}
|
||||
|
||||
// The various reflection maps.
|
||||
@ -133,7 +133,7 @@ fn spawn_sphere(
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("#ffd891").unwrap().into(),
|
||||
base_color: Srgba::hex("#ffffff").unwrap().into(),
|
||||
metallic: 1.0,
|
||||
perceptual_roughness: app_status.sphere_roughness,
|
||||
..StandardMaterial::default()
|
||||
@ -157,10 +157,10 @@ fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) {
|
||||
));
|
||||
}
|
||||
|
||||
fn spawn_prefiltered_environment_map(commands: &mut Commands, cubemaps: &Cubemaps) {
|
||||
fn spawn_generated_environment_map(commands: &mut Commands, cubemaps: &Cubemaps) {
|
||||
commands.spawn((
|
||||
LightProbe,
|
||||
FilteredEnvironmentMapLight {
|
||||
GeneratedEnvironmentMapLight {
|
||||
environment_map: cubemaps.unfiltered_environment_map.clone(),
|
||||
intensity: 5000.0,
|
||||
..default()
|
||||
@ -232,8 +232,8 @@ fn change_reflection_type(
|
||||
match app_status.reflection_mode {
|
||||
ReflectionMode::None | ReflectionMode::EnvironmentMap => {}
|
||||
ReflectionMode::ReflectionProbe => spawn_reflection_probe(&mut commands, &cubemaps),
|
||||
ReflectionMode::PrefilteredEnvironmentMap => {
|
||||
spawn_prefiltered_environment_map(&mut commands, &cubemaps);
|
||||
ReflectionMode::GeneratedEnvironmentMap => {
|
||||
spawn_generated_environment_map(&mut commands, &cubemaps);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,9 +245,9 @@ fn change_reflection_type(
|
||||
}
|
||||
ReflectionMode::EnvironmentMap
|
||||
| ReflectionMode::ReflectionProbe
|
||||
| ReflectionMode::PrefilteredEnvironmentMap => {
|
||||
| ReflectionMode::GeneratedEnvironmentMap => {
|
||||
let image = match app_status.reflection_mode {
|
||||
ReflectionMode::PrefilteredEnvironmentMap => {
|
||||
ReflectionMode::GeneratedEnvironmentMap => {
|
||||
cubemaps.unfiltered_environment_map.clone()
|
||||
}
|
||||
_ => cubemaps.skybox.clone(),
|
||||
@ -287,7 +287,7 @@ impl TryFrom<u32> for ReflectionMode {
|
||||
0 => Ok(ReflectionMode::None),
|
||||
1 => Ok(ReflectionMode::EnvironmentMap),
|
||||
2 => Ok(ReflectionMode::ReflectionProbe),
|
||||
3 => Ok(ReflectionMode::PrefilteredEnvironmentMap),
|
||||
3 => Ok(ReflectionMode::GeneratedEnvironmentMap),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@ -299,7 +299,7 @@ impl Display for ReflectionMode {
|
||||
ReflectionMode::None => "No reflections",
|
||||
ReflectionMode::EnvironmentMap => "Environment map",
|
||||
ReflectionMode::ReflectionProbe => "Reflection probe",
|
||||
ReflectionMode::PrefilteredEnvironmentMap => "Prefiltered environment map",
|
||||
ReflectionMode::GeneratedEnvironmentMap => "Generated environment map",
|
||||
};
|
||||
formatter.write_str(text)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user