fix PathRasterization
pipeline
This commit is contained in:
parent
d7b14d8dc5
commit
62d1b7e36f
2 changed files with 196 additions and 253 deletions
|
@ -68,7 +68,8 @@ struct DirectXResources {
|
||||||
struct DirectXRenderPipelines {
|
struct DirectXRenderPipelines {
|
||||||
shadow_pipeline: PipelineState<Shadow>,
|
shadow_pipeline: PipelineState<Shadow>,
|
||||||
quad_pipeline: PipelineState<Quad>,
|
quad_pipeline: PipelineState<Quad>,
|
||||||
path_rasterization_pipeline: PathRasterizationPipelineState,
|
// path_rasterization_pipeline: PathRasterizationPipelineState,
|
||||||
|
path_rasterization_pipeline: PipelineState<PathRasterizationSprite>,
|
||||||
path_sprite_pipeline: PipelineState<PathSprite>,
|
path_sprite_pipeline: PipelineState<PathSprite>,
|
||||||
underline_pipeline: PipelineState<Underline>,
|
underline_pipeline: PipelineState<Underline>,
|
||||||
mono_sprites: PipelineState<MonochromeSprite>,
|
mono_sprites: PipelineState<MonochromeSprite>,
|
||||||
|
@ -341,6 +342,8 @@ impl DirectXRenderer {
|
||||||
&self.devices.device_context,
|
&self.devices.device_context,
|
||||||
&self.resources.viewport,
|
&self.resources.viewport,
|
||||||
&self.globals.global_params_buffer,
|
&self.globals.global_params_buffer,
|
||||||
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
|
||||||
|
4,
|
||||||
shadows.len() as u32,
|
shadows.len() as u32,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -358,6 +361,8 @@ impl DirectXRenderer {
|
||||||
&self.devices.device_context,
|
&self.devices.device_context,
|
||||||
&self.resources.viewport,
|
&self.resources.viewport,
|
||||||
&self.globals.global_params_buffer,
|
&self.globals.global_params_buffer,
|
||||||
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
|
||||||
|
4,
|
||||||
quads.len() as u32,
|
quads.len() as u32,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -383,35 +388,29 @@ impl DirectXRenderer {
|
||||||
|
|
||||||
// Collect all vertices and sprites for a single draw call
|
// Collect all vertices and sprites for a single draw call
|
||||||
let mut vertices = Vec::new();
|
let mut vertices = Vec::new();
|
||||||
let mut sprites = Vec::new();
|
|
||||||
|
|
||||||
for (path_index, path) in paths.iter().enumerate() {
|
for path in paths {
|
||||||
vertices.extend(path.vertices.iter().map(|v| DirectXPathVertex {
|
vertices.extend(path.vertices.iter().map(|v| PathRasterizationSprite {
|
||||||
xy_position: v.xy_position,
|
xy_position: v.xy_position,
|
||||||
st_position: v.st_position,
|
st_position: v.st_position,
|
||||||
path_index: path_index as u32,
|
|
||||||
}));
|
|
||||||
|
|
||||||
sprites.push(PathRasterizationSprite {
|
|
||||||
bounds: path.bounds.intersect(&path.content_mask.bounds),
|
|
||||||
color: path.color,
|
color: path.color,
|
||||||
});
|
bounds: path.bounds.intersect(&path.content_mask.bounds),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !vertices.is_empty() {
|
self.pipelines.path_rasterization_pipeline.update_buffer(
|
||||||
self.pipelines.path_rasterization_pipeline.update_buffer(
|
&self.devices.device,
|
||||||
&self.devices.device,
|
&self.devices.device_context,
|
||||||
&self.devices.device_context,
|
&vertices,
|
||||||
&sprites,
|
)?;
|
||||||
&vertices,
|
self.pipelines.path_rasterization_pipeline.draw(
|
||||||
)?;
|
&self.devices.device_context,
|
||||||
self.pipelines.path_rasterization_pipeline.draw(
|
&self.resources.viewport,
|
||||||
&self.devices.device_context,
|
&self.globals.global_params_buffer,
|
||||||
vertices.len() as u32,
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
|
||||||
&self.resources.viewport,
|
vertices.len() as u32,
|
||||||
&self.globals.global_params_buffer,
|
1,
|
||||||
)?;
|
)?;
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve MSAA to non-MSAA intermediate texture
|
// Resolve MSAA to non-MSAA intermediate texture
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -490,6 +489,8 @@ impl DirectXRenderer {
|
||||||
&self.devices.device_context,
|
&self.devices.device_context,
|
||||||
&self.resources.viewport,
|
&self.resources.viewport,
|
||||||
&self.globals.global_params_buffer,
|
&self.globals.global_params_buffer,
|
||||||
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
|
||||||
|
4,
|
||||||
underlines.len() as u32,
|
underlines.len() as u32,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -655,7 +656,12 @@ impl DirectXRenderPipelines {
|
||||||
let shadow_pipeline =
|
let shadow_pipeline =
|
||||||
PipelineState::new(device, "shadow_pipeline", ShaderModule::Shadow, 4)?;
|
PipelineState::new(device, "shadow_pipeline", ShaderModule::Shadow, 4)?;
|
||||||
let quad_pipeline = PipelineState::new(device, "quad_pipeline", ShaderModule::Quad, 64)?;
|
let quad_pipeline = PipelineState::new(device, "quad_pipeline", ShaderModule::Quad, 64)?;
|
||||||
let path_rasterization_pipeline = PathRasterizationPipelineState::new(device)?;
|
let path_rasterization_pipeline = PipelineState::new(
|
||||||
|
device,
|
||||||
|
"path_rasterization_pipeline",
|
||||||
|
ShaderModule::PathRasterization,
|
||||||
|
32,
|
||||||
|
)?;
|
||||||
let path_sprite_pipeline =
|
let path_sprite_pipeline =
|
||||||
PipelineState::new(device, "path_sprite_pipeline", ShaderModule::PathSprite, 1)?;
|
PipelineState::new(device, "path_sprite_pipeline", ShaderModule::PathSprite, 1)?;
|
||||||
let underline_pipeline =
|
let underline_pipeline =
|
||||||
|
@ -769,16 +775,16 @@ struct PipelineState<T> {
|
||||||
_marker: std::marker::PhantomData<T>,
|
_marker: std::marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PathRasterizationPipelineState {
|
// struct PathRasterizationPipelineState {
|
||||||
vertex: ID3D11VertexShader,
|
// vertex: ID3D11VertexShader,
|
||||||
fragment: ID3D11PixelShader,
|
// fragment: ID3D11PixelShader,
|
||||||
buffer: ID3D11Buffer,
|
// buffer: ID3D11Buffer,
|
||||||
buffer_size: usize,
|
// buffer_size: usize,
|
||||||
view: [Option<ID3D11ShaderResourceView>; 1],
|
// view: [Option<ID3D11ShaderResourceView>; 1],
|
||||||
vertex_buffer: Option<ID3D11Buffer>,
|
// vertex_buffer: Option<ID3D11Buffer>,
|
||||||
vertex_buffer_size: usize,
|
// vertex_buffer_size: usize,
|
||||||
input_layout: ID3D11InputLayout,
|
// input_layout: ID3D11InputLayout,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl<T> PipelineState<T> {
|
impl<T> PipelineState<T> {
|
||||||
fn new(
|
fn new(
|
||||||
|
@ -837,19 +843,21 @@ impl<T> PipelineState<T> {
|
||||||
device_context: &ID3D11DeviceContext,
|
device_context: &ID3D11DeviceContext,
|
||||||
viewport: &[D3D11_VIEWPORT],
|
viewport: &[D3D11_VIEWPORT],
|
||||||
global_params: &[Option<ID3D11Buffer>],
|
global_params: &[Option<ID3D11Buffer>],
|
||||||
|
topology: D3D_PRIMITIVE_TOPOLOGY,
|
||||||
|
vertex_count: u32,
|
||||||
instance_count: u32,
|
instance_count: u32,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
set_pipeline_state(
|
set_pipeline_state(
|
||||||
device_context,
|
device_context,
|
||||||
&self.view,
|
&self.view,
|
||||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
|
topology,
|
||||||
viewport,
|
viewport,
|
||||||
&self.vertex,
|
&self.vertex,
|
||||||
&self.fragment,
|
&self.fragment,
|
||||||
global_params,
|
global_params,
|
||||||
);
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
device_context.DrawInstanced(4, instance_count, 0, 0);
|
device_context.DrawInstanced(vertex_count, instance_count, 0, 0);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -883,175 +891,130 @@ impl<T> PipelineState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathRasterizationPipelineState {
|
// impl PathRasterizationPipelineState {
|
||||||
fn new(device: &ID3D11Device) -> Result<Self> {
|
// fn new(device: &ID3D11Device) -> Result<Self> {
|
||||||
let (vertex, vertex_shader) = {
|
// let (vertex, vertex_shader) = {
|
||||||
let raw_vertex_shader =
|
// let raw_vertex_shader =
|
||||||
RawShaderBytes::new(ShaderModule::PathRasterization, ShaderTarget::Vertex)?;
|
// RawShaderBytes::new(ShaderModule::PathRasterization, ShaderTarget::Vertex)?;
|
||||||
(
|
// (
|
||||||
create_vertex_shader(device, raw_vertex_shader.as_bytes())?,
|
// create_vertex_shader(device, raw_vertex_shader.as_bytes())?,
|
||||||
raw_vertex_shader,
|
// raw_vertex_shader,
|
||||||
)
|
// )
|
||||||
};
|
// };
|
||||||
let fragment = {
|
// let fragment = {
|
||||||
let raw_shader =
|
// let raw_shader =
|
||||||
RawShaderBytes::new(ShaderModule::PathRasterization, ShaderTarget::Fragment)?;
|
// RawShaderBytes::new(ShaderModule::PathRasterization, ShaderTarget::Fragment)?;
|
||||||
create_fragment_shader(device, raw_shader.as_bytes())?
|
// create_fragment_shader(device, raw_shader.as_bytes())?
|
||||||
};
|
// };
|
||||||
let buffer = create_buffer(device, std::mem::size_of::<PathRasterizationSprite>(), 32)?;
|
// let buffer = create_buffer(device, std::mem::size_of::<PathRasterizationSprite>(), 32)?;
|
||||||
let view = create_buffer_view(device, &buffer)?;
|
// let view = create_buffer_view(device, &buffer)?;
|
||||||
let vertex_buffer = Some(create_buffer(
|
// let vertex_buffer = Some(create_buffer(
|
||||||
device,
|
// device,
|
||||||
std::mem::size_of::<DirectXPathVertex>(),
|
// std::mem::size_of::<PathRasterizationSprite>(),
|
||||||
32,
|
// 32,
|
||||||
)?);
|
// )?);
|
||||||
|
|
||||||
let input_layout = unsafe {
|
// Ok(Self {
|
||||||
let mut layout = None;
|
// vertex,
|
||||||
device.CreateInputLayout(
|
// fragment,
|
||||||
&[
|
// buffer,
|
||||||
D3D11_INPUT_ELEMENT_DESC {
|
// buffer_size: 32,
|
||||||
SemanticName: windows::core::s!("POSITION"),
|
// view,
|
||||||
SemanticIndex: 0,
|
// vertex_buffer,
|
||||||
Format: DXGI_FORMAT_R32G32_FLOAT,
|
// vertex_buffer_size: 32,
|
||||||
InputSlot: 0,
|
// })
|
||||||
AlignedByteOffset: 0,
|
// }
|
||||||
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
||||||
InstanceDataStepRate: 0,
|
|
||||||
},
|
|
||||||
D3D11_INPUT_ELEMENT_DESC {
|
|
||||||
SemanticName: windows::core::s!("TEXCOORD"),
|
|
||||||
SemanticIndex: 0,
|
|
||||||
Format: DXGI_FORMAT_R32G32_FLOAT,
|
|
||||||
InputSlot: 0,
|
|
||||||
AlignedByteOffset: 8,
|
|
||||||
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
||||||
InstanceDataStepRate: 0,
|
|
||||||
},
|
|
||||||
D3D11_INPUT_ELEMENT_DESC {
|
|
||||||
SemanticName: windows::core::s!("TEXCOORD"),
|
|
||||||
SemanticIndex: 1,
|
|
||||||
Format: DXGI_FORMAT_R32_UINT,
|
|
||||||
InputSlot: 0,
|
|
||||||
AlignedByteOffset: 16,
|
|
||||||
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
|
||||||
InstanceDataStepRate: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
vertex_shader.as_bytes(),
|
|
||||||
Some(&mut layout),
|
|
||||||
)?;
|
|
||||||
layout.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self {
|
// fn update_buffer(
|
||||||
vertex,
|
// &mut self,
|
||||||
fragment,
|
// device: &ID3D11Device,
|
||||||
buffer,
|
// device_context: &ID3D11DeviceContext,
|
||||||
buffer_size: 32,
|
// sprites: &[PathRasterizationSprite],
|
||||||
view,
|
// vertices_data: &[DirectXPathVertex],
|
||||||
vertex_buffer,
|
// ) -> Result<()> {
|
||||||
vertex_buffer_size: 32,
|
// if self.buffer_size < sprites.len() {
|
||||||
input_layout,
|
// let new_buffer_size = sprites.len().next_power_of_two();
|
||||||
})
|
// log::info!(
|
||||||
}
|
// "Updating Paths Pipeline buffer size from {} to {}",
|
||||||
|
// self.buffer_size,
|
||||||
|
// new_buffer_size
|
||||||
|
// );
|
||||||
|
// let buffer = create_buffer(
|
||||||
|
// device,
|
||||||
|
// std::mem::size_of::<PathRasterizationSprite>(),
|
||||||
|
// new_buffer_size,
|
||||||
|
// )?;
|
||||||
|
// let view = create_buffer_view(device, &buffer)?;
|
||||||
|
// self.buffer = buffer;
|
||||||
|
// self.view = view;
|
||||||
|
// self.buffer_size = new_buffer_size;
|
||||||
|
// }
|
||||||
|
// update_buffer(device_context, &self.buffer, sprites)?;
|
||||||
|
|
||||||
fn update_buffer(
|
// if self.vertex_buffer_size < vertices_data.len() {
|
||||||
&mut self,
|
// let new_vertex_buffer_size = vertices_data.len().next_power_of_two();
|
||||||
device: &ID3D11Device,
|
// log::info!(
|
||||||
device_context: &ID3D11DeviceContext,
|
// "Updating Paths Pipeline vertex buffer size from {} to {}",
|
||||||
sprites: &[PathRasterizationSprite],
|
// self.vertex_buffer_size,
|
||||||
vertices_data: &[DirectXPathVertex],
|
// new_vertex_buffer_size
|
||||||
) -> Result<()> {
|
// );
|
||||||
if self.buffer_size < sprites.len() {
|
// let vertex_buffer = create_buffer(
|
||||||
let new_buffer_size = sprites.len().next_power_of_two();
|
// device,
|
||||||
log::info!(
|
// std::mem::size_of::<DirectXPathVertex>(),
|
||||||
"Updating Paths Pipeline buffer size from {} to {}",
|
// new_vertex_buffer_size,
|
||||||
self.buffer_size,
|
// )?;
|
||||||
new_buffer_size
|
// self.vertex_buffer = Some(vertex_buffer);
|
||||||
);
|
// self.vertex_buffer_size = new_vertex_buffer_size;
|
||||||
let buffer = create_buffer(
|
// }
|
||||||
device,
|
// update_buffer(
|
||||||
std::mem::size_of::<PathRasterizationSprite>(),
|
// device_context,
|
||||||
new_buffer_size,
|
// self.vertex_buffer.as_ref().unwrap(),
|
||||||
)?;
|
// vertices_data,
|
||||||
let view = create_buffer_view(device, &buffer)?;
|
// )?;
|
||||||
self.buffer = buffer;
|
|
||||||
self.view = view;
|
|
||||||
self.buffer_size = new_buffer_size;
|
|
||||||
}
|
|
||||||
update_buffer(device_context, &self.buffer, sprites)?;
|
|
||||||
|
|
||||||
if self.vertex_buffer_size < vertices_data.len() {
|
// Ok(())
|
||||||
let new_vertex_buffer_size = vertices_data.len().next_power_of_two();
|
// }
|
||||||
log::info!(
|
|
||||||
"Updating Paths Pipeline vertex buffer size from {} to {}",
|
|
||||||
self.vertex_buffer_size,
|
|
||||||
new_vertex_buffer_size
|
|
||||||
);
|
|
||||||
let vertex_buffer = create_buffer(
|
|
||||||
device,
|
|
||||||
std::mem::size_of::<DirectXPathVertex>(),
|
|
||||||
new_vertex_buffer_size,
|
|
||||||
)?;
|
|
||||||
self.vertex_buffer = Some(vertex_buffer);
|
|
||||||
self.vertex_buffer_size = new_vertex_buffer_size;
|
|
||||||
}
|
|
||||||
update_buffer(
|
|
||||||
device_context,
|
|
||||||
self.vertex_buffer.as_ref().unwrap(),
|
|
||||||
vertices_data,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
// fn draw(
|
||||||
}
|
// &self,
|
||||||
|
// device_context: &ID3D11DeviceContext,
|
||||||
fn draw(
|
// vertex_count: u32,
|
||||||
&self,
|
// viewport: &[D3D11_VIEWPORT],
|
||||||
device_context: &ID3D11DeviceContext,
|
// global_params: &[Option<ID3D11Buffer>],
|
||||||
vertex_count: u32,
|
// ) -> Result<()> {
|
||||||
viewport: &[D3D11_VIEWPORT],
|
// set_pipeline_state(
|
||||||
global_params: &[Option<ID3D11Buffer>],
|
// device_context,
|
||||||
) -> Result<()> {
|
// &self.view,
|
||||||
set_pipeline_state(
|
// D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
|
||||||
device_context,
|
// viewport,
|
||||||
&self.view,
|
// &self.vertex,
|
||||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
|
// &self.fragment,
|
||||||
viewport,
|
// global_params,
|
||||||
&self.vertex,
|
// );
|
||||||
&self.fragment,
|
// unsafe {
|
||||||
global_params,
|
// const STRIDE: u32 = std::mem::size_of::<DirectXPathVertex>() as u32;
|
||||||
);
|
// const OFFSET: u32 = 0;
|
||||||
unsafe {
|
// device_context.IASetInputLayout(&self.input_layout);
|
||||||
const STRIDE: u32 = std::mem::size_of::<DirectXPathVertex>() as u32;
|
// device_context.IASetVertexBuffers(
|
||||||
const OFFSET: u32 = 0;
|
// 0,
|
||||||
device_context.IASetInputLayout(&self.input_layout);
|
// 1,
|
||||||
device_context.IASetVertexBuffers(
|
// Some(&self.vertex_buffer),
|
||||||
0,
|
// Some(&STRIDE),
|
||||||
1,
|
// Some(&OFFSET),
|
||||||
Some(&self.vertex_buffer),
|
// );
|
||||||
Some(&STRIDE),
|
// device_context.Draw(vertex_count, 0);
|
||||||
Some(&OFFSET),
|
// }
|
||||||
);
|
// Ok(())
|
||||||
device_context.Draw(vertex_count, 0);
|
// }
|
||||||
}
|
// }
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
struct DirectXPathVertex {
|
|
||||||
xy_position: Point<ScaledPixels>,
|
|
||||||
st_position: Point<f32>,
|
|
||||||
path_index: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct PathRasterizationSprite {
|
struct PathRasterizationSprite {
|
||||||
bounds: Bounds<ScaledPixels>,
|
xy_position: Point<ScaledPixels>,
|
||||||
|
st_position: Point<f32>,
|
||||||
color: Background,
|
color: Background,
|
||||||
|
bounds: Bounds<ScaledPixels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|
|
@ -876,18 +876,10 @@ float4 shadow_fragment(ShadowFragmentInput input): SV_TARGET {
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct PathVertex {
|
|
||||||
float2 xy_position: POSITION;
|
|
||||||
float2 st_position: TEXCOORD0;
|
|
||||||
uint path_index: TEXCOORD1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PathRasterizationSprite {
|
struct PathRasterizationSprite {
|
||||||
Bounds bounds;
|
float2 xy_position;
|
||||||
|
float2 st_position;
|
||||||
Background color;
|
Background color;
|
||||||
};
|
|
||||||
|
|
||||||
struct PathSprite {
|
|
||||||
Bounds bounds;
|
Bounds bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -896,68 +888,52 @@ StructuredBuffer<PathRasterizationSprite> path_rasterization_sprites: register(t
|
||||||
struct PathVertexOutput {
|
struct PathVertexOutput {
|
||||||
float4 position: SV_Position;
|
float4 position: SV_Position;
|
||||||
float2 st_position: TEXCOORD0;
|
float2 st_position: TEXCOORD0;
|
||||||
nointerpolation uint tag: TEXCOORD1;
|
nointerpolation uint vertex_id: TEXCOORD1;
|
||||||
nointerpolation uint color_space: TEXCOORD2;
|
float4 clip_distance: SV_ClipDistance;
|
||||||
nointerpolation float gradient_angle: TEXCOORD3;
|
|
||||||
nointerpolation float4 solid_color: COLOR0;
|
|
||||||
nointerpolation float4 color0: COLOR1;
|
|
||||||
nointerpolation float4 color1: COLOR2;
|
|
||||||
nointerpolation float2 stop_percentages: COLOR3;
|
|
||||||
nointerpolation Bounds bounds: BOUNDS;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PathFragmentInput {
|
struct PathFragmentInput {
|
||||||
float4 position: SV_Position;
|
float4 position: SV_Position;
|
||||||
float2 st_position: TEXCOORD0;
|
float2 st_position: TEXCOORD0;
|
||||||
nointerpolation uint tag: TEXCOORD1;
|
nointerpolation uint vertex_id: TEXCOORD1;
|
||||||
nointerpolation uint color_space: TEXCOORD2;
|
|
||||||
nointerpolation float gradient_angle: TEXCOORD3;
|
|
||||||
nointerpolation float4 solid_color: COLOR0;
|
|
||||||
nointerpolation float4 color0: COLOR1;
|
|
||||||
nointerpolation float4 color1: COLOR2;
|
|
||||||
nointerpolation float2 stop_percentages: COLOR3;
|
|
||||||
nointerpolation Bounds bounds: BOUNDS;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PathVertexOutput path_rasterization_vertex(PathVertex input) {
|
PathVertexOutput path_rasterization_vertex(uint vertex_id: SV_VertexID) {
|
||||||
PathRasterizationSprite sprite = path_rasterization_sprites[input.path_index];
|
PathRasterizationSprite sprite = path_rasterization_sprites[vertex_id];
|
||||||
|
|
||||||
PathVertexOutput output;
|
PathVertexOutput output;
|
||||||
output.position = to_device_position_impl(input.xy_position);
|
output.position = to_device_position_impl(sprite.xy_position);
|
||||||
output.st_position = input.st_position;
|
output.st_position = sprite.st_position;
|
||||||
output.bounds = sprite.bounds;
|
output.vertex_id = vertex_id;
|
||||||
output.tag = sprite.color.tag;
|
output.clip_distance = distance_from_clip_rect_impl(sprite.xy_position, sprite.bounds);
|
||||||
output.color_space = sprite.color.color_space;
|
|
||||||
output.gradient_angle = sprite.color.gradient_angle_or_pattern_height;
|
|
||||||
output.stop_percentages = float2(sprite.color.colors[0].percentage, sprite.color.colors[1].percentage);
|
|
||||||
|
|
||||||
GradientColor gradient = prepare_gradient_color(
|
|
||||||
sprite.color.tag,
|
|
||||||
sprite.color.color_space,
|
|
||||||
sprite.color.solid,
|
|
||||||
sprite.color.colors
|
|
||||||
);
|
|
||||||
output.solid_color = gradient.solid;
|
|
||||||
output.color0 = gradient.color0;
|
|
||||||
output.color1 = gradient.color1;
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 path_rasterization_fragment(PathFragmentInput input): SV_Target {
|
float4 path_rasterization_fragment(PathFragmentInput input): SV_Target {
|
||||||
Background background;
|
float2 dx = ddx(input.st_position);
|
||||||
background.tag = input.tag;
|
float2 dy = ddy(input.st_position);
|
||||||
background.color_space = input.color_space;
|
PathRasterizationSprite sprite = path_rasterization_sprites[input.vertex_id];
|
||||||
background.solid = (Hsla)0; // Not used when tag != 0
|
|
||||||
background.gradient_angle_or_pattern_height = input.gradient_angle;
|
Background background = sprite.color;
|
||||||
background.colors[0].color = (Hsla)0; // Not used when colors are pre-computed
|
Bounds bounds = sprite.bounds;
|
||||||
background.colors[0].percentage = input.stop_percentages.x;
|
|
||||||
background.colors[1].color = (Hsla)0; // Not used when colors are pre-computed
|
|
||||||
background.colors[1].percentage = input.stop_percentages.y;
|
|
||||||
|
|
||||||
float4 color = gradient_color(background, input.position.xy, input.bounds,
|
float alpha;
|
||||||
input.solid_color, input.color0, input.color1);
|
if (length(float2(dx.x, dy.x))) {
|
||||||
return color;
|
alpha = 1.0;
|
||||||
|
} else {
|
||||||
|
float2 gradient = 2.0 * input.st_position.xx * float2(dx.x, dy.x) - float2(dx.y, dy.y);
|
||||||
|
float f = input.st_position.x * input.st_position.x - input.st_position.y;
|
||||||
|
float distance = f / length(gradient);
|
||||||
|
alpha = saturate(0.5 - distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientColor gradient = prepare_gradient_color(
|
||||||
|
background.tag, background.color_space, background.solid, background.colors);
|
||||||
|
|
||||||
|
float4 color = gradient_color(background, input.position.xy, bounds,
|
||||||
|
gradient.solid, gradient.color0, gradient.color1);
|
||||||
|
return float4(color.rgb * color.a * alpha, alpha * color.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -966,6 +942,10 @@ float4 path_rasterization_fragment(PathFragmentInput input): SV_Target {
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct PathSprite {
|
||||||
|
Bounds bounds;
|
||||||
|
};
|
||||||
|
|
||||||
struct PathSpriteVertexOutput {
|
struct PathSpriteVertexOutput {
|
||||||
float4 position: SV_Position;
|
float4 position: SV_Position;
|
||||||
float2 texture_coords: TEXCOORD0;
|
float2 texture_coords: TEXCOORD0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue