mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
Fix oit webgl (#15728)
The previous fixes were breaking pretty much everything on main due to naga-oil complaining about the OIT shader not being loaded, since apparently webgl is a default feature. This fix is a bit messier, but properly warns the user and is probably what we should have gone for in the first place.
This commit is contained in:
parent
320d53c1d2
commit
b48f9e2a4b
4 changed files with 57 additions and 38 deletions
|
@ -76,7 +76,6 @@ use crate::{
|
|||
use bevy_app::{App, Plugin};
|
||||
use bevy_asset::load_internal_asset;
|
||||
use bevy_render::prelude::Shader;
|
||||
#[cfg(not(feature = "webgl"))]
|
||||
use oit::OrderIndependentTransparencyPlugin;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -110,8 +109,6 @@ impl Plugin for CorePipelinePlugin {
|
|||
DepthOfFieldPlugin,
|
||||
SmaaPlugin,
|
||||
PostProcessingPlugin,
|
||||
// DownlevelFlags::FRAGMENT_WRITABLE_STORAGE is required for OIT
|
||||
#[cfg(not(feature = "webgl"))]
|
||||
OrderIndependentTransparencyPlugin,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
use crate::{
|
||||
fullscreen_vertex_shader::fullscreen_shader_vertex_state,
|
||||
oit::OrderIndependentTransparencySettings,
|
||||
};
|
||||
use bevy_app::Plugin;
|
||||
use bevy_asset::{load_internal_asset, Handle};
|
||||
use bevy_derive::Deref;
|
||||
|
@ -9,20 +13,16 @@ use bevy_render::{
|
|||
render_resource::{
|
||||
binding_types::{storage_buffer_sized, texture_depth_2d, uniform_buffer},
|
||||
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, BlendComponent,
|
||||
BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState,
|
||||
MultisampleState, PipelineCache, PrimitiveState, RenderPipelineDescriptor, Shader,
|
||||
ShaderStages, TextureFormat,
|
||||
BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, DownlevelFlags,
|
||||
FragmentState, MultisampleState, PipelineCache, PrimitiveState, RenderPipelineDescriptor,
|
||||
Shader, ShaderStages, TextureFormat,
|
||||
},
|
||||
renderer::RenderDevice,
|
||||
renderer::{RenderAdapter, RenderDevice},
|
||||
texture::BevyDefault,
|
||||
view::{ExtractedView, ViewTarget, ViewUniform, ViewUniforms},
|
||||
Render, RenderApp, RenderSet,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
fullscreen_vertex_shader::fullscreen_shader_vertex_state,
|
||||
oit::OrderIndependentTransparencySettings,
|
||||
};
|
||||
use bevy_utils::tracing::warn;
|
||||
|
||||
use super::OitBuffers;
|
||||
|
||||
|
@ -42,18 +42,6 @@ impl Plugin for OitResolvePlugin {
|
|||
"oit_resolve.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
};
|
||||
|
||||
render_app.add_systems(
|
||||
Render,
|
||||
(
|
||||
queue_oit_resolve_pipeline.in_set(RenderSet::Queue),
|
||||
prepare_oit_resolve_bind_group.in_set(RenderSet::PrepareBindGroups),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
fn finish(&self, app: &mut bevy_app::App) {
|
||||
|
@ -61,7 +49,26 @@ impl Plugin for OitResolvePlugin {
|
|||
return;
|
||||
};
|
||||
|
||||
render_app.init_resource::<OitResolvePipeline>();
|
||||
if !render_app
|
||||
.world()
|
||||
.resource::<RenderAdapter>()
|
||||
.get_downlevel_capabilities()
|
||||
.flags
|
||||
.contains(DownlevelFlags::FRAGMENT_WRITABLE_STORAGE)
|
||||
{
|
||||
warn!("OrderIndependentTransparencyPlugin not loaded. GPU lacks support: DownlevelFlags::FRAGMENT_WRITABLE_STORAGE.");
|
||||
return;
|
||||
}
|
||||
|
||||
render_app
|
||||
.add_systems(
|
||||
Render,
|
||||
(
|
||||
queue_oit_resolve_pipeline.in_set(RenderSet::Queue),
|
||||
prepare_oit_resolve_bind_group.in_set(RenderSet::PrepareBindGroups),
|
||||
),
|
||||
)
|
||||
.init_resource::<OitResolvePipeline>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use alloc::sync::Arc;
|
||||
use core::{array, num::NonZero};
|
||||
|
||||
use bevy_core_pipeline::{
|
||||
core_3d::ViewTransmissionTexture,
|
||||
oit::{OitBuffers, OrderIndependentTransparencySettings},
|
||||
|
@ -29,9 +27,11 @@ use bevy_render::{
|
|||
VISIBILITY_RANGES_STORAGE_BUFFER_COUNT,
|
||||
},
|
||||
};
|
||||
use core::{array, num::NonZero};
|
||||
|
||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||
use bevy_render::render_resource::binding_types::texture_cube;
|
||||
use bevy_render::renderer::RenderAdapter;
|
||||
#[cfg(debug_assertions)]
|
||||
use bevy_utils::warn_once;
|
||||
use environment_map::EnvironmentMapLight;
|
||||
|
@ -194,6 +194,7 @@ fn layout_entries(
|
|||
visibility_ranges_buffer_binding_type: BufferBindingType,
|
||||
layout_key: MeshPipelineViewLayoutKey,
|
||||
render_device: &RenderDevice,
|
||||
render_adapter: &RenderAdapter,
|
||||
) -> Vec<BindGroupLayoutEntry> {
|
||||
let mut entries = DynamicBindGroupLayoutEntries::new_with_indices(
|
||||
ShaderStages::FRAGMENT,
|
||||
|
@ -358,15 +359,25 @@ fn layout_entries(
|
|||
));
|
||||
|
||||
// OIT
|
||||
if cfg!(not(feature = "webgl")) && layout_key.contains(MeshPipelineViewLayoutKey::OIT_ENABLED) {
|
||||
entries = entries.extend_with_indices((
|
||||
// oit_layers
|
||||
(31, storage_buffer_sized(false, None)),
|
||||
// oit_layer_ids,
|
||||
(32, storage_buffer_sized(false, None)),
|
||||
// oit_layer_count
|
||||
(33, uniform_buffer::<i32>(true)),
|
||||
));
|
||||
if layout_key.contains(MeshPipelineViewLayoutKey::OIT_ENABLED) {
|
||||
// Check if the GPU supports writable storage buffers in the fragment shader
|
||||
// If not, we can't use OIT, so we skip the OIT bindings.
|
||||
// This is a hack to avoid errors on webgl -- the OIT plugin will warn the user that OIT
|
||||
// is not supported on their platform, so we don't need to do it here.
|
||||
if render_adapter
|
||||
.get_downlevel_capabilities()
|
||||
.flags
|
||||
.contains(DownlevelFlags::FRAGMENT_WRITABLE_STORAGE)
|
||||
{
|
||||
entries = entries.extend_with_indices((
|
||||
// oit_layers
|
||||
(31, storage_buffer_sized(false, None)),
|
||||
// oit_layer_ids,
|
||||
(32, storage_buffer_sized(false, None)),
|
||||
// oit_layer_count
|
||||
(33, uniform_buffer::<i32>(true)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
entries.to_vec()
|
||||
|
@ -387,6 +398,7 @@ impl FromWorld for MeshPipelineViewLayouts {
|
|||
// [`MeshPipelineViewLayoutKey`] flags.
|
||||
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
let render_adapter = world.resource::<RenderAdapter>();
|
||||
|
||||
let clustered_forward_buffer_binding_type = render_device
|
||||
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
|
||||
|
@ -400,6 +412,7 @@ impl FromWorld for MeshPipelineViewLayouts {
|
|||
visibility_ranges_buffer_binding_type,
|
||||
key,
|
||||
render_device,
|
||||
render_adapter,
|
||||
);
|
||||
#[cfg(debug_assertions)]
|
||||
let texture_count: usize = entries
|
||||
|
@ -436,6 +449,7 @@ impl MeshPipelineViewLayouts {
|
|||
/// [`MeshPipelineViewLayoutKey`] flags.
|
||||
pub fn generate_view_layouts(
|
||||
render_device: &RenderDevice,
|
||||
render_adapter: &RenderAdapter,
|
||||
clustered_forward_buffer_binding_type: BufferBindingType,
|
||||
visibility_ranges_buffer_binding_type: BufferBindingType,
|
||||
) -> [MeshPipelineViewLayout; MeshPipelineViewLayoutKey::COUNT] {
|
||||
|
@ -446,6 +460,7 @@ pub fn generate_view_layouts(
|
|||
visibility_ranges_buffer_binding_type,
|
||||
key,
|
||||
render_device,
|
||||
render_adapter,
|
||||
);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
|
|
@ -42,8 +42,8 @@ pub use wgpu::{
|
|||
BufferBinding, BufferBindingType, BufferDescriptor, BufferSize, BufferUsages, ColorTargetState,
|
||||
ColorWrites, CommandEncoder, CommandEncoderDescriptor, CompareFunction, ComputePass,
|
||||
ComputePassDescriptor, ComputePipelineDescriptor as RawComputePipelineDescriptor,
|
||||
DepthBiasState, DepthStencilState, Extent3d, Face, Features as WgpuFeatures, FilterMode,
|
||||
FragmentState as RawFragmentState, FrontFace, ImageCopyBuffer, ImageCopyBufferBase,
|
||||
DepthBiasState, DepthStencilState, DownlevelFlags, Extent3d, Face, Features as WgpuFeatures,
|
||||
FilterMode, FragmentState as RawFragmentState, FrontFace, ImageCopyBuffer, ImageCopyBufferBase,
|
||||
ImageCopyTexture, ImageCopyTextureBase, ImageDataLayout, ImageSubresourceRange, IndexFormat,
|
||||
Limits as WgpuLimits, LoadOp, Maintain, MapMode, MultisampleState, Operations, Origin3d,
|
||||
PipelineCompilationOptions, PipelineLayout, PipelineLayoutDescriptor, PolygonMode,
|
||||
|
|
Loading…
Reference in a new issue