Unify stencil and volume shaders.
This commit is contained in:
parent
95b3a5b298
commit
e86c6d6c60
|
@ -1,14 +0,0 @@
|
|||
#define_import_path bevy_mod_outline::common
|
||||
#import bevy_pbr::mesh_view_bindings
|
||||
#import bevy_pbr::mesh_types
|
||||
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
|
||||
fn model_origin_z(plane: vec3<f32>, view_proj: mat4x4<f32>) -> f32 {
|
||||
var proj_zw = mat4x2<f32>(
|
||||
view_proj[0].zw, view_proj[1].zw,
|
||||
view_proj[2].zw, view_proj[3].zw);
|
||||
var zw = proj_zw * vec4<f32>(plane, 1.0);
|
||||
return zw.x / zw.y;
|
||||
}
|
|
@ -3,7 +3,7 @@ use bevy::prelude::*;
|
|||
/// A component for storing the computed depth at which the outline lies.
|
||||
#[derive(Clone, Component, Default)]
|
||||
pub struct ComputedOutlineDepth {
|
||||
pub(crate) plane: Vec3,
|
||||
pub(crate) origin: Vec3,
|
||||
}
|
||||
|
||||
/// A component which specifies that this entity lies at the same depth as its parent.
|
||||
|
@ -27,7 +27,7 @@ pub(crate) fn compute_outline_depth(
|
|||
for (mut computed, transform, changed_transform, children) in root_query.iter_mut() {
|
||||
if changed_transform {
|
||||
let matrix = transform.compute_matrix();
|
||||
computed.plane = matrix.project_point3(Vec3::ZERO);
|
||||
computed.origin = matrix.project_point3(Vec3::ZERO);
|
||||
}
|
||||
if let Some((cs, changed_children)) = children {
|
||||
let changed2 = changed_children || changed_transform;
|
||||
|
|
11
src/draw.rs
11
src/draw.rs
|
@ -7,7 +7,9 @@ use bevy::render::view::ExtractedView;
|
|||
|
||||
use crate::node::{OpaqueOutline, StencilOutline, TransparentOutline};
|
||||
use crate::pipeline::{OutlinePipeline, PassType};
|
||||
use crate::uniforms::{OutlineFragmentUniform, SetOutlineBindGroup, SetOutlineStencilBindGroup};
|
||||
use crate::uniforms::{
|
||||
OutlineFragmentUniform, SetOutlineStencilBindGroup, SetOutlineVolumeBindGroup,
|
||||
};
|
||||
use crate::view_uniforms::SetOutlineViewBindGroup;
|
||||
use crate::OutlineStencil;
|
||||
|
||||
|
@ -15,7 +17,8 @@ pub type DrawStencil = (
|
|||
SetItemPipeline,
|
||||
SetMeshViewBindGroup<0>,
|
||||
SetMeshBindGroup<1>,
|
||||
SetOutlineStencilBindGroup<2>,
|
||||
SetOutlineViewBindGroup<2>,
|
||||
SetOutlineStencilBindGroup<3>,
|
||||
DrawMesh,
|
||||
);
|
||||
|
||||
|
@ -68,12 +71,12 @@ pub type DrawOutline = (
|
|||
SetMeshViewBindGroup<0>,
|
||||
SetMeshBindGroup<1>,
|
||||
SetOutlineViewBindGroup<2>,
|
||||
SetOutlineBindGroup<3>,
|
||||
SetOutlineVolumeBindGroup<3>,
|
||||
DrawMesh,
|
||||
);
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn queue_outline_mesh(
|
||||
pub fn queue_outline_volume_mesh(
|
||||
opaque_draw_functions: Res<DrawFunctions<OpaqueOutline>>,
|
||||
transparent_draw_functions: Res<DrawFunctions<TransparentOutline>>,
|
||||
outline_pipeline: Res<OutlinePipeline>,
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#ifdef VOLUME
|
||||
|
||||
struct OutlineFragmentUniform {
|
||||
@align(16)
|
||||
colour: vec4<f32>,
|
||||
};
|
||||
|
||||
@group(3) @binding(1)
|
||||
var<uniform> fstage: OutlineFragmentUniform;
|
||||
|
||||
@fragment
|
||||
fn fragment() -> @location(0) vec4<f32> {
|
||||
return fstage.colour;
|
||||
}
|
||||
|
||||
#else
|
||||
// Stencil
|
||||
|
||||
@fragment
|
||||
fn fragment() {
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
35
src/lib.rs
35
src/lib.rs
|
@ -28,15 +28,15 @@ use bevy::render::render_resource::{SpecializedMeshPipelines, VertexFormat};
|
|||
use bevy::render::{RenderApp, RenderStage};
|
||||
use bevy::transform::TransformSystem;
|
||||
|
||||
use crate::draw::{queue_outline_mesh, queue_outline_stencil_mesh, DrawOutline, DrawStencil};
|
||||
use crate::node::{OpaqueOutline, OutlineNode, StencilOutline, TransparentOutline};
|
||||
use crate::pipeline::{
|
||||
OutlinePipeline, COMMON_SHADER_HANDLE, OUTLINE_SHADER_HANDLE, STENCIL_SHADER_HANDLE,
|
||||
use crate::draw::{
|
||||
queue_outline_stencil_mesh, queue_outline_volume_mesh, DrawOutline, DrawStencil,
|
||||
};
|
||||
use crate::node::{OpaqueOutline, OutlineNode, StencilOutline, TransparentOutline};
|
||||
use crate::pipeline::{OutlinePipeline, FRAGMENT_SHADER_HANDLE, OUTLINE_SHADER_HANDLE};
|
||||
use crate::uniforms::{
|
||||
extract_outline_stencil_uniforms, extract_outline_uniforms, queue_outline_bind_group,
|
||||
queue_outline_stencil_bind_group, OutlineFragmentUniform, OutlineStencilUniform,
|
||||
OutlineVertexUniform,
|
||||
extract_outline_stencil_uniforms, extract_outline_volume_uniforms,
|
||||
queue_outline_stencil_bind_group, queue_outline_volume_bind_group, OutlineFragmentUniform,
|
||||
OutlineStencilUniform, OutlineVolumeUniform,
|
||||
};
|
||||
use crate::view_uniforms::{
|
||||
extract_outline_view_uniforms, queue_outline_view_bind_group, OutlineViewUniform,
|
||||
|
@ -109,23 +109,22 @@ pub struct OutlinePlugin;
|
|||
|
||||
impl Plugin for OutlinePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
load_internal_asset!(app, COMMON_SHADER_HANDLE, "common.wgsl", Shader::from_wgsl);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
STENCIL_SHADER_HANDLE,
|
||||
"stencil.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
OUTLINE_SHADER_HANDLE,
|
||||
"outline.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
FRAGMENT_SHADER_HANDLE,
|
||||
"fragment.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
|
||||
app.add_plugin(ExtractComponentPlugin::<OutlineStencil>::extract_visible())
|
||||
.add_plugin(UniformComponentPlugin::<OutlineStencilUniform>::default())
|
||||
.add_plugin(UniformComponentPlugin::<OutlineVertexUniform>::default())
|
||||
.add_plugin(UniformComponentPlugin::<OutlineVolumeUniform>::default())
|
||||
.add_plugin(UniformComponentPlugin::<OutlineFragmentUniform>::default())
|
||||
.add_plugin(UniformComponentPlugin::<OutlineViewUniform>::default())
|
||||
.add_system_to_stage(
|
||||
|
@ -143,7 +142,7 @@ impl Plugin for OutlinePlugin {
|
|||
.add_render_command::<TransparentOutline, DrawOutline>()
|
||||
.add_system_to_stage(RenderStage::Extract, extract_outline_view_uniforms)
|
||||
.add_system_to_stage(RenderStage::Extract, extract_outline_stencil_uniforms)
|
||||
.add_system_to_stage(RenderStage::Extract, extract_outline_uniforms)
|
||||
.add_system_to_stage(RenderStage::Extract, extract_outline_volume_uniforms)
|
||||
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<StencilOutline>)
|
||||
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<OpaqueOutline>)
|
||||
.add_system_to_stage(
|
||||
|
@ -152,9 +151,9 @@ impl Plugin for OutlinePlugin {
|
|||
)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_view_bind_group)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_stencil_bind_group)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_bind_group)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_volume_bind_group)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_stencil_mesh)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_mesh);
|
||||
.add_system_to_stage(RenderStage::Queue, queue_outline_volume_mesh);
|
||||
|
||||
let world = &mut app.sub_app_mut(RenderApp).world;
|
||||
let node = OutlineNode::new(world);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#import bevy_mod_outline::common
|
||||
#import bevy_pbr::mesh_view_bindings
|
||||
#import bevy_pbr::mesh_types
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
#ifndef OFFSET_ZERO
|
||||
@location(1) normal: vec3<f32>,
|
||||
#endif
|
||||
#ifdef SKINNED
|
||||
@location(2) joint_indexes: vec4<u32>,
|
||||
@location(3) joint_weights: vec4<f32>,
|
||||
|
@ -10,22 +13,18 @@ struct VertexInput {
|
|||
};
|
||||
|
||||
struct OutlineViewUniform {
|
||||
#ifdef ALIGN_16
|
||||
@align(16)
|
||||
#endif
|
||||
scale: vec2<f32>,
|
||||
};
|
||||
|
||||
struct OutlineVertexUniform {
|
||||
@align(16)
|
||||
plane: vec3<f32>,
|
||||
width: f32,
|
||||
origin: vec3<f32>,
|
||||
offset: f32,
|
||||
};
|
||||
|
||||
struct OutlineFragmentUniform {
|
||||
@align(16)
|
||||
colour: vec4<f32>,
|
||||
};
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
|
||||
@group(2) @binding(0)
|
||||
var<uniform> view_uniform: OutlineViewUniform;
|
||||
|
@ -33,15 +32,20 @@ var<uniform> view_uniform: OutlineViewUniform;
|
|||
@group(3) @binding(0)
|
||||
var<uniform> vstage: OutlineVertexUniform;
|
||||
|
||||
@group(3) @binding(1)
|
||||
var<uniform> fstage: OutlineFragmentUniform;
|
||||
|
||||
fn mat4to3(m: mat4x4<f32>) -> mat3x3<f32> {
|
||||
return mat3x3<f32>(
|
||||
m[0].xyz, m[1].xyz, m[2].xyz
|
||||
);
|
||||
}
|
||||
|
||||
fn model_origin_z(plane: vec3<f32>, view_proj: mat4x4<f32>) -> f32 {
|
||||
var proj_zw = mat4x2<f32>(
|
||||
view_proj[0].zw, view_proj[1].zw,
|
||||
view_proj[2].zw, view_proj[3].zw);
|
||||
var zw = proj_zw * vec4<f32>(plane, 1.0);
|
||||
return zw.x / zw.y;
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex(vertex: VertexInput) -> @builtin(position) vec4<f32> {
|
||||
#ifdef SKINNED
|
||||
|
@ -49,14 +53,13 @@ fn vertex(vertex: VertexInput) -> @builtin(position) vec4<f32> {
|
|||
#else
|
||||
let model = mesh.model;
|
||||
#endif
|
||||
var clip_pos = view.view_proj * (model * vec4<f32>(vertex.position, 1.0));
|
||||
var clip_norm = mat4to3(view.view_proj) * (mat4to3(model) * vertex.normal);
|
||||
var ndc_pos = clip_pos.xy / clip_pos.w;
|
||||
var ndc_delta = vstage.width * normalize(clip_norm.xy) * view_uniform.scale;
|
||||
return vec4<f32>(ndc_pos + ndc_delta, model_origin_z(vstage.plane, view.view_proj), 1.0);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment() -> @location(0) vec4<f32> {
|
||||
return fstage.colour;
|
||||
let clip_pos = view.view_proj * (model * vec4<f32>(vertex.position, 1.0));
|
||||
let ndc_pos = clip_pos.xy / clip_pos.w;
|
||||
#ifdef OFFSET_ZERO
|
||||
let ndc_delta = vec2<f32>(0.0, 0.0);
|
||||
#else
|
||||
let clip_norm = mat4to3(view.view_proj) * (mat4to3(model) * vertex.normal);
|
||||
let ndc_delta = vstage.offset * normalize(clip_norm.xy) * view_uniform.scale;
|
||||
#endif
|
||||
return vec4<f32>(ndc_pos + ndc_delta, model_origin_z(vstage.origin, view.view_proj), 1.0);
|
||||
}
|
||||
|
|
|
@ -20,19 +20,16 @@ use bevy::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::uniforms::{OutlineFragmentUniform, OutlineStencilUniform, OutlineVertexUniform};
|
||||
use crate::uniforms::{OutlineFragmentUniform, OutlineStencilUniform, OutlineVolumeUniform};
|
||||
use crate::view_uniforms::OutlineViewUniform;
|
||||
use crate::ATTRIBUTE_OUTLINE_NORMAL;
|
||||
|
||||
pub const COMMON_SHADER_HANDLE: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 9448276477068917228);
|
||||
|
||||
pub const STENCIL_SHADER_HANDLE: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 12033806834125368121);
|
||||
|
||||
pub const OUTLINE_SHADER_HANDLE: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 2101625026478770097);
|
||||
|
||||
pub const FRAGMENT_SHADER_HANDLE: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 12033806834125368121);
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum PassType {
|
||||
Stencil,
|
||||
|
@ -44,7 +41,7 @@ pub struct OutlinePipeline {
|
|||
mesh_pipeline: MeshPipeline,
|
||||
pub outline_view_bind_group_layout: BindGroupLayout,
|
||||
pub outline_stencil_bind_group_layout: BindGroupLayout,
|
||||
pub outline_bind_group_layout: BindGroupLayout,
|
||||
pub outline_volume_bind_group_layout: BindGroupLayout,
|
||||
}
|
||||
|
||||
impl FromWorld for OutlinePipeline {
|
||||
|
@ -66,9 +63,9 @@ impl FromWorld for OutlinePipeline {
|
|||
count: None,
|
||||
}],
|
||||
});
|
||||
let outline_bind_group_layout =
|
||||
let outline_volume_bind_group_layout =
|
||||
render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
label: Some("outline_bind_group_layout"),
|
||||
label: Some("outline_volume_bind_group_layout"),
|
||||
entries: &[
|
||||
BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
|
@ -77,7 +74,7 @@ impl FromWorld for OutlinePipeline {
|
|||
ty: BufferBindingType::Uniform,
|
||||
has_dynamic_offset: true,
|
||||
min_binding_size: BufferSize::new(
|
||||
OutlineVertexUniform::SHADER_SIZE.get(),
|
||||
OutlineVolumeUniform::SHADER_SIZE.get(),
|
||||
),
|
||||
},
|
||||
count: None,
|
||||
|
@ -114,7 +111,7 @@ impl FromWorld for OutlinePipeline {
|
|||
mesh_pipeline,
|
||||
outline_view_bind_group_layout,
|
||||
outline_stencil_bind_group_layout,
|
||||
outline_bind_group_layout,
|
||||
outline_volume_bind_group_layout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,12 +127,13 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
|||
let mut targets = vec![];
|
||||
let mut bind_layouts = vec![self.mesh_pipeline.view_layout.clone()];
|
||||
let mut buffer_attrs = vec![Mesh::ATTRIBUTE_POSITION.at_shader_location(0)];
|
||||
let mut shader_defs = vec![];
|
||||
let mut vertex_defs = vec![];
|
||||
let mut fragment_defs = vec![];
|
||||
bind_layouts.push(
|
||||
if mesh_layout.contains(Mesh::ATTRIBUTE_JOINT_INDEX)
|
||||
&& mesh_layout.contains(Mesh::ATTRIBUTE_JOINT_WEIGHT)
|
||||
{
|
||||
shader_defs.push("SKINNED".to_string());
|
||||
vertex_defs.push("SKINNED".to_string());
|
||||
buffer_attrs.push(Mesh::ATTRIBUTE_JOINT_INDEX.at_shader_location(2));
|
||||
buffer_attrs.push(Mesh::ATTRIBUTE_JOINT_WEIGHT.at_shader_location(3));
|
||||
self.mesh_pipeline.skinned_mesh_layout.clone()
|
||||
|
@ -143,14 +141,14 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
|||
self.mesh_pipeline.mesh_layout.clone()
|
||||
},
|
||||
);
|
||||
let shader;
|
||||
bind_layouts.push(self.outline_view_bind_group_layout.clone());
|
||||
match pass_type {
|
||||
PassType::Stencil => {
|
||||
shader = STENCIL_SHADER_HANDLE;
|
||||
vertex_defs.push("OFFSET_ZERO".to_string());
|
||||
bind_layouts.push(self.outline_stencil_bind_group_layout.clone());
|
||||
}
|
||||
PassType::Opaque | PassType::Transparent => {
|
||||
shader = OUTLINE_SHADER_HANDLE;
|
||||
fragment_defs.push("VOLUME".to_string());
|
||||
targets.push(Some(ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
blend: Some(if pass_type == PassType::Transparent {
|
||||
|
@ -161,8 +159,7 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
|||
write_mask: ColorWrites::ALL,
|
||||
}));
|
||||
|
||||
bind_layouts.push(self.outline_view_bind_group_layout.clone());
|
||||
bind_layouts.push(self.outline_bind_group_layout.clone());
|
||||
bind_layouts.push(self.outline_volume_bind_group_layout.clone());
|
||||
buffer_attrs.push(
|
||||
if mesh_layout.contains(ATTRIBUTE_OUTLINE_NORMAL) {
|
||||
ATTRIBUTE_OUTLINE_NORMAL
|
||||
|
@ -176,14 +173,14 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
|||
let buffers = vec![mesh_layout.get_layout(&buffer_attrs)?];
|
||||
Ok(RenderPipelineDescriptor {
|
||||
vertex: VertexState {
|
||||
shader: shader.clone().typed::<Shader>(),
|
||||
shader: OUTLINE_SHADER_HANDLE.typed::<Shader>(),
|
||||
entry_point: "vertex".into(),
|
||||
shader_defs: shader_defs.clone(),
|
||||
shader_defs: vertex_defs,
|
||||
buffers,
|
||||
},
|
||||
fragment: Some(FragmentState {
|
||||
shader: shader.typed::<Shader>(),
|
||||
shader_defs,
|
||||
shader: FRAGMENT_SHADER_HANDLE.typed::<Shader>(),
|
||||
shader_defs: fragment_defs,
|
||||
entry_point: "fragment".into(),
|
||||
targets,
|
||||
}),
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#import bevy_mod_outline::common
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
#ifdef SKINNED
|
||||
@location(2) joint_indexes: vec4<u32>,
|
||||
@location(3) joint_weights: vec4<f32>,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct OutlineStencilUniform {
|
||||
@align(16)
|
||||
plane: vec3<f32>,
|
||||
};
|
||||
|
||||
@group(2) @binding(0)
|
||||
var<uniform> vstage: OutlineStencilUniform;
|
||||
|
||||
@vertex
|
||||
fn vertex(vertex: VertexInput) -> @builtin(position) vec4<f32> {
|
||||
#ifdef SKINNED
|
||||
let model = skin_model(vertex.joint_indexes, vertex.joint_weights);
|
||||
#else
|
||||
let model = mesh.model;
|
||||
#endif
|
||||
var clip_pos = view.view_proj * (model * vec4<f32>(vertex.position, 1.0));
|
||||
var ndc_pos = clip_pos.xy / clip_pos.w;
|
||||
return vec4<f32>(ndc_pos, model_origin_z(vstage.plane, view.view_proj), 1.0);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment() {
|
||||
return;
|
||||
}
|
|
@ -15,18 +15,19 @@ use bevy::{
|
|||
|
||||
use crate::{pipeline::OutlinePipeline, ComputedOutlineDepth, Outline, OutlineStencil};
|
||||
|
||||
#[derive(Clone, Component, ShaderType)]
|
||||
pub struct OutlineStencilUniform {
|
||||
#[align(16)]
|
||||
pub plane: Vec3,
|
||||
macro_rules! outline_vertex_uniform {
|
||||
($x:ident) => {
|
||||
#[derive(Clone, Component, ShaderType)]
|
||||
pub struct $x {
|
||||
#[align(16)]
|
||||
pub origin: Vec3,
|
||||
pub offset: f32,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Component, ShaderType)]
|
||||
pub struct OutlineVertexUniform {
|
||||
#[align(16)]
|
||||
pub plane: Vec3,
|
||||
pub width: f32,
|
||||
}
|
||||
outline_vertex_uniform!(OutlineStencilUniform);
|
||||
outline_vertex_uniform!(OutlineVolumeUniform);
|
||||
|
||||
#[derive(Clone, Component, ShaderType)]
|
||||
pub struct OutlineFragmentUniform {
|
||||
|
@ -38,7 +39,7 @@ pub struct OutlineStencilBindGroup {
|
|||
pub bind_group: BindGroup,
|
||||
}
|
||||
|
||||
pub struct OutlineBindGroup {
|
||||
pub struct OutlineVolumeBindGroup {
|
||||
pub bind_group: BindGroup,
|
||||
}
|
||||
|
||||
|
@ -48,12 +49,13 @@ pub fn extract_outline_stencil_uniforms(
|
|||
) {
|
||||
for (entity, computed) in query.iter() {
|
||||
commands.get_or_spawn(entity).insert(OutlineStencilUniform {
|
||||
plane: computed.plane,
|
||||
origin: computed.origin,
|
||||
offset: 0.0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_outline_uniforms(
|
||||
pub fn extract_outline_volume_uniforms(
|
||||
mut commands: Commands,
|
||||
query: Extract<Query<(Entity, &Outline, &ComputedOutlineDepth)>>,
|
||||
) {
|
||||
|
@ -63,9 +65,9 @@ pub fn extract_outline_uniforms(
|
|||
}
|
||||
commands
|
||||
.get_or_spawn(entity)
|
||||
.insert(OutlineVertexUniform {
|
||||
width: outline.width,
|
||||
plane: computed.plane,
|
||||
.insert(OutlineVolumeUniform {
|
||||
origin: computed.origin,
|
||||
offset: outline.width,
|
||||
})
|
||||
.insert(OutlineFragmentUniform {
|
||||
colour: outline.colour.as_linear_rgba_f32().into(),
|
||||
|
@ -92,11 +94,11 @@ pub fn queue_outline_stencil_bind_group(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn queue_outline_bind_group(
|
||||
pub fn queue_outline_volume_bind_group(
|
||||
mut commands: Commands,
|
||||
render_device: Res<RenderDevice>,
|
||||
outline_pipeline: Res<OutlinePipeline>,
|
||||
vertex: Res<ComponentUniforms<OutlineVertexUniform>>,
|
||||
vertex: Res<ComponentUniforms<OutlineVolumeUniform>>,
|
||||
fragment: Res<ComponentUniforms<OutlineFragmentUniform>>,
|
||||
) {
|
||||
if let (Some(vertex_binding), Some(fragment_binding)) = (vertex.binding(), fragment.binding()) {
|
||||
|
@ -111,10 +113,10 @@ pub fn queue_outline_bind_group(
|
|||
resource: fragment_binding.clone(),
|
||||
},
|
||||
],
|
||||
label: Some("outline_bind_group"),
|
||||
layout: &outline_pipeline.outline_bind_group_layout,
|
||||
label: Some("outline_volume_bind_group"),
|
||||
layout: &outline_pipeline.outline_volume_bind_group_layout,
|
||||
});
|
||||
commands.insert_resource(OutlineBindGroup { bind_group });
|
||||
commands.insert_resource(OutlineVolumeBindGroup { bind_group });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,13 +139,13 @@ impl<const I: usize> EntityRenderCommand for SetOutlineStencilBindGroup<I> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct SetOutlineBindGroup<const I: usize>();
|
||||
pub struct SetOutlineVolumeBindGroup<const I: usize>();
|
||||
|
||||
impl<const I: usize> EntityRenderCommand for SetOutlineBindGroup<I> {
|
||||
impl<const I: usize> EntityRenderCommand for SetOutlineVolumeBindGroup<I> {
|
||||
type Param = (
|
||||
SRes<OutlineBindGroup>,
|
||||
SRes<OutlineVolumeBindGroup>,
|
||||
SQuery<(
|
||||
Read<DynamicUniformIndex<OutlineVertexUniform>>,
|
||||
Read<DynamicUniformIndex<OutlineVolumeUniform>>,
|
||||
Read<DynamicUniformIndex<OutlineFragmentUniform>>,
|
||||
)>,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue