EnvironmentMapLight support for WebGL2 (#7737)
# Objective - Fix the environment map shader not working under webgl due to textureNumLevels() not being supported - Fixes https://github.com/bevyengine/bevy/issues/7722 ## Solution - Instead of using textureNumLevels(), put an extra field in the GpuLights uniform to store the mip count
This commit is contained in:
parent
912fb58869
commit
03575aef22
@ -18,8 +18,9 @@ fn environment_map_light(
|
||||
) -> EnvironmentMapLight {
|
||||
|
||||
// Split-sum approximation for image based lighting: https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
|
||||
let smallest_specular_mip_level = textureNumLevels(environment_map_specular) - 1i;
|
||||
let radiance_level = perceptual_roughness * f32(smallest_specular_mip_level);
|
||||
// Technically we could use textureNumLevels(environment_map_specular) - 1 here, but we use a uniform
|
||||
// because textureNumLevels() does not work on WebGL2
|
||||
let radiance_level = perceptual_roughness * f32(lights.environment_map_smallest_specular_mip_level);
|
||||
let irradiance = textureSample(environment_map_diffuse, environment_map_sampler, N).rgb;
|
||||
let radiance = textureSampleLevel(environment_map_specular, environment_map_sampler, R, radiance_level).rgb;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
directional_light_order, point_light_order, AmbientLight, Cascade, CascadeShadowConfig,
|
||||
Cascades, CascadesVisibleEntities, Clusters, CubemapVisibleEntities, DirectionalLight,
|
||||
DirectionalLightShadowMap, DrawMesh, GlobalVisiblePointLights, MeshPipeline, NotShadowCaster,
|
||||
PointLight, PointLightShadowMap, SetMeshBindGroup, SpotLight, VisiblePointLights,
|
||||
SHADOW_SHADER_HANDLE,
|
||||
DirectionalLightShadowMap, DrawMesh, EnvironmentMapLight, GlobalVisiblePointLights,
|
||||
MeshPipeline, NotShadowCaster, PointLight, PointLightShadowMap, SetMeshBindGroup, SpotLight,
|
||||
VisiblePointLights, SHADOW_SHADER_HANDLE,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_core_pipeline::core_3d::Transparent3d;
|
||||
@ -218,6 +218,7 @@ pub struct GpuLights {
|
||||
n_directional_lights: u32,
|
||||
// offset from spot light's light index to spot light's shadow map index
|
||||
spot_light_shadowmap_offset: i32,
|
||||
environment_map_smallest_specular_mip_level: u32,
|
||||
}
|
||||
|
||||
// NOTE: this must be kept in sync with the same constants in pbr.frag
|
||||
@ -787,12 +788,18 @@ pub(crate) fn spot_light_projection_matrix(angle: f32) -> Mat4 {
|
||||
pub fn prepare_lights(
|
||||
mut commands: Commands,
|
||||
mut texture_cache: ResMut<TextureCache>,
|
||||
images: Res<RenderAssets<Image>>,
|
||||
render_device: Res<RenderDevice>,
|
||||
render_queue: Res<RenderQueue>,
|
||||
mut global_light_meta: ResMut<GlobalLightMeta>,
|
||||
mut light_meta: ResMut<LightMeta>,
|
||||
views: Query<
|
||||
(Entity, &ExtractedView, &ExtractedClusterConfig),
|
||||
(
|
||||
Entity,
|
||||
&ExtractedView,
|
||||
&ExtractedClusterConfig,
|
||||
Option<&EnvironmentMapLight>,
|
||||
),
|
||||
With<RenderPhase<Transparent3d>>,
|
||||
>,
|
||||
ambient_light: Res<AmbientLight>,
|
||||
@ -1029,7 +1036,7 @@ pub fn prepare_lights(
|
||||
.write_buffer(&render_device, &render_queue);
|
||||
|
||||
// set up light data for each view
|
||||
for (entity, extracted_view, clusters) in &views {
|
||||
for (entity, extracted_view, clusters, environment_map) in &views {
|
||||
let point_light_depth_texture = texture_cache.get(
|
||||
&render_device,
|
||||
TextureDescriptor {
|
||||
@ -1096,6 +1103,10 @@ pub fn prepare_lights(
|
||||
// index to shadow map index, we need to subtract point light count and add directional shadowmap count.
|
||||
spot_light_shadowmap_offset: num_directional_cascades_enabled as i32
|
||||
- point_light_count as i32,
|
||||
environment_map_smallest_specular_mip_level: environment_map
|
||||
.and_then(|env_map| images.get(&env_map.specular_map))
|
||||
.map(|specular_map| specular_map.mip_level_count - 1)
|
||||
.unwrap_or(0),
|
||||
};
|
||||
|
||||
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query
|
||||
|
@ -546,6 +546,7 @@ impl FromWorld for MeshPipeline {
|
||||
image.texture_descriptor.size.width as f32,
|
||||
image.texture_descriptor.size.height as f32,
|
||||
),
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,7 @@ struct DirectionalCascade {
|
||||
texel_size: f32,
|
||||
far_bound: f32,
|
||||
}
|
||||
|
||||
|
||||
struct DirectionalLight {
|
||||
cascades: array<DirectionalCascade, #{MAX_CASCADES_PER_LIGHT}>,
|
||||
color: vec4<f32>,
|
||||
@ -59,6 +59,7 @@ struct Lights {
|
||||
cluster_factors: vec4<f32>,
|
||||
n_directional_lights: u32,
|
||||
spot_light_shadowmap_offset: i32,
|
||||
environment_map_smallest_specular_mip_level: u32,
|
||||
};
|
||||
|
||||
struct Fog {
|
||||
|
@ -78,6 +78,7 @@ fn fallback_image_new(
|
||||
image.texture_descriptor.size.width as f32,
|
||||
image.texture_descriptor.size.height as f32,
|
||||
),
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,6 +499,7 @@ pub struct GpuImage {
|
||||
pub texture_format: TextureFormat,
|
||||
pub sampler: Sampler,
|
||||
pub size: Vec2,
|
||||
pub mip_level_count: u32,
|
||||
}
|
||||
|
||||
impl RenderAsset for Image {
|
||||
@ -548,6 +549,7 @@ impl RenderAsset for Image {
|
||||
texture_format: image.texture_descriptor.format,
|
||||
sampler,
|
||||
size,
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +253,7 @@ impl FromWorld for Mesh2dPipeline {
|
||||
image.texture_descriptor.size.width as f32,
|
||||
image.texture_descriptor.size.height as f32,
|
||||
),
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
};
|
||||
Mesh2dPipeline {
|
||||
|
@ -134,6 +134,7 @@ impl FromWorld for SpritePipeline {
|
||||
image.texture_descriptor.size.width as f32,
|
||||
image.texture_descriptor.size.height as f32,
|
||||
),
|
||||
mip_level_count: image.texture_descriptor.mip_level_count,
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user