Finalize CanvasShading

This commit is contained in:
2023-01-28 15:56:28 +01:00
parent 112c7bc94d
commit 71103a9fb7
4 changed files with 24 additions and 66 deletions

View File

@@ -27,7 +27,8 @@ fn fragment(input: FragmentInput) -> @location(0) vec4<f32> {
var lighting = vec4<f32>();
for (var i: u32 = 0u; i < canvas_material.number_of_lights; i++) {
var luminance = canvas_material.tile_lights[i].intensity * pow(length(canvas_material.tile_lights[i].position - input.world_position.xy), -1.7) * 2.0;
var luminance = pow(length(canvas_material.tile_lights[i].position - input.world_position.xy), -2.0);
luminance *= canvas_material.tile_lights[i].intensity * 2.5;
lighting += vec4<f32>(luminance * canvas_material.tile_lights[i].color.rgb, 0.0);
}

View File

@@ -11,9 +11,8 @@ use bevy::{
},
sprite::{Material2d, Material2dPlugin, MaterialMesh2dBundle, RenderMaterials2d},
};
use tile_light::{
extract_tile_lights, prepare_tile_lights, TileLight, TileLights, TileLightsUniform,
};
use tile_light::{extract_tile_lights, TileLight, TileLightsUniform};
pub(crate) use tile_light::EmissiveTile;
pub struct CanvasPlugin;
@@ -24,13 +23,13 @@ impl Plugin for CanvasPlugin {
.add_startup_system(spawn_canvas);
app.sub_app_mut(RenderApp)
.init_resource::<TileLights>()
.add_system_to_stage(RenderStage::Extract, extract_tile_lights)
.add_system_to_stage(RenderStage::Prepare, prepare_canvas_material);
// .add_system_to_stage(RenderStage::Prepare, prepare_tile_lights);
}
}
const CANVAS_COLOR: Color = Color::rgb(0.05, 0.05, 0.05);
#[derive(AsBindGroup, TypeUuid, Clone)]
#[uuid = "24f83f6e-e52d-41a6-bf1d-0e46e57a4995"]
struct CanvasMaterial {
@@ -45,7 +44,7 @@ struct CanvasMaterial {
impl Default for CanvasMaterial {
fn default() -> Self {
Self {
ambient_color: Color::rgb(0.1, 0.1, 0.1),
ambient_color: CANVAS_COLOR,
number_of_lights: 0,
tile_lights: Default::default(),
}
@@ -63,18 +62,6 @@ impl Material2d for CanvasMaterial {
fn fragment_shader() -> ShaderRef {
"canvas_shader.wgsl".into()
}
// fn specialize(
// descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor,
// layout: &bevy::render::mesh::MeshVertexBufferLayout,
// key: bevy::sprite::Material2dKey<Self>,
// ) -> Result<(), bevy::render::render_resource::SpecializedMeshPipelineError> {
// if let Some(layouts) = descriptor.layout {
// layouts.push(BindGr);
// }
// Ok(())
// }
}
fn prepare_canvas_material(
@@ -84,13 +71,7 @@ fn prepare_canvas_material(
render_queue: Res<RenderQueue>,
) {
let tile_lights = tile_light_query.iter().cloned().collect::<Vec<_>>();
let mut tile_lights_uniform = tile_light::TileLightsUniform::default();
// tile_lights_uniform.data.copy_from_slice(&tile_lights);
let len = tile_lights.len().min(256);
let src = &tile_lights[..len];
let dst = &mut tile_lights_uniform.data[..len];
dst.copy_from_slice(src);
let tile_lights_uniform = TileLightsUniform::from_lights(&tile_lights);
for handle in canvas_query.iter() {
if let Some(material) = materials.get(handle) {
@@ -99,7 +80,7 @@ fn prepare_canvas_material(
let mut buffer = encase::UniformBuffer::new(Vec::new());
buffer
.write(&CanvasMaterialUniform {
ambient_color: Color::rgb_u8(12, 12, 12),
ambient_color: CANVAS_COLOR,
tile_lights: tile_lights_uniform.clone(),
number_of_lights: tile_lights.len() as _,
})

View File

@@ -1,16 +1,9 @@
use bevy::{
math::Vec3Swizzles,
prelude::*,
render::{
render_resource::{ShaderType, UniformBuffer},
renderer::{RenderDevice, RenderQueue},
Extract,
},
sprite::Material2dPipeline,
render::{render_resource::ShaderType, Extract},
};
use super::CanvasMaterial;
const MAX_TILE_LIGHTS: usize = 256;
#[derive(Component, Clone, Copy)]
@@ -31,14 +24,24 @@ pub(super) struct TileLight {
position: Vec2,
}
#[derive(Default, Resource)]
pub(super) struct TileLights(UniformBuffer<TileLightsUniform>);
#[derive(ShaderType, Clone)]
pub(super) struct TileLightsUniform {
pub data: Box<[TileLight; MAX_TILE_LIGHTS]>,
}
impl TileLightsUniform {
pub(super) fn from_lights(tile_lights: &[TileLight]) -> Self {
let mut tile_lights_uniform = TileLightsUniform::default();
let len = tile_lights.len().min(MAX_TILE_LIGHTS);
let src = &tile_lights[..len];
let dst = &mut tile_lights_uniform.data[..len];
dst.copy_from_slice(src);
tile_lights_uniform
}
}
impl Default for TileLightsUniform {
fn default() -> Self {
Self {
@@ -47,19 +50,6 @@ impl Default for TileLightsUniform {
}
}
impl TileLights {
fn set(&mut self, lights: &[TileLight]) {
let len = lights.len().min(MAX_TILE_LIGHTS);
let src = &lights[..len];
let dst = &mut self.0.get_mut().data[..len];
dst.copy_from_slice(src);
}
fn write_buffer(&mut self, render_device: &RenderDevice, render_queue: &RenderQueue) {
self.0.write_buffer(render_device, render_queue);
}
}
pub(super) fn extract_tile_lights(
mut commands: Commands,
emissive_sprite_query: Extract<Query<(Entity, &EmissiveTile, &Sprite, &GlobalTransform)>>,
@@ -72,17 +62,3 @@ pub(super) fn extract_tile_lights(
});
}
}
pub(super) fn prepare_tile_lights(
render_device: Res<RenderDevice>,
render_queue: Res<RenderQueue>,
canvas_material_pipeline: Res<Material2dPipeline<CanvasMaterial>>,
light_query: Query<&TileLight>,
mut tile_lights: ResMut<TileLights>,
) {
let lights = light_query.iter().cloned().collect::<Vec<_>>();
tile_lights.set(&lights);
tile_lights.write_buffer(&render_device, &render_queue);
// canvas_material_pipeline.
}

View File

@@ -1,5 +1,5 @@
use crate::{canvas::CanvasPlugin, fruit::FruitPlugin, snake::SnakePlugin, tick::TickPlugin};
use bevy::{core_pipeline::bloom::BloomSettings, prelude::*, render::camera::ScalingMode};
use bevy::{prelude::*, render::camera::ScalingMode};
use bevy_tweening::TweeningPlugin;
use grid::{SEGMENT_SIZE, SIZE};
use iyes_loopless::prelude::*;