From a33c92eeb3242b4e93529b5fb2695656e7e47b33 Mon Sep 17 00:00:00 2001 From: Speykious Date: Wed, 25 Sep 2024 00:09:35 +0200 Subject: [PATCH] Remove WGPU renderer We currently suffer from a skill issue regarding WGPU, so we cannot maintain it. If in the future one of us learns to use WGPU, we will rewrite a WGPU renderer from scratch according to inox2d's new architecture. --- README.md | 14 +- examples/render-wgpu/Cargo.toml | 18 - examples/render-wgpu/src/main.rs | 155 ------ inox2d-wgpu/Cargo.toml | 19 - inox2d-wgpu/src/buffers.rs | 68 --- inox2d-wgpu/src/lib.rs | 442 ------------------ inox2d-wgpu/src/node_bundle.rs | 166 ------- inox2d-wgpu/src/pipeline.rs | 325 ------------- inox2d-wgpu/src/shaders/basic/anim.vert.wgsl | 27 -- .../src/shaders/basic/basic-mask.frag.wgsl | 26 -- inox2d-wgpu/src/shaders/basic/basic.frag.wgsl | 60 --- inox2d-wgpu/src/shaders/basic/basic.vert.wgsl | 30 -- .../shaders/basic/composite-mask.frag.wgsl | 27 -- .../src/shaders/basic/composite.frag.wgsl | 57 --- .../src/shaders/basic/composite.vert.wgsl | 17 - inox2d-wgpu/src/shaders/basic/mask.frag.wgsl | 21 - inox2d-wgpu/src/shaders/basic/mask.vert.wgsl | 28 -- 17 files changed, 1 insertion(+), 1499 deletions(-) delete mode 100644 examples/render-wgpu/Cargo.toml delete mode 100644 examples/render-wgpu/src/main.rs delete mode 100644 inox2d-wgpu/Cargo.toml delete mode 100644 inox2d-wgpu/src/buffers.rs delete mode 100644 inox2d-wgpu/src/lib.rs delete mode 100644 inox2d-wgpu/src/node_bundle.rs delete mode 100644 inox2d-wgpu/src/pipeline.rs delete mode 100644 inox2d-wgpu/src/shaders/basic/anim.vert.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/basic-mask.frag.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/basic.frag.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/basic.vert.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/composite-mask.frag.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/composite.frag.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/composite.vert.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/mask.frag.wgsl delete mode 100644 inox2d-wgpu/src/shaders/basic/mask.vert.wgsl diff --git a/README.md b/README.md index 5e018d8..7258bb5 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This repository is purely for developers and is not useful if you're an end user Both INP and INX files get parsed correctly. -Both renderers (OpenGL, WGPU) now work on all models we could test them on (Aka, Midori, Arch-chan). +The OpenGL renderer works on all models we could test them on (Aka, Midori, Arch-chan). The newer models which use the MeshGroup feature don't work yet though. Support for mesh groups and animations is on the way! @@ -47,8 +47,6 @@ Support for mesh groups and animations is on the way! - [x] Rendering - [x] OpenGL - [x] WASM (WebGL) - - [x] WGPU - - [ ] WASM (WebGL) - [ ] Draw List - [x] Parameters - [x] Deforms (mesh vertex offsets) @@ -80,16 +78,6 @@ See the [`render_webgl`](/examples/render_webgl) example. ![WebGL-rendered Aka](https://fs.speykious.dev/inox2d/inox2d-webgl-foxgirl.png) -### WGPU renderer - -```sh -cargo run -p render-wgpu path/to/puppet.inp -``` - -![WGPU-rendered Arch-chan](https://fs.speykious.dev/inox2d/inox2d-wgpu-arch-chan.png) - -  - ## Implementation Inox2D aims to support all features currently present in the standard D implementation. diff --git a/examples/render-wgpu/Cargo.toml b/examples/render-wgpu/Cargo.toml deleted file mode 100644 index d868f1f..0000000 --- a/examples/render-wgpu/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "render-wgpu" -version = "0.1.0" -edition = "2021" - -[dependencies] -common = { path = "../common" } -inox2d = { path = "../../inox2d" } -inox2d-wgpu = { path = "../../inox2d-wgpu" } - -clap = { version = "4.1.8", features = ["derive"] } -glam = { version = "0.25.0", features = ["bytemuck"] } -pollster = "0.3.0" -raw-window-handle = "0.5.2" -tracing = "0.1.37" -tracing-subscriber = "0.3.16" -winit = { version = "0.29", features = ["rwh_05"] } -wgpu = "0.19.1" diff --git a/examples/render-wgpu/src/main.rs b/examples/render-wgpu/src/main.rs deleted file mode 100644 index 588be6b..0000000 --- a/examples/render-wgpu/src/main.rs +++ /dev/null @@ -1,155 +0,0 @@ -use common::scene::ExampleSceneController; -use glam::{uvec2, vec2, Vec2}; -use wgpu::CompositeAlphaMode; -use winit::{ - event::*, - event_loop::EventLoop, - keyboard::{KeyCode, PhysicalKey}, - window::WindowBuilder, -}; - -use inox2d::formats::inp::parse_inp; -use inox2d::model::Model; -use inox2d_wgpu::Renderer; -use std::fs; -use std::path::PathBuf; - -use clap::Parser; - -pub async fn run(model: Model) { - let event_loop = EventLoop::new().unwrap(); - let window = WindowBuilder::new() - .with_inner_size(winit::dpi::PhysicalSize::new(800, 800)) - .with_resizable(true) - .with_transparent(true) - .with_title("Render Inochi2D Puppet (WGPU)") - .build(&event_loop) - .unwrap(); - - let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default()); - let surface = instance.create_surface(&window).unwrap(); - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::default(), - compatible_surface: Some(&surface), - force_fallback_adapter: false, - }) - .await - .unwrap(); - - let (device, queue) = adapter - .request_device( - &wgpu::DeviceDescriptor { - label: None, - required_features: wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER, - required_limits: wgpu::Limits::default(), - }, - None, - ) - .await - .unwrap(); - - // Fallback to first alpha mode if PreMultiplied is not supported - let alpha_modes = surface.get_capabilities(&adapter).alpha_modes; - let alpha_mode = if alpha_modes.contains(&CompositeAlphaMode::PreMultiplied) { - CompositeAlphaMode::PreMultiplied - } else { - alpha_modes[0] - }; - - let mut config = wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, - format: wgpu::TextureFormat::Bgra8Unorm, - width: window.inner_size().width, - height: window.inner_size().height, - present_mode: wgpu::PresentMode::Fifo, - alpha_mode, - view_formats: Vec::new(), - desired_maximum_frame_latency: 2, - }; - surface.configure(&device, &config); - - let mut renderer = Renderer::new( - &device, - &queue, - wgpu::TextureFormat::Bgra8Unorm, - &model, - uvec2(window.inner_size().width, window.inner_size().height), - ); - renderer.camera.scale = Vec2::splat(0.15); - - let mut scene_ctrl = ExampleSceneController::new(&renderer.camera, 0.5); - let mut puppet = model.puppet; - - event_loop - .run(|event, elwt| match event { - Event::WindowEvent { - window_id: _, - event: WindowEvent::RedrawRequested, - } => { - scene_ctrl.update(&mut renderer.camera); - - puppet.begin_set_params(); - let t = scene_ctrl.current_elapsed(); - let _ = puppet.set_named_param("Head:: Yaw-Pitch", vec2(t.cos(), t.sin())); - puppet.end_set_params(scene_ctrl.dt()); - - let output = surface.get_current_texture().unwrap(); - let view = (output.texture).create_view(&wgpu::TextureViewDescriptor::default()); - - renderer.render(&queue, &device, &puppet, &view); - output.present(); - } - Event::WindowEvent { ref event, .. } => match event { - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - //virtual_keycode: Some(VirtualKeyCode::Escape), - state: ElementState::Pressed, - physical_key: PhysicalKey::Code(KeyCode::Escape), - .. - }, - .. - } => { - elwt.exit(); - } - WindowEvent::Resized(size) => { - // Reconfigure the surface with the new size - config.width = size.width; - config.height = size.height; - surface.configure(&device, &config); - - // Update the renderer's internal viewport - renderer.resize(uvec2(size.width, size.height)); - - // On macos the window needs to be redrawn manually after resizing - window.request_redraw(); - } - _ => scene_ctrl.interact(event, &renderer.camera), - }, - Event::AboutToWait => { - // RedrawRequested will only trigger once, unless we manually - // request it. - window.request_redraw(); - } - _ => {} - }) - .expect("Error in event loop") -} - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Cli { - #[arg(help = "Path to the .inp or .inx file.")] - inp_path: PathBuf, -} - -fn main() { - let cli = Cli::parse(); - - let data = fs::read(cli.inp_path).unwrap(); - let model = parse_inp(data.as_slice()).unwrap(); - - pollster::block_on(run(model)); -} diff --git a/inox2d-wgpu/Cargo.toml b/inox2d-wgpu/Cargo.toml deleted file mode 100644 index c591780..0000000 --- a/inox2d-wgpu/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "inox2d-wgpu" -description = "WGPU renderer for Inox2D" -authors = ["carbonatiuman"] -version = "0.3.0" -edition = "2021" -repository = "https://github.com/Inochi2D/inox2d" -license = "BSD-2-Clause" -keywords = ["gamedev", "graphics", "inochi2d", "vtuber", "wgpu"] -categories = ["graphics", "rendering"] - -[dependencies] -inox2d = { path = "../inox2d", version = "0.3.0" } -bytemuck = "1.13.1" -encase = { version = "0.7.0", features = ["glam"] } -glam = { version = "0.25.0", features = ["bytemuck"] } -thiserror = "1.0.39" -tracing = "0.1.37" -wgpu = { version = "0.19.1", features = ["webgl"] } diff --git a/inox2d-wgpu/src/buffers.rs b/inox2d-wgpu/src/buffers.rs deleted file mode 100644 index 21610a9..0000000 --- a/inox2d-wgpu/src/buffers.rs +++ /dev/null @@ -1,68 +0,0 @@ -use std::collections::HashMap; - -use wgpu::{util::DeviceExt, Buffer, BufferDescriptor, BufferUsages, Device}; - -use inox2d::{node::InoxNodeUuid, puppet::Puppet}; - -pub struct InoxBuffers { - pub uniform_buffer: Buffer, - pub uniform_index_map: HashMap, - - pub vertex_buffer: Buffer, - pub uv_buffer: Buffer, - pub deform_buffer: Buffer, - pub index_buffer: Buffer, -} - -pub fn buffers_for_puppet(device: &Device, puppet: &Puppet, uniform_alignment_needed: usize) -> InoxBuffers { - let mut uniform_index_map: HashMap = HashMap::new(); - - for (i, node) in (puppet.nodes.arena.iter()) - .map(|arena_node| arena_node.get()) - .filter(|node| node.is_part() || node.is_composite()) - .enumerate() - { - uniform_index_map.insert(node.uuid, i); - } - - let uniform_buffer = device.create_buffer(&BufferDescriptor { - label: Some("inox2d uniform buffer"), - size: (uniform_alignment_needed * uniform_index_map.len()) as u64, - usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST, - mapped_at_creation: false, - }); - - let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("vertex buffer"), - contents: bytemuck::cast_slice(&puppet.render_ctx.vertex_buffers.verts), - usage: wgpu::BufferUsages::VERTEX, - }); - - let uv_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("uv buffer"), - contents: bytemuck::cast_slice(&puppet.render_ctx.vertex_buffers.uvs), - usage: wgpu::BufferUsages::VERTEX, - }); - - let deform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("deform buffer"), - contents: bytemuck::cast_slice(&puppet.render_ctx.vertex_buffers.deforms), - usage: wgpu::BufferUsages::VERTEX | BufferUsages::COPY_DST, - }); - - let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("index buffer"), - contents: bytemuck::cast_slice(&puppet.render_ctx.vertex_buffers.indices), - usage: wgpu::BufferUsages::INDEX, - }); - - InoxBuffers { - uniform_buffer, - uniform_index_map, - - vertex_buffer, - uv_buffer, - deform_buffer, - index_buffer, - } -} diff --git a/inox2d-wgpu/src/lib.rs b/inox2d-wgpu/src/lib.rs deleted file mode 100644 index 9776733..0000000 --- a/inox2d-wgpu/src/lib.rs +++ /dev/null @@ -1,442 +0,0 @@ -#![allow(dead_code)] - -mod buffers; -mod node_bundle; -mod pipeline; - -use inox2d::math::camera::Camera; -use inox2d::model::Model; -use inox2d::node::data::{InoxData, MaskMode}; -use inox2d::puppet::Puppet; -use inox2d::render::RenderCtxKind; - -use encase::ShaderType; -use glam::{vec3, Mat4, UVec2, Vec2, Vec3}; -use inox2d::texture::decode_model_textures; -use tracing::warn; -use wgpu::util::TextureDataOrder; -use wgpu::{util::DeviceExt, *}; - -use self::node_bundle::{CompositeData, PartData}; -use self::{ - buffers::buffers_for_puppet, - node_bundle::{node_bundles_for_model, NodeBundle}, - pipeline::{InoxPipeline, Uniform}, -}; - -pub struct Renderer { - setup: InoxPipeline, - model_texture_binds: Vec, - buffers: buffers::InoxBuffers, - bundles: Vec, - pub camera: Camera, - - viewport: UVec2, - // Cached, must change when viewport does - composite_texture: Option, - mask_texture: Option, -} - -impl Renderer { - pub fn new(device: &Device, queue: &Queue, texture_format: TextureFormat, model: &Model, viewport: UVec2) -> Self { - let setup = InoxPipeline::create(device, texture_format); - - let mut model_texture_binds = Vec::new(); - - let sampler = device.create_sampler(&SamplerDescriptor { - min_filter: FilterMode::Linear, - mag_filter: FilterMode::Linear, - mipmap_filter: FilterMode::Linear, - address_mode_u: AddressMode::ClampToBorder, - address_mode_v: AddressMode::ClampToBorder, - border_color: Some(SamplerBorderColor::TransparentBlack), - ..SamplerDescriptor::default() - }); - - let shalltexs = decode_model_textures(model.textures.iter()); - for shalltex in &shalltexs { - let texture_size = wgpu::Extent3d { - width: shalltex.width(), - height: shalltex.height(), - depth_or_array_layers: 1, - }; - - let texture = device.create_texture_with_data( - queue, - &wgpu::TextureDescriptor { - size: texture_size, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8Unorm, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - label: Some("texture"), - view_formats: &[], - }, - TextureDataOrder::LayerMajor, - shalltex.pixels(), - ); - - let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); - - let texture_bind = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &setup.texture_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&texture_view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&sampler), - }, - ], - label: Some("texture bind group"), - }); - model_texture_binds.push(texture_bind); - } - - let buffers = buffers_for_puppet(device, &model.puppet, setup.uniform_alignment_needed); - let bundles = node_bundles_for_model(device, &setup, &buffers, &model_texture_binds, &model.puppet); - - Self { - setup, - buffers, - bundles, - - model_texture_binds, - camera: Camera::default(), - - viewport, - composite_texture: None, - mask_texture: None, - } - } - - pub fn resize(&mut self, viewport: UVec2) { - self.viewport = viewport; - self.composite_texture = None; - self.mask_texture = None; - } - - #[allow(clippy::too_many_arguments)] - fn render_part( - &self, - puppet: &Puppet, - - view: &TextureView, - mask_view: &TextureView, - uniform_group: &BindGroup, - - op: LoadOp, - encoder: &mut CommandEncoder, - - PartData(bundle, masks): &PartData, - ) { - let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("Part Render Pass"), - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view, - resolve_target: None, - ops: wgpu::Operations { - load: op, - store: StoreOp::Store, - }, - })], - depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { - view: mask_view, - depth_ops: None, - stencil_ops: Some(Operations { - load: wgpu::LoadOp::Clear(u32::from(!masks.is_empty())), - store: StoreOp::Store, - }), - }), - timestamp_writes: None, // todo!(), - occlusion_query_set: None, // todo!(), - }); - - render_pass.set_vertex_buffer(0, self.buffers.vertex_buffer.slice(..)); - render_pass.set_vertex_buffer(1, self.buffers.uv_buffer.slice(..)); - render_pass.set_vertex_buffer(2, self.buffers.deform_buffer.slice(..)); - render_pass.set_index_buffer(self.buffers.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - render_pass.set_pipeline(&self.setup.mask_pipeline); - - for mask in masks { - let node = puppet.nodes.get_node(mask.source).unwrap(); - let part = if let InoxData::Part(part) = &node.data { - part - } else { - todo!() - }; - - render_pass.set_bind_group(1, &self.model_texture_binds[part.tex_albedo.raw()], &[]); - render_pass.set_bind_group(2, &self.model_texture_binds[part.tex_emissive.raw()], &[]); - render_pass.set_bind_group(3, &self.model_texture_binds[part.tex_bumpmap.raw()], &[]); - - render_pass.set_bind_group( - 0, - uniform_group, - &[(self.setup.uniform_alignment_needed * self.buffers.uniform_index_map[&mask.source]) as u32], - ); - - match mask.mode { - MaskMode::Mask => { - render_pass.set_stencil_reference(0); - } - MaskMode::Dodge => { - render_pass.set_stencil_reference(1); - } - } - - let node_rinf = &puppet.render_ctx.node_render_ctxs[&mask.source]; - if let RenderCtxKind::Part(pinf) = &node_rinf.kind { - let range = (pinf.index_offset as u32)..(pinf.index_offset as u32 + pinf.index_len as u32); - render_pass.draw_indexed(range, 0, 0..1); - } else { - warn!( - "Node mask {:?} is not a part but is trying to get rendered as one", - mask.source - ); - } - } - - render_pass.set_stencil_reference(0); - render_pass.execute_bundles(std::iter::once(bundle)); - - drop(render_pass); - } - - #[allow(clippy::too_many_arguments)] - fn render_composite( - &self, - puppet: &Puppet, - - view: &TextureView, - mask_view: &TextureView, - uniform_group: &BindGroup, - - op: LoadOp, - encoder: &mut CommandEncoder, - - composite_view: &TextureView, - composite_bind: &BindGroup, - CompositeData(parts, uuid): &CompositeData, - ) { - for (i, data) in parts.iter().enumerate() { - self.render_part( - puppet, - composite_view, - mask_view, - uniform_group, - if i == 0 { - LoadOp::Clear(Color::TRANSPARENT) - } else { - LoadOp::Load - }, - encoder, - data, - ); - } - - let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("Render Pass"), - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view, - resolve_target: None, - ops: wgpu::Operations { - load: op, - store: StoreOp::Store, - }, - })], - depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { - view: mask_view, - depth_ops: None, - stencil_ops: None, - }), - timestamp_writes: None, // todo!(), - occlusion_query_set: None, //todo!(), - }); - - render_pass.set_vertex_buffer(0, self.buffers.vertex_buffer.slice(..)); - render_pass.set_vertex_buffer(1, self.buffers.uv_buffer.slice(..)); - render_pass.set_vertex_buffer(2, self.buffers.deform_buffer.slice(..)); - render_pass.set_index_buffer(self.buffers.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - - let child = puppet.nodes.get_node(*uuid).unwrap(); - let child = if let InoxData::Composite(comp) = &child.data { - comp - } else { - todo!() - }; - - render_pass.set_pipeline(&self.setup.composite_pipelines[&child.draw_state.blend_mode]); - - render_pass.set_bind_group( - 0, - uniform_group, - &[(self.setup.uniform_alignment_needed * self.buffers.uniform_index_map[uuid]) as u32], - ); - render_pass.set_bind_group(1, composite_bind, &[]); - render_pass.set_bind_group(2, composite_bind, &[]); - render_pass.set_bind_group(3, composite_bind, &[]); - render_pass.draw_indexed(0..6, 0, 0..1); - - drop(render_pass); - } - - /// It is a logical error to pass in a different puppet than the one passed to create. - pub fn render(&mut self, queue: &Queue, device: &Device, puppet: &Puppet, view: &TextureView) { - let uniform_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("inox2d uniform bind group"), - layout: &self.setup.uniform_layout, - entries: &[wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding { - buffer: &self.buffers.uniform_buffer, - offset: 0, - size: wgpu::BufferSize::new(Uniform::min_size().into()), - }), - }], - }); - - let composite_texture = self.composite_texture.get_or_insert_with(|| { - device.create_texture(&wgpu::TextureDescriptor { - size: wgpu::Extent3d { - width: self.viewport.x, - height: self.viewport.y, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Bgra8Unorm, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT, - label: Some("texture"), - view_formats: &[], - }) - }); - - let composite_view = composite_texture.create_view(&wgpu::TextureViewDescriptor::default()); - - let mask_texture = self.mask_texture.get_or_insert_with(|| { - device.create_texture(&wgpu::TextureDescriptor { - size: wgpu::Extent3d { - width: self.viewport.x, - height: self.viewport.y, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Depth24PlusStencil8, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT, - label: Some("texture"), - view_formats: &[], - }) - }); - - let mask_view = mask_texture.create_view(&wgpu::TextureViewDescriptor::default()); - - let sampler = device.create_sampler(&SamplerDescriptor { - min_filter: FilterMode::Linear, - mag_filter: FilterMode::Linear, - mipmap_filter: FilterMode::Linear, - address_mode_u: AddressMode::ClampToBorder, - address_mode_v: AddressMode::ClampToBorder, - border_color: Some(SamplerBorderColor::TransparentBlack), - ..SamplerDescriptor::default() - }); - - let composite_bind = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &self.setup.texture_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&composite_view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&sampler), - }, - ], - label: Some("texture bind group"), - }); - - for uuid in puppet.nodes.all_node_ids() { - let node = puppet.nodes.get_node(uuid).unwrap(); - - let unif = match &node.data { - InoxData::Part(_) => { - let mvp = Mat4::from_scale(vec3(1.0, 1.0, 0.0)) - * self.camera.matrix(self.viewport.as_vec2()) - * puppet.render_ctx.node_render_ctxs[&uuid].trans; - - Uniform { - opacity: 1.0, - mult_color: Vec3::ONE, - screen_color: Vec3::ZERO, - emission_strength: 0.0, - offset: Vec2::ZERO, - mvp, - } - } - InoxData::Composite(_) => Uniform { - opacity: 1.0, - mult_color: Vec3::ONE, - screen_color: Vec3::ZERO, - emission_strength: 0.0, - offset: Vec2::ZERO, - mvp: Mat4::IDENTITY, - }, - _ => continue, - }; - - let offset = self.setup.uniform_alignment_needed * self.buffers.uniform_index_map[&uuid]; - - let mut buffer = encase::UniformBuffer::new(Vec::new()); - buffer.write(&unif).unwrap(); - queue.write_buffer(&self.buffers.uniform_buffer, offset as u64, buffer.as_ref()); - } - - // Upload deform buffers - let mut buffer = encase::DynamicStorageBuffer::new(Vec::new()); - (buffer.write(&puppet.render_ctx.vertex_buffers.deforms)).unwrap(); - queue.write_buffer(&self.buffers.deform_buffer, 0, buffer.as_ref()); - - let mut first = true; - - let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: Some("Part Render Encoder"), - }); - - for bundle in &self.bundles { - let op = if first { - first = false; - - wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT) - } else { - wgpu::LoadOp::Load - }; - - match bundle { - NodeBundle::Part(data) => { - self.render_part(puppet, view, &mask_view, &uniform_group, op, &mut encoder, data); - } - NodeBundle::Composite(data) => { - self.render_composite( - puppet, - view, - &mask_view, - &uniform_group, - op, - &mut encoder, - &composite_view, - &composite_bind, - data, - ); - } - } - } - queue.submit(std::iter::once(encoder.finish())); - } -} diff --git a/inox2d-wgpu/src/node_bundle.rs b/inox2d-wgpu/src/node_bundle.rs deleted file mode 100644 index 0c46d2b..0000000 --- a/inox2d-wgpu/src/node_bundle.rs +++ /dev/null @@ -1,166 +0,0 @@ -use encase::ShaderType; -use tracing::warn; -use wgpu::{BindGroup, Device, RenderBundle}; - -use inox2d::{ - node::{ - data::{InoxData, Mask, Part}, - InoxNodeUuid, - }, - puppet::Puppet, - render::RenderCtxKind, -}; - -use super::{ - buffers::InoxBuffers, - pipeline::{InoxPipeline, Uniform}, -}; - -#[derive(Debug)] -pub struct PartData(pub RenderBundle, pub Vec); - -#[derive(Debug)] -pub struct CompositeData(pub Vec, pub InoxNodeUuid); - -#[derive(Debug)] -pub enum NodeBundle { - Part(PartData), - Composite(CompositeData), -} - -#[allow(clippy::too_many_arguments)] -fn part_bundle_for_part( - device: &Device, - setup: &InoxPipeline, - buffers: &InoxBuffers, - model_texture_binds: &[BindGroup], - uniform_group: &BindGroup, - - uuid: InoxNodeUuid, - part: &Part, - puppet: &Puppet, -) -> PartData { - let mut encoder = device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { - label: Some(&format!("part encoder: {:?}", uuid)), - color_formats: &[Some(setup.texture_format)], - depth_stencil: Some(wgpu::RenderBundleDepthStencil { - format: wgpu::TextureFormat::Depth24PlusStencil8, - depth_read_only: true, - stencil_read_only: false, - }), - sample_count: 1, - ..Default::default() - }); - - encoder.set_vertex_buffer(0, buffers.vertex_buffer.slice(..)); - encoder.set_vertex_buffer(1, buffers.uv_buffer.slice(..)); - encoder.set_vertex_buffer(2, buffers.deform_buffer.slice(..)); - encoder.set_index_buffer(buffers.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - - encoder.set_pipeline(&setup.basic_pipelines[&part.draw_state.blend_mode]); - - encoder.set_bind_group( - 0, - uniform_group, - &[(setup.uniform_alignment_needed * buffers.uniform_index_map[&uuid]) as u32], - ); - encoder.set_bind_group(1, &model_texture_binds[part.tex_albedo.raw()], &[]); - encoder.set_bind_group(2, &model_texture_binds[part.tex_emissive.raw()], &[]); - encoder.set_bind_group(3, &model_texture_binds[part.tex_bumpmap.raw()], &[]); - - let node_rinf = &puppet.render_ctx.node_render_ctxs[&uuid]; - if let RenderCtxKind::Part(pinf) = &node_rinf.kind { - let range = (pinf.index_offset as u32)..(pinf.index_offset as u32 + pinf.index_len as u32); - encoder.draw_indexed(range, 0, 0..1); - } else { - warn!("Node {:?} is not a part but is trying to get rendered as one", uuid); - } - - let bundle = encoder.finish(&wgpu::RenderBundleDescriptor { - label: Some(&format!("part bundle: {:?}", uuid)), - }); - - PartData(bundle, part.draw_state.masks.clone()) -} - -pub fn node_bundles_for_model( - device: &Device, - setup: &InoxPipeline, - buffers: &InoxBuffers, - model_texture_binds: &[BindGroup], - - puppet: &Puppet, -) -> Vec { - let uniform_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("inox2d uniform bind group"), - layout: &setup.uniform_layout, - entries: &[wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding { - buffer: &buffers.uniform_buffer, - offset: 0, - size: wgpu::BufferSize::new(Uniform::min_size().get()), - }), - }], - }); - - let mut out = Vec::new(); - - for uuid in puppet.nodes.zsorted_root() { - let node = puppet.nodes.get_node(uuid).unwrap(); - - if let InoxData::Part(part) = &node.data { - out.push(NodeBundle::Part(part_bundle_for_part( - device, - setup, - buffers, - model_texture_binds, - &uniform_group, - uuid, - part, - puppet, - ))); - } else if let InoxData::Composite(_) = &node.data { - let mut encoder = device.create_render_bundle_encoder(&wgpu::RenderBundleEncoderDescriptor { - label: Some(&format!("composite children encoder: {:?}", uuid)), - color_formats: &[Some(setup.texture_format)], - depth_stencil: Some(wgpu::RenderBundleDepthStencil { - format: wgpu::TextureFormat::Depth24PlusStencil8, - depth_read_only: true, - stencil_read_only: false, - }), - sample_count: 1, - ..Default::default() - }); - - encoder.set_vertex_buffer(0, buffers.vertex_buffer.slice(..)); - encoder.set_vertex_buffer(1, buffers.uv_buffer.slice(..)); - encoder.set_vertex_buffer(2, buffers.deform_buffer.slice(..)); - encoder.set_index_buffer(buffers.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - - let mut bundles = Vec::new(); - - for child_id in puppet.nodes.zsorted_children(uuid) { - let child = puppet.nodes.get_node(child_id).unwrap(); - - if let InoxData::Part(part) = &child.data { - let bundle = part_bundle_for_part( - device, - setup, - buffers, - model_texture_binds, - &uniform_group, - child_id, - part, - puppet, - ); - bundles.push(bundle); - } - } - - out.push(NodeBundle::Composite(CompositeData(bundles, uuid))); - } - } - - out -} diff --git a/inox2d-wgpu/src/pipeline.rs b/inox2d-wgpu/src/pipeline.rs deleted file mode 100644 index 0c46e29..0000000 --- a/inox2d-wgpu/src/pipeline.rs +++ /dev/null @@ -1,325 +0,0 @@ -use std::collections::HashMap; - -use encase::ShaderType; -use glam::{Mat4, Vec2, Vec3}; -use wgpu::*; - -use inox2d::node::data::BlendMode; - -fn blend_state_for_blend_mode(mode: BlendMode) -> BlendState { - let component = match mode { - BlendMode::Normal => BlendComponent { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - BlendMode::Multiply => BlendComponent { - src_factor: BlendFactor::Dst, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - BlendMode::ColorDodge => BlendComponent { - src_factor: BlendFactor::Dst, - dst_factor: BlendFactor::One, - operation: BlendOperation::Add, - }, - BlendMode::LinearDodge => BlendComponent { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::One, - operation: BlendOperation::Add, - }, - BlendMode::Screen => BlendComponent { - src_factor: BlendFactor::One, - dst_factor: BlendFactor::OneMinusSrc, - operation: BlendOperation::Add, - }, - BlendMode::ClipToLower => BlendComponent { - src_factor: BlendFactor::DstAlpha, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Add, - }, - BlendMode::SliceFromLower => BlendComponent { - src_factor: BlendFactor::DstAlpha, - dst_factor: BlendFactor::OneMinusSrcAlpha, - operation: BlendOperation::Subtract, - }, - }; - - BlendState { - color: component, - alpha: component, - } -} - -#[allow(clippy::too_many_arguments)] -fn create_part_pipeline( - device: &Device, - label: Label<'_>, - layout: &PipelineLayout, - texture_format: TextureFormat, - fragment: &ShaderModule, - vertex: &ShaderModule, - composite: bool, - blend: BlendState, -) -> RenderPipeline { - let face_state = StencilFaceState { - compare: if composite { - CompareFunction::Always - } else { - CompareFunction::Equal - }, - ..StencilFaceState::default() - }; - device.create_render_pipeline(&RenderPipelineDescriptor { - label, - layout: Some(layout), - fragment: Some(FragmentState { - module: fragment, - entry_point: "fs_main", - targets: &[Some(ColorTargetState { - format: texture_format, - blend: Some(blend), - write_mask: ColorWrites::ALL, - })], - }), - vertex: VertexState { - module: vertex, - entry_point: "vs_main", - buffers: &[ - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![0 => Float32x2], - }, - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![1 => Float32x2], - }, - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![2 => Float32x2], - }, - ], - }, - primitive: PrimitiveState { - cull_mode: None, - ..PrimitiveState::default() - }, - depth_stencil: Some(DepthStencilState { - format: TextureFormat::Depth24PlusStencil8, - depth_write_enabled: false, - depth_compare: CompareFunction::Always, - stencil: StencilState { - front: face_state, - back: face_state, - read_mask: 0xff, - write_mask: if composite { 0 } else { 0xff }, - }, - bias: DepthBiasState::default(), - }), - multisample: MultisampleState::default(), - multiview: None, - }) -} - -fn create_stencil_pipeline( - device: &Device, - label: Label<'_>, - layout: &PipelineLayout, - texture_format: TextureFormat, - fragment: &ShaderModule, - vertex: &ShaderModule, -) -> RenderPipeline { - let face_state = StencilFaceState { - compare: CompareFunction::Always, - fail_op: StencilOperation::Keep, - depth_fail_op: StencilOperation::Keep, - pass_op: StencilOperation::Replace, - }; - - device.create_render_pipeline(&RenderPipelineDescriptor { - label, - layout: Some(layout), - fragment: Some(FragmentState { - module: fragment, - entry_point: "fs_main", - targets: &[Some(ColorTargetState { - format: texture_format, - blend: Some(BlendState::PREMULTIPLIED_ALPHA_BLENDING), - write_mask: ColorWrites::empty(), - })], - }), - vertex: VertexState { - module: vertex, - entry_point: "vs_main", - buffers: &[ - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![0 => Float32x2], - }, - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![1 => Float32x2], - }, - wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![2 => Float32x2], - }, - ], - }, - primitive: PrimitiveState { - cull_mode: None, - ..PrimitiveState::default() - }, - depth_stencil: Some(DepthStencilState { - format: TextureFormat::Depth24PlusStencil8, - depth_write_enabled: false, - depth_compare: CompareFunction::Always, - stencil: StencilState { - front: face_state, - back: face_state, - read_mask: 0xff, - write_mask: 0xff, - }, - bias: DepthBiasState::default(), - }), - multisample: MultisampleState::default(), - multiview: None, - }) -} - -#[derive(Debug)] -pub struct InoxPipeline { - pub basic_pipelines: HashMap, - pub composite_pipelines: HashMap, - pub mask_pipeline: RenderPipeline, - - pub uniform_layout: BindGroupLayout, - pub texture_layout: BindGroupLayout, - pub texture_format: TextureFormat, - pub uniform_alignment_needed: usize, -} - -impl InoxPipeline { - pub fn create(device: &Device, texture_format: TextureFormat) -> Self { - let uniform_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("inox2d uniform bind group layout"), - entries: &[BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::VERTEX_FRAGMENT, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: true, - min_binding_size: BufferSize::new(Uniform::min_size().get()), - }, - count: None, - }], - }); - - let texture_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("inox2d texture bind group layout"), - entries: &[ - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Texture { - multisampled: false, - sample_type: TextureSampleType::Float { filterable: true }, - view_dimension: TextureViewDimension::D2, - }, - count: None, - }, - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Sampler(SamplerBindingType::Filtering), - count: None, - }, - ], - }); - - let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor { - label: Some("inox2d basic pipeline layout"), - bind_group_layouts: &[&uniform_layout, &texture_layout, &texture_layout, &texture_layout], - push_constant_ranges: &[], - }); - - let mask_pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor { - label: Some("inox2d mask pipeline layout"), - bind_group_layouts: &[&uniform_layout, &texture_layout], - push_constant_ranges: &[], - }); - - // for (mode, state) in get - - let mut basic_pipelines: HashMap = HashMap::new(); - for mode in BlendMode::VALUES { - let basic_pipeline = create_part_pipeline( - device, - Some("inox2d basic pipeline"), - &pipeline_layout, - texture_format, - &device.create_shader_module(include_wgsl!("shaders/basic/basic.frag.wgsl")), - &device.create_shader_module(include_wgsl!("shaders/basic/basic.vert.wgsl")), - false, - blend_state_for_blend_mode(mode), - ); - - basic_pipelines.insert(mode, basic_pipeline); - } - - let mut composite_pipelines: HashMap = HashMap::new(); - for mode in BlendMode::VALUES { - let composite_pipeline = create_part_pipeline( - device, - Some("inox2d composite pipeline"), - &pipeline_layout, - texture_format, - &device.create_shader_module(include_wgsl!("shaders/basic/composite.frag.wgsl")), - &device.create_shader_module(include_wgsl!("shaders/basic/composite.vert.wgsl")), - true, - blend_state_for_blend_mode(mode), - ); - - composite_pipelines.insert(mode, composite_pipeline); - } - - let mask_pipeline = create_stencil_pipeline( - device, - Some("inox2d mask pipeline"), - &mask_pipeline_layout, - texture_format, - &device.create_shader_module(include_wgsl!("shaders/basic/mask.frag.wgsl")), - &device.create_shader_module(include_wgsl!("shaders/basic/mask.vert.wgsl")), - ); - - let min_uniform_buffer_offset_alignment = device.limits().min_uniform_buffer_offset_alignment; - - InoxPipeline { - basic_pipelines, - composite_pipelines, - mask_pipeline, - - uniform_layout, - texture_layout, - texture_format, - uniform_alignment_needed: (Uniform::min_size().get()).max(min_uniform_buffer_offset_alignment.into()) - as usize, - } - } -} - -#[derive(ShaderType, Debug, Clone, Copy, PartialEq)] -pub struct Uniform { - pub opacity: f32, - pub mult_color: Vec3, - pub screen_color: Vec3, - pub emission_strength: f32, - pub offset: Vec2, - pub mvp: Mat4, -} diff --git a/inox2d-wgpu/src/shaders/basic/anim.vert.wgsl b/inox2d-wgpu/src/shaders/basic/anim.vert.wgsl deleted file mode 100644 index 8274115..0000000 --- a/inox2d-wgpu/src/shaders/basic/anim.vert.wgsl +++ /dev/null @@ -1,27 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct Uniform { - offset: vec2, - splits: vec2, - animation: f32, - frame: f32, -}; - -@group(0) @binding(1) -var unif: Uniform; - -@vertex -fn vs_main( - @location(0) verts: vec2, - @location(1) uvs: vec2, - @location(2) deform: vec2, -) -> VertexOutput { - var out: VertexOutput; - out.position = unif.mvp * vec4(verts.x - unif.offset.x + deform.x, - verts.y - unif.offset.y + deform.y, 0.0, 1.0); - out.texUVs = vec2((uvs.x / unif.splits.x) * unif.frame, (uvs.y / unif.splits.y) * unif.animation); - return out; -} diff --git a/inox2d-wgpu/src/shaders/basic/basic-mask.frag.wgsl b/inox2d-wgpu/src/shaders/basic/basic-mask.frag.wgsl deleted file mode 100644 index 12a2248..0000000 --- a/inox2d-wgpu/src/shaders/basic/basic-mask.frag.wgsl +++ /dev/null @@ -1,26 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct Uniform { - tex: mat4x4, - threshold: f32, -}; - -@group(0) @binding(0) -var unif: Uniform; - -@group(1) @binding(0) -var tex : texture_2d; -@group(1) @binding(1) -var samp : sampler; - -@fragment -fn fs_main(in: VertexOutput) -> @location(0) vec4 { - let color = textureSample(tex, samp, in.texUVs); - if (color.a <= unif.threshold) { - discard; - } - return vec4(1.0, 1.0, 1.0, 1.0); -} diff --git a/inox2d-wgpu/src/shaders/basic/basic.frag.wgsl b/inox2d-wgpu/src/shaders/basic/basic.frag.wgsl deleted file mode 100644 index 16be667..0000000 --- a/inox2d-wgpu/src/shaders/basic/basic.frag.wgsl +++ /dev/null @@ -1,60 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct FragmentOutput { - @location(0) albedo: vec4, - @location(1) emissive: vec4, - @location(2) bump: vec4, -}; - -struct Uniform { - opacity: f32, - multColor: vec3, - screenColor: vec3, - emissionStrength: f32, - offset: vec2, - mvp: mat4x4, -}; - -@group(0) @binding(1) -var unif: Uniform; - -@group(1) @binding(0) -var albedo : texture_2d; -@group(1) @binding(1) -var albedoSamp : sampler; - -@group(2) @binding(0) -var emissive : texture_2d; -@group(2) @binding(1) -var emissiveSamp : sampler; - -@group(3) @binding(0) -var bump : texture_2d; -@group(3) @binding(1) -var bumpSamp : sampler; - -@fragment -fn fs_main(in: VertexOutput) -> FragmentOutput { - var out: FragmentOutput; - - // Sample texture - let texColor = textureSample(albedo, albedoSamp, in.texUVs); - - // Screen color math - let screenOut = vec3(1.0) - ((vec3(1.0) - (texColor.xyz)) * - (vec3(1.0) - (unif.screenColor * texColor.a))); - - // Multiply color math + opacity application. - out.albedo = vec4(screenOut.xyz, texColor.a) * vec4(unif.multColor.xyz, 1.0) * unif.opacity; - - // Emissive - out.emissive = vec4(textureSample(emissive, emissiveSamp, in.texUVs).xyz * unif.emissionStrength, 1.0) * out.albedo.a; - - // Bumpmap - out.bump = vec4(textureSample(bump, bumpSamp, in.texUVs).xyz, 1.0) * out.albedo.a; - - return out; -} diff --git a/inox2d-wgpu/src/shaders/basic/basic.vert.wgsl b/inox2d-wgpu/src/shaders/basic/basic.vert.wgsl deleted file mode 100644 index b3bab3e..0000000 --- a/inox2d-wgpu/src/shaders/basic/basic.vert.wgsl +++ /dev/null @@ -1,30 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct Uniform { - opacity: f32, - multColor: vec3, - screenColor: vec3, - emissionStrength: f32, - offset: vec2, - mvp: mat4x4, -}; - -@group(0) @binding(1) -var unif: Uniform; - -@vertex -fn vs_main( - @location(0) verts: vec2, - @location(1) uvs: vec2, - @location(2) deform: vec2, -) -> VertexOutput { - var out: VertexOutput; - - out.position = unif.mvp * vec4(verts + deform - unif.offset, 0.0, 1.0); - - out.texUVs = uvs; - return out; -} diff --git a/inox2d-wgpu/src/shaders/basic/composite-mask.frag.wgsl b/inox2d-wgpu/src/shaders/basic/composite-mask.frag.wgsl deleted file mode 100644 index cf59de8..0000000 --- a/inox2d-wgpu/src/shaders/basic/composite-mask.frag.wgsl +++ /dev/null @@ -1,27 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct Uniform { - tex: mat4x4, - threshold: f32, - opacity: f32, -}; - -@group(0) @binding(0) -var unif: Uniform; - -@group(1) @binding(0) -var tex : texture_2d; -@group(1) @binding(1) -var samp : sampler; - -@fragment -fn fs_main(in: VertexOutput) -> @location(0) vec4 { - let color = textureSample(tex, samp, in.texUVs) * vec4(1.0, 1.0, 1.0, unif.opacity); - if (color.a <= unif.threshold) { - discard; - } - return vec4(1.0, 1.0, 1.0, 1.0); -} diff --git a/inox2d-wgpu/src/shaders/basic/composite.frag.wgsl b/inox2d-wgpu/src/shaders/basic/composite.frag.wgsl deleted file mode 100644 index d6b4a93..0000000 --- a/inox2d-wgpu/src/shaders/basic/composite.frag.wgsl +++ /dev/null @@ -1,57 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct FragmentOutput { - @location(0) albedo: vec4, - @location(1) emissive: vec4, - @location(2) bump: vec4, -}; - -struct Uniform { - opacity: f32, - multColor: vec3, - screenColor: vec3, -}; - -@group(0) @binding(1) -var unif: Uniform; - -@group(1) @binding(0) -var albedo : texture_2d; -@group(1) @binding(1) -var albedoSamp : sampler; - -@group(2) @binding(0) -var emissive : texture_2d; -@group(2) @binding(1) -var emissiveSamp : sampler; - -@group(3) @binding(0) -var bump : texture_2d; -@group(3) @binding(1) -var bumpSamp : sampler; - -@fragment -fn fs_main(in: VertexOutput) -> FragmentOutput { - var out: FragmentOutput; - - // Sample texture - let texColor = textureSample(albedo, albedoSamp, in.texUVs); - - // Screen color math - let screenOut = vec3(1.0) - ((vec3(1.0) - (texColor.xyz)) * - (vec3(1.0) - (unif.screenColor * texColor.a))); - - // Multiply color math + opacity application. - out.albedo = vec4(screenOut.xyz, texColor.a) * vec4(unif.multColor.xyz, 1.0) * unif.opacity; - - // Emissive - out.emissive = textureSample(emissive, emissiveSamp, in.texUVs) * out.albedo.a; - - // Bumpmap - out.bump = vec4(textureSample(bump, bumpSamp, in.texUVs).xyz, 1.0) * out.albedo.a; - - return out; -} diff --git a/inox2d-wgpu/src/shaders/basic/composite.vert.wgsl b/inox2d-wgpu/src/shaders/basic/composite.vert.wgsl deleted file mode 100644 index 6fdfea4..0000000 --- a/inox2d-wgpu/src/shaders/basic/composite.vert.wgsl +++ /dev/null @@ -1,17 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -@vertex -fn vs_main( - @location(0) verts: vec2, - @location(1) uvs: vec2, -) -> VertexOutput { - var out: VertexOutput; - out.position = vec4(verts, 0.0, 1.0); - out.position.y = -out.position.y; - - out.texUVs = uvs; - return out; -} diff --git a/inox2d-wgpu/src/shaders/basic/mask.frag.wgsl b/inox2d-wgpu/src/shaders/basic/mask.frag.wgsl deleted file mode 100644 index 1765fb5..0000000 --- a/inox2d-wgpu/src/shaders/basic/mask.frag.wgsl +++ /dev/null @@ -1,21 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -@group(1) @binding(0) -var albedo : texture_2d; -@group(1) @binding(1) -var albedoSamp : sampler; - -@fragment -fn fs_main( - in: VertexOutput -) -> @location(0) vec4 { - let texColor = textureSample(albedo, albedoSamp, in.texUVs); - if (texColor.a <= 0.5) { - discard; - } - - return vec4(0.0, 0.0, 0.0, 1.0); -} \ No newline at end of file diff --git a/inox2d-wgpu/src/shaders/basic/mask.vert.wgsl b/inox2d-wgpu/src/shaders/basic/mask.vert.wgsl deleted file mode 100644 index 7b5c39d..0000000 --- a/inox2d-wgpu/src/shaders/basic/mask.vert.wgsl +++ /dev/null @@ -1,28 +0,0 @@ -struct VertexOutput { - @builtin(position) position: vec4, - @location(0) texUVs: vec2, -}; - -struct Uniform { - opacity: f32, - multColor: vec3, - screenColor: vec3, - emissionStrength: f32, - offset: vec2, - mvp: mat4x4, -}; - -@group(0) @binding(1) -var unif: Uniform; - -@vertex -fn vs_main( - @location(0) verts: vec2, - @location(1) uvs: vec2, -) -> VertexOutput { - var out: VertexOutput; - - out.position = unif.mvp * vec4(verts - unif.offset, 0.0, 1.0); - out.texUVs = uvs; - return out; -}