Rebuild core around render graph AST and shared memory
Amp-Thread-ID: https://ampcode.com/threads/T-01a01380-b478-77d0-84a0-102880a5c5ae Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
+10
-129
@@ -1,22 +1,12 @@
|
||||
#![cfg(target_arch = "wasm32")]
|
||||
|
||||
use ultraviolet::Mat4;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use renderer::app_setup::WebAppRuntime;
|
||||
use renderer::camera::Camera;
|
||||
use renderer::render_data::{InstanceType, MeshCreateInfo, RenderData};
|
||||
use renderer::render_data::RenderData;
|
||||
use renderer::renderer as gpu_renderer;
|
||||
use renderer::renderer::gpu_scene::vertex_layouts;
|
||||
use renderer::renderer::scene::FrameMetadata;
|
||||
|
||||
/// Simple vertex format.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct Vertex {
|
||||
pos: [f32; 3],
|
||||
}
|
||||
|
||||
struct EditorScene {
|
||||
uniform_buffers: [wgpu::Buffer; 2],
|
||||
bind_groups: [wgpu::BindGroup; 2],
|
||||
@@ -28,7 +18,7 @@ impl renderer::renderer::scene::Scene for EditorScene {
|
||||
fn setup(
|
||||
renderer_context: &gpu_renderer::RendererContext,
|
||||
resources: &mut gpu_renderer::PipelineLibrary,
|
||||
render_data: &mut RenderData,
|
||||
_render_data: &mut RenderData,
|
||||
) -> Self {
|
||||
let dimension = ultraviolet::Vec2::new(
|
||||
renderer_context.surface_config.width as f32,
|
||||
@@ -50,21 +40,12 @@ impl renderer::renderer::scene::Scene for EditorScene {
|
||||
|
||||
resources.set_bind_group_layouts(&bind_group_layouts);
|
||||
|
||||
let mut scene = EditorScene {
|
||||
EditorScene {
|
||||
uniform_buffers: [uniform_resource.buffer, camera_resource.buffer],
|
||||
bind_groups: [uniform_resource.bind_group, camera_resource.bind_group],
|
||||
frame_metadata,
|
||||
cam: camera,
|
||||
};
|
||||
|
||||
scene.create_default_scene(
|
||||
&renderer_context.device,
|
||||
resources,
|
||||
render_data,
|
||||
renderer_context.surface_config.format,
|
||||
);
|
||||
|
||||
scene
|
||||
}
|
||||
}
|
||||
|
||||
fn frame_metadata_mut(&mut self) -> Option<&mut FrameMetadata> {
|
||||
@@ -108,116 +89,16 @@ impl renderer::renderer::scene::Scene for EditorScene {
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorScene {
|
||||
/// Ground plane vertex data.
|
||||
const VERTICES: &[Vertex] = &[
|
||||
// First triangle of quad
|
||||
Vertex {
|
||||
pos: [-5.0, 0.0, -5.0],
|
||||
},
|
||||
Vertex {
|
||||
pos: [5.0, 0.0, -5.0],
|
||||
},
|
||||
Vertex {
|
||||
pos: [-5.0, 0.0, 5.0],
|
||||
},
|
||||
// Second triangle of quad
|
||||
Vertex {
|
||||
pos: [5.0, 0.0, -5.0],
|
||||
},
|
||||
Vertex {
|
||||
pos: [5.0, 0.0, 5.0],
|
||||
},
|
||||
Vertex {
|
||||
pos: [-5.0, 0.0, 5.0],
|
||||
},
|
||||
];
|
||||
// Wind the ground plane so the upward-facing side is front-facing (CCW from
|
||||
// above) to avoid being culled by the default back-face culling.
|
||||
const INDICES: &[u32] = &[0, 2, 1, 3, 5, 4];
|
||||
|
||||
fn create_default_scene(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
resources: &mut gpu_renderer::PipelineLibrary,
|
||||
render_data: &mut RenderData,
|
||||
surface_format: wgpu::TextureFormat,
|
||||
) {
|
||||
let positions: Vec<[f32; 3]> = Self::VERTICES.iter().map(|v| v.pos).collect();
|
||||
// Ground plane normals point upward (Y+)
|
||||
let normals: Vec<[f32; 3]> = vec![[0.0, 1.0, 0.0]; positions.len()];
|
||||
let tangents: Vec<[f32; 4]> = vec![[1.0, 0.0, 0.0, 1.0]; positions.len()];
|
||||
let uvs: &[[f32; 2]] = &[
|
||||
[0.0, 0.0],
|
||||
[1.0, 0.0],
|
||||
[0.0, 1.0],
|
||||
[1.0, 0.0],
|
||||
[1.0, 1.0],
|
||||
[0.0, 1.0],
|
||||
];
|
||||
|
||||
let vertex_layout = vertex_layouts();
|
||||
|
||||
let pipeline_index = resources.get_or_create_pipeline(
|
||||
device,
|
||||
"ground_plane",
|
||||
&vertex_layout,
|
||||
include_str!("./program.wgsl"),
|
||||
surface_format,
|
||||
);
|
||||
|
||||
let scale_factor = 100.0;
|
||||
let scale_matrix = Mat4::from_scale(scale_factor);
|
||||
|
||||
let transform: [[f32; 4]; 4] = scale_matrix.into();
|
||||
render_data
|
||||
.create_mesh(MeshCreateInfo {
|
||||
positions: &positions,
|
||||
normals: &normals,
|
||||
tangents: &tangents,
|
||||
uvs,
|
||||
indices: Self::INDICES,
|
||||
pipeline: pipeline_index,
|
||||
material: renderer::render_data::MaterialKey::DEFAULT,
|
||||
default_instance_type: InstanceType {
|
||||
words: [1 | 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
},
|
||||
default_transform: transform,
|
||||
})
|
||||
.expect("ground plane geometry is valid");
|
||||
}
|
||||
}
|
||||
|
||||
/// Entrypoint for the level editor
|
||||
/// Start the level editor inside its owning render worker.
|
||||
#[wasm_bindgen]
|
||||
pub fn main(profile: bool) -> Result<RendererBridge, JsValue> {
|
||||
pub fn worker_main(profile: bool) -> u32 {
|
||||
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
wasm_logger::init(wasm_logger::Config::default());
|
||||
|
||||
let runtime = WebAppRuntime::new::<EditorScene>("main-worker", "#canvas0", profile)?;
|
||||
Ok(RendererBridge { runtime })
|
||||
renderer::app_setup::worker_entrypoint::<EditorScene>(profile)
|
||||
}
|
||||
|
||||
/// Opaque owner of the worker, event listeners, and pinned command ring.
|
||||
/// Return this worker's shared WebAssembly memory to messaging clients.
|
||||
#[wasm_bindgen]
|
||||
pub struct RendererBridge {
|
||||
runtime: renderer::app_setup::WebAppRuntime,
|
||||
pub fn worker_memory() -> JsValue {
|
||||
wasm_bindgen::memory()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl RendererBridge {
|
||||
#[wasm_bindgen(getter)]
|
||||
pub fn worker(&self) -> web_sys::Worker {
|
||||
web_sys::Worker::clone(&*self.runtime.worker())
|
||||
}
|
||||
#[wasm_bindgen(getter, js_name = ringPtr)]
|
||||
pub fn ring_ptr(&self) -> u32 {
|
||||
self.runtime.ring_ptr()
|
||||
}
|
||||
#[wasm_bindgen(getter)]
|
||||
pub fn memory(&self) -> JsValue {
|
||||
wasm_bindgen::memory()
|
||||
}
|
||||
}
|
||||
|
||||
renderer::export_worker_entrypoint!();
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
struct UniformData {
|
||||
mouse_move: vec2<f32>,
|
||||
mouse_click: vec2<f32>,
|
||||
resolution: vec2<f32>,
|
||||
time: f32,
|
||||
_padding0: f32,
|
||||
camera_position: vec4<f32>,
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var<uniform> uni: UniformData;
|
||||
@group(1) @binding(0) var<uniform> view_proj: mat4x4<f32>;
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) pos: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
@location(2) uv: vec2<f32>,
|
||||
@location(3) model_col0: vec4<f32>,
|
||||
@location(4) model_col1: vec4<f32>,
|
||||
@location(5) model_col2: vec4<f32>,
|
||||
@location(6) model_col3: vec4<f32>,
|
||||
@location(7) normal_col0: vec4<f32>,
|
||||
@location(8) normal_col1: vec4<f32>,
|
||||
@location(9) normal_col2: vec4<f32>,
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) world_pos: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>
|
||||
}
|
||||
|
||||
|
||||
@vertex
|
||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
let model = mat4x4<f32>(
|
||||
in.model_col0,
|
||||
in.model_col1,
|
||||
in.model_col2,
|
||||
in.model_col3,
|
||||
);
|
||||
let world_position = model * vec4<f32>(in.pos, 1.0);
|
||||
out.clip_position = view_proj * world_position;
|
||||
out.world_pos = world_position.xyz;
|
||||
let normal_matrix = mat3x3<f32>(in.normal_col0.xyz, in.normal_col1.xyz, in.normal_col2.xyz);
|
||||
out.normal = normalize(normal_matrix * in.normal);
|
||||
return out;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let light_direction = normalize(vec3<f32>(0.35, 1.0, 0.45));
|
||||
let light_color = vec3<f32>(1.0, 0.95, 0.85);
|
||||
let base_color = vec3<f32>(0.2, 0.2, 0.2);
|
||||
|
||||
let normal = normalize(in.normal);
|
||||
let view_dir = normalize(uni.camera_position.xyz - in.world_pos);
|
||||
|
||||
let diffuse_strength = max(dot(normal, light_direction), 0.0);
|
||||
let ambient = 0.15;
|
||||
|
||||
var specular = 0.0;
|
||||
if diffuse_strength > 0.0 {
|
||||
let halfway_dir = normalize(light_direction + view_dir);
|
||||
specular = pow(max(dot(normal, halfway_dir), 0.0), 32.0);
|
||||
}
|
||||
|
||||
let lighting = min(base_color * (ambient + diffuse_strength) + light_color * specular, vec3<f32>(1.0));
|
||||
let x = select(0.0, 0.3, distance(in.clip_position.xy, uni.mouse_move) < 25.0);
|
||||
let y = select(0.0, 0.3, distance(in.clip_position.xy, uni.mouse_click) < 25.0);
|
||||
return vec4<f32>(lighting + x - y, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user