textures, they DO they work! but how to sample?

This commit is contained in:
2026-02-18 20:07:59 -05:00
parent 58b757a838
commit dd7232d5e7
4 changed files with 39 additions and 53 deletions

BIN
assets/sky-array.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -41,27 +41,21 @@ fn update(@builtin(global_invocation_id) invocation_id: vec3<u32>) {
let ndc = loc * 2.0f - 1.0f; let ndc = loc * 2.0f - 1.0f;
var ray = createCameraRay(ndc); var ray = createCameraRay(ndc);
// var result = vec3<f32>(0.0);
// for (var i: i32 = 0; i < 1; i++){
// var hit = trace(ray);
// result += ray.energy * shade(&ray, hit);
// if !any(ray.energy != vec3<f32>(0.0))
// {
// break;
// }
// }
let hit_data = trace(ray); let hit_data = trace(ray);
var final_color = hit_data.color; var final_color = hit_data.color;
// Simple fog/distance visualization let step_factor = f32(hit_data.steps)/100.0;
let distance_factor = clamp(hit_data.distance / 50.0, 0.0, 1.0); final_color = final_color * step_factor;
final_color = mix(final_color * (f32(hit_data.steps)/ 100.0), vec3<f32>(0.1), distance_factor); // Fog: mix object color with dark gray
let color = vec4<f32>(final_color, 1.0);
var color = vec4<f32>(final_color, 1.0);
if hit_data.distance == 100.0 {
color = config.sky_color;
// color = textureSampleLevel(skybox_texture, skybox_sampler, vec3<f32>(0.0, 0.0, 1.0), 0, 0u);
}
let location = vec2<i32>(i32(invocation_id.x), i32(invocation_id.y)); let location = vec2<i32>(i32(invocation_id.x), i32(invocation_id.y));
textureStore(output, location, color); textureStore(output, location, color);
@@ -139,25 +133,6 @@ struct Ray {
energy: vec3<f32>, energy: vec3<f32>,
} }
struct RayHit {
distance: f32,
position: vec3<f32>,
normal: vec3<f32>,
albedo: vec3<f32>,
specular: vec3<f32>
}
fn createRayHit() -> RayHit {
var hit: RayHit;
hit.position = vec3<f32>(0.0, 0.0, 0.0);
hit.distance = -999999999.0f;
hit.normal = vec3<f32>(0.0, 0.0, 0.0);
hit.albedo = vec3<f32>(0.0, 0.0, 0.0);
hit.specular = vec3<f32>(0.0, 0.0, 0.0);
return hit;
}
fn createRay(origin: vec3<f32>, direction: vec3<f32>) -> Ray fn createRay(origin: vec3<f32>, direction: vec3<f32>) -> Ray
{ {
var ray: Ray; var ray: Ray;
@@ -197,6 +172,7 @@ struct Hit {
hit_pos: vec3<f32>, hit_pos: vec3<f32>,
normal: vec3<f32>, normal: vec3<f32>,
color: vec3<f32>, color: vec3<f32>,
direction: vec3<f32>,
steps: i32, steps: i32,
}; };
@@ -223,7 +199,7 @@ fn trace(ray: Ray) -> Hit {
// Check for a hit // Check for a hit
if (distance_to_scene < min_hit_distance) { if (distance_to_scene < min_hit_distance) {
// A hit occurred! // A hit occurred!
return Hit(total_distance, current_pos, vec3<f32>(0.0), vec3<f32>(1.0, 0.0, 0.0), i); // Return red color for now return Hit(total_distance, current_pos, vec3<f32>(0.0), vec3<f32>(1.0, 0.0, 0.0), ray.direction, i); // Return red color for now
} }
// Check if we marched too far // Check if we marched too far
@@ -236,5 +212,5 @@ fn trace(ray: Ray) -> Hit {
} }
// No hit found // No hit found
return Hit(max_distance, vec3<f32>(0.0), vec3<f32>(0.0), vec3<f32>(0.0, 0.0, 0.0), 0); // Return black for background return Hit(max_distance, vec3<f32>(0.0), vec3<f32>(0.0), vec3<f32>(0.0, 0.0, 0.0), ray.direction, max_steps); // Return black for background
} }

View File

@@ -2,7 +2,9 @@ use bevy::{
asset::RenderAssetUsages, asset::RenderAssetUsages,
prelude::*, prelude::*,
render::{ render::{
render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages, TextureViewDimension}, render_resource::{
Extent3d, TextureDimension, TextureFormat, TextureUsages, TextureViewDescriptor, TextureViewDimension,
},
view::RenderLayers, view::RenderLayers,
}, },
window::PrimaryWindow, window::PrimaryWindow,
@@ -93,19 +95,24 @@ fn setup(
let mut skybox_render_image = Image::new_fill( let mut skybox_render_image = Image::new_fill(
Extent3d { Extent3d {
width: 1024, width: 256,
height: 768, height: 1536,
..Default::default() ..Default::default()
}, },
TextureDimension::D3, TextureDimension::D2,
&[255; PIXEL_SIZE], &[255; PIXEL_SIZE],
PIXEL_FORMAT, PIXEL_FORMAT,
RenderAssetUsages::RENDER_WORLD, RenderAssetUsages::RENDER_WORLD,
); );
skybox_render_image.reinterpret_stacked_2d_as_array(6);
skybox_render_image.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING | TextureUsages::RENDER_ATTACHMENT; skybox_render_image.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING | TextureUsages::RENDER_ATTACHMENT;
skybox_render_image.texture_view_descriptor = Some(TextureViewDescriptor {
dimension: Some(TextureViewDimension::Cube),
..default()
});
let skybox_render_image_handle = images.add(skybox_render_image); let skybox_render_image_handle = images.add(skybox_render_image);
let skybox_asset = asset_server.load("sky-test.png"); let skybox_asset = asset_server.load("sky-array.png");
commands.spawn(( commands.spawn((
Name::new("Render Sprite"), Name::new("Render Sprite"),
Sprite { Sprite {
@@ -165,9 +172,10 @@ fn prepare_skybox(
.expect("Skybox asset image does not exist") .expect("Skybox asset image does not exist")
.clone(); .clone();
skybox_image.reinterpret_stacked_2d_as_array(skybox_image.height() / skybox_image.width()); skybox_image.reinterpret_stacked_2d_as_array(skybox_image.height() / skybox_image.width());
let mut desc = skybox_image.texture_view_descriptor.unwrap(); skybox_image.texture_view_descriptor = Some(TextureViewDescriptor {
desc.dimension = Some(TextureViewDimension::Cube); dimension: Some(TextureViewDimension::Cube),
skybox_image.texture_view_descriptor = Some(desc); ..default()
});
image_assets.insert(tracer_textures.skybox.id(), skybox_image.clone()); image_assets.insert(tracer_textures.skybox.id(), skybox_image.clone());
} }

View File

@@ -36,22 +36,24 @@ 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 => {
let shader_loaded = match pipeline_cache.get_compute_pipeline_state(pipeline.init_pipeline) { match pipeline_cache.get_compute_pipeline_state(pipeline.init_pipeline) {
CachedPipelineState::Ok(_) => true, CachedPipelineState::Ok(_) => {
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(_)) => false, CachedPipelineState::Err(PipelineCacheError::ShaderNotLoaded(_)) => (),
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 tex = world.resource::<TracerRenderTextures>();
let asset_server = world.resource::<AssetServer>(); // let asset_server = world.resource::<AssetServer>();
let load_state = asset_server.get_load_state(tex.skybox.id()).unwrap(); // let load_state = asset_server.get_load_state(tex.skybox.id()).expect();
if load_state.is_loaded() && shader_loaded { // if load_state.is_loaded() && shader_loaded {
self.state = TracerState::Init; // self.state = TracerState::Init;
} // }
} }
TracerState::Init => { TracerState::Init => {
if let CachedPipelineState::Ok(_) = pipeline_cache.get_compute_pipeline_state(pipeline.update_pipeline) if let CachedPipelineState::Ok(_) = pipeline_cache.get_compute_pipeline_state(pipeline.update_pipeline)