wip skybox loading
This commit is contained in:
BIN
assets/sky-test.png
Normal file
BIN
assets/sky-test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -4,7 +4,8 @@
|
|||||||
@group(0) @binding(1) var output: texture_storage_2d<rgba32float, write>;
|
@group(0) @binding(1) var output: texture_storage_2d<rgba32float, write>;
|
||||||
|
|
||||||
@group(0) @binding(2) var<uniform> config: TracerUniforms;
|
@group(0) @binding(2) var<uniform> config: TracerUniforms;
|
||||||
|
@group(0) @binding(3) var skybox_texture: texture_cube<f32>;
|
||||||
|
@group(0) @binding(4) var skybox_sampler: sampler;
|
||||||
|
|
||||||
struct View {
|
struct View {
|
||||||
view_proj: mat4x4<f32>,
|
view_proj: mat4x4<f32>,
|
||||||
|
|||||||
14
src/app.rs
14
src/app.rs
@@ -36,7 +36,12 @@ impl Plugin for Blackhole {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>, window: Single<&Window, With<PrimaryWindow>>) {
|
fn setup(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut images: ResMut<Assets<Image>>,
|
||||||
|
window: Single<&Window, With<PrimaryWindow>>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
PerfUiRoot::default(),
|
PerfUiRoot::default(),
|
||||||
PerfUiEntryFPS::default(),
|
PerfUiEntryFPS::default(),
|
||||||
@@ -70,6 +75,7 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>, window: Sing
|
|||||||
let img0 = images.add(image.clone());
|
let img0 = images.add(image.clone());
|
||||||
let img1 = images.add(image);
|
let img1 = images.add(image);
|
||||||
|
|
||||||
|
let skybox = asset_server.load("sky-test.png");
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Name::new("Render Sprite"),
|
Name::new("Render Sprite"),
|
||||||
Sprite {
|
Sprite {
|
||||||
@@ -97,5 +103,9 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>, window: Sing
|
|||||||
))
|
))
|
||||||
.insert(Camera { order: -1, ..default() });
|
.insert(Camera { order: -1, ..default() });
|
||||||
|
|
||||||
commands.insert_resource(TracerRenderTextures(img0, img1));
|
commands.insert_resource(TracerRenderTextures {
|
||||||
|
main: img0,
|
||||||
|
secondary: img1,
|
||||||
|
skybox,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use bevy::{prelude::*, render::render_resource::encase::private::ShaderType};
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct RTCamera;
|
pub struct RTCamera;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use bevy::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::render::pipeline::{TracerImageBindGroups, TracerPipeline};
|
use crate::render::pipeline::{TracerImageBindGroups, TracerPipeline, TracerRenderTextures};
|
||||||
use crate::{SHADER_ASSET_PATH, WORKGROUP_SIZE};
|
use crate::{SHADER_ASSET_PATH, WORKGROUP_SIZE};
|
||||||
|
|
||||||
pub enum TracerState {
|
pub enum TracerState {
|
||||||
@@ -36,16 +36,21 @@ impl render_graph::Node for TracerNode {
|
|||||||
// if the corresponding pipeline has loaded, transition to the next stage
|
// if the corresponding pipeline has loaded, transition to the next stage
|
||||||
match self.state {
|
match self.state {
|
||||||
TracerState::Loading => {
|
TracerState::Loading => {
|
||||||
match pipeline_cache.get_compute_pipeline_state(pipeline.init_pipeline) {
|
let shader_loaded = match pipeline_cache.get_compute_pipeline_state(pipeline.init_pipeline) {
|
||||||
CachedPipelineState::Ok(_) => {
|
CachedPipelineState::Ok(_) => true,
|
||||||
self.state = TracerState::Init;
|
|
||||||
}
|
|
||||||
// If the shader hasn't loaded yet, just wait.
|
// If the shader hasn't loaded yet, just wait.
|
||||||
CachedPipelineState::Err(PipelineCacheError::ShaderNotLoaded(_)) => {}
|
CachedPipelineState::Err(PipelineCacheError::ShaderNotLoaded(_)) => false,
|
||||||
CachedPipelineState::Err(err) => {
|
CachedPipelineState::Err(err) => {
|
||||||
panic!("Initializing assets/{SHADER_ASSET_PATH}:\n{err}")
|
panic!("Initializing assets/{SHADER_ASSET_PATH}:\n{err}")
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let tex = world.resource::<TracerRenderTextures>();
|
||||||
|
let asset_server = world.resource::<AssetServer>();
|
||||||
|
let load_state = asset_server.get_load_state(tex.skybox.id()).unwrap();
|
||||||
|
if load_state.is_loaded() && shader_loaded {
|
||||||
|
self.state = TracerState::Init;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TracerState::Init => {
|
TracerState::Init => {
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ use bevy::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
render::{
|
render::{
|
||||||
Render, RenderApp, RenderSet,
|
Render, RenderApp, RenderSet,
|
||||||
camera::CameraProjection,
|
|
||||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_graph::{RenderGraph, RenderLabel},
|
render_graph::{RenderGraph, RenderLabel},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedComputePipelineId,
|
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedComputePipelineId,
|
||||||
ComputePipelineDescriptor, PipelineCache, ShaderStages, ShaderType, StorageTextureAccess, TextureFormat,
|
ComputePipelineDescriptor, PipelineCache, SamplerBindingType, ShaderStages, ShaderType,
|
||||||
UniformBuffer,
|
StorageTextureAccess, TextureFormat, TextureSampleType, UniformBuffer,
|
||||||
binding_types::{texture_storage_2d, uniform_buffer},
|
binding_types::{sampler, texture_cube, texture_storage_2d, uniform_buffer},
|
||||||
},
|
},
|
||||||
renderer::{RenderDevice, RenderQueue},
|
renderer::{RenderDevice, RenderQueue},
|
||||||
texture::GpuImage,
|
texture::GpuImage,
|
||||||
@@ -26,7 +25,11 @@ pub struct TracerLabel;
|
|||||||
|
|
||||||
#[derive(Resource, Reflect, ExtractResource, Clone)]
|
#[derive(Resource, Reflect, ExtractResource, Clone)]
|
||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
pub struct TracerRenderTextures(pub Handle<Image>, pub Handle<Image>);
|
pub struct TracerRenderTextures {
|
||||||
|
pub main: Handle<Image>,
|
||||||
|
pub secondary: Handle<Image>,
|
||||||
|
pub skybox: Handle<Image>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Resource, Clone, ExtractResource, ShaderType, Default)]
|
#[derive(Resource, Clone, ExtractResource, ShaderType, Default)]
|
||||||
pub struct TracerUniforms {
|
pub struct TracerUniforms {
|
||||||
@@ -64,10 +67,10 @@ impl Plugin for TracerPipelinePlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn switch_textures(images: Res<TracerRenderTextures>, mut sprite: Single<&mut Sprite>) {
|
fn switch_textures(images: Res<TracerRenderTextures>, mut sprite: Single<&mut Sprite>) {
|
||||||
if sprite.image == images.0 {
|
if sprite.image == images.main {
|
||||||
sprite.image = images.1.clone();
|
sprite.image = images.secondary.clone();
|
||||||
} else {
|
} else {
|
||||||
sprite.image = images.0.clone();
|
sprite.image = images.main.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +93,8 @@ impl FromWorld for TracerPipeline {
|
|||||||
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::ReadOnly),
|
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::ReadOnly),
|
||||||
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::WriteOnly),
|
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::WriteOnly),
|
||||||
uniform_buffer::<TracerUniforms>(false),
|
uniform_buffer::<TracerUniforms>(false),
|
||||||
|
texture_cube(TextureSampleType::Float { filterable: true }),
|
||||||
|
sampler(SamplerBindingType::Filtering),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -138,6 +143,8 @@ fn init_pipeline(
|
|||||||
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::ReadOnly),
|
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::ReadOnly),
|
||||||
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::WriteOnly),
|
texture_storage_2d(TextureFormat::Rgba32Float, StorageTextureAccess::WriteOnly),
|
||||||
uniform_buffer::<TracerUniforms>(false),
|
uniform_buffer::<TracerUniforms>(false),
|
||||||
|
texture_cube(TextureSampleType::Float { filterable: true }),
|
||||||
|
sampler(SamplerBindingType::Filtering),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -177,21 +184,12 @@ fn update_tracer_uniforms(
|
|||||||
rt_camera: Single<(&GlobalTransform, &Camera), With<RTCamera>>,
|
rt_camera: Single<(&GlobalTransform, &Camera), With<RTCamera>>,
|
||||||
) {
|
) {
|
||||||
let (transform, cam) = rt_camera.into_inner();
|
let (transform, cam) = rt_camera.into_inner();
|
||||||
/*
|
|
||||||
|
|
||||||
let clip_from_view = cam.clip_from_view();
|
|
||||||
let world_from_clip = clip_from_view.inverse() * transform.compute_matrix().inverse();
|
|
||||||
*/
|
|
||||||
|
|
||||||
let clip_from_view = cam.clip_from_view();
|
let clip_from_view = cam.clip_from_view();
|
||||||
let world_from_clip = transform.compute_matrix() * clip_from_view.inverse();
|
let world_from_clip = transform.compute_matrix() * clip_from_view.inverse();
|
||||||
// cam.ndc_to_world(camera_transform, ndc)
|
|
||||||
|
|
||||||
tracer_uniforms.world_from_clip = world_from_clip;
|
tracer_uniforms.world_from_clip = world_from_clip;
|
||||||
tracer_uniforms.world_position = transform.translation();
|
tracer_uniforms.world_position = transform.translation();
|
||||||
|
|
||||||
// info!("clip_from_view = {:?}", clip_from_view);
|
|
||||||
// info!("world_from_clip = {:?}", world_from_clip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_bind_groups(
|
fn prepare_bind_groups(
|
||||||
@@ -203,8 +201,9 @@ fn prepare_bind_groups(
|
|||||||
render_device: Res<RenderDevice>,
|
render_device: Res<RenderDevice>,
|
||||||
queue: Res<RenderQueue>,
|
queue: Res<RenderQueue>,
|
||||||
) {
|
) {
|
||||||
let view_a = gpu_images.get(&tracer_images.0).unwrap();
|
let view_a = gpu_images.get(&tracer_images.main).unwrap();
|
||||||
let view_b = gpu_images.get(&tracer_images.1).unwrap();
|
let view_b = gpu_images.get(&tracer_images.secondary).unwrap();
|
||||||
|
let skybox = gpu_images.get(&tracer_images.skybox).unwrap();
|
||||||
|
|
||||||
// Uniform buffer is used here to demonstrate how to set up a uniform in a compute shader
|
// Uniform buffer is used here to demonstrate how to set up a uniform in a compute shader
|
||||||
// Alternatives such as storage buffers or push constants may be more suitable for your use case
|
// Alternatives such as storage buffers or push constants may be more suitable for your use case
|
||||||
@@ -214,12 +213,24 @@ fn prepare_bind_groups(
|
|||||||
let bind_group_0 = render_device.create_bind_group(
|
let bind_group_0 = render_device.create_bind_group(
|
||||||
None,
|
None,
|
||||||
&pipeline.texture_bind_group_layout,
|
&pipeline.texture_bind_group_layout,
|
||||||
&BindGroupEntries::sequential((&view_a.texture_view, &view_b.texture_view, &uniform_buffer)),
|
&BindGroupEntries::sequential((
|
||||||
|
&view_a.texture_view,
|
||||||
|
&view_b.texture_view,
|
||||||
|
&uniform_buffer,
|
||||||
|
&skybox.texture_view,
|
||||||
|
&skybox.sampler,
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
let bind_group_1 = render_device.create_bind_group(
|
let bind_group_1 = render_device.create_bind_group(
|
||||||
None,
|
None,
|
||||||
&pipeline.texture_bind_group_layout,
|
&pipeline.texture_bind_group_layout,
|
||||||
&BindGroupEntries::sequential((&view_b.texture_view, &view_a.texture_view, &uniform_buffer)),
|
&BindGroupEntries::sequential((
|
||||||
|
&view_b.texture_view,
|
||||||
|
&view_a.texture_view,
|
||||||
|
&uniform_buffer,
|
||||||
|
&skybox.texture_view,
|
||||||
|
&skybox.sampler,
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
commands.insert_resource(TracerImageBindGroups([bind_group_0, bind_group_1]));
|
commands.insert_resource(TracerImageBindGroups([bind_group_0, bind_group_1]));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user