Skip to content

Commit

Permalink
Implement SDF rendering for rectangles
Browse files Browse the repository at this point in the history
Also updates the interface images for new SDF based icons created by eleriaqueen.
  • Loading branch information
hasenbanck committed Dec 17, 2024
1 parent ff6c51e commit 0e574ed
Show file tree
Hide file tree
Showing 16 changed files with 243 additions and 46 deletions.
Binary file removed korangar/archive/data/texture/checked_box.png
Binary file not shown.
Binary file modified korangar/archive/data/texture/collapsed_arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified korangar/archive/data/texture/expanded_arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added korangar/archive/data/texture/filled_box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed korangar/archive/data/texture/unchecked_box.png
Binary file not shown.
Binary file added korangar/archive/data/texture/unfilled_box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions korangar/src/graphics/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ pub enum RectangleInstruction {
screen_size: ScreenSize,
color: Color,
},
Sdf {
screen_position: ScreenPosition,
screen_size: ScreenSize,
color: Color,
texture_position: Vector2<f32>,
texture_size: Vector2<f32>,
texture: Arc<Texture>,
},
Sprite {
screen_position: ScreenPosition,
screen_size: ScreenSize,
Expand All @@ -141,6 +149,14 @@ pub enum InterfaceRectangleInstruction {
color: Color,
corner_radius: CornerRadius,
},
Sdf {
screen_position: ScreenPosition,
screen_size: ScreenSize,
screen_clip: ScreenClip,
color: Color,
corner_radius: CornerRadius,
texture: Arc<Texture>,
},
Sprite {
screen_position: ScreenPosition,
screen_size: ScreenSize,
Expand Down
61 changes: 57 additions & 4 deletions korangar/src/graphics/passes/interface/rectangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,38 @@ impl Prepare for InterfaceRectangleDrawer {
padding: Default::default(),
});
}
InterfaceRectangleInstruction::Sdf {
screen_position,
screen_size,
screen_clip,
color,
corner_radius,
texture,
} => {
let mut texture_index = texture_views.len() as i32;
let id = texture.get_id();
let potential_index = self.lookup.get(&id);

if let Some(potential_index) = potential_index {
texture_index = *potential_index;
} else {
self.lookup.insert(id, texture_index);
texture_views.push(texture.get_texture_view());
}

self.instance_data.push(InstanceData {
color: color.components_linear(),
corner_radius: (*corner_radius).into(),
screen_clip: (*screen_clip).into(),
screen_position: (*screen_position).into(),
screen_size: (*screen_size).into(),
texture_position: [0.0, 0.0],
texture_size: [1.0, 1.0],
rectangle_type: 1,
texture_index,
padding: Default::default(),
});
}
InterfaceRectangleInstruction::Sprite {
screen_position,
screen_size,
Expand All @@ -285,7 +317,7 @@ impl Prepare for InterfaceRectangleDrawer {
texture,
smooth,
} => {
let rectangle_type = if *smooth { 1 } else { 2 };
let rectangle_type = if *smooth { 2 } else { 3 };

let mut texture_index = texture_views.len() as i32;
let id = texture.get_id();
Expand Down Expand Up @@ -327,7 +359,7 @@ impl Prepare for InterfaceRectangleDrawer {
screen_size: (*screen_size).into(),
texture_position: (*texture_position).into(),
texture_size: (*texture_size).into(),
rectangle_type: 3,
rectangle_type: 4,
texture_index: 0,
padding: Default::default(),
});
Expand Down Expand Up @@ -370,6 +402,27 @@ impl Prepare for InterfaceRectangleDrawer {
padding: Default::default(),
});
}
InterfaceRectangleInstruction::Sdf {
screen_position,
screen_size,
screen_clip,
color,
corner_radius,
texture: _,
} => {
self.instance_data.push(InstanceData {
color: color.components_linear(),
corner_radius: (*corner_radius).into(),
screen_clip: (*screen_clip).into(),
screen_position: (*screen_position).into(),
screen_size: (*screen_size).into(),
texture_position: [0.0, 0.0],
texture_size: [1.0, 1.0],
rectangle_type: 1,
texture_index: 0,
padding: Default::default(),
});
}
InterfaceRectangleInstruction::Sprite {
screen_position,
screen_size,
Expand All @@ -379,7 +432,7 @@ impl Prepare for InterfaceRectangleDrawer {
texture: _,
smooth,
} => {
let rectangle_type = if *smooth { 1 } else { 2 };
let rectangle_type = if *smooth { 2 } else { 3 };

self.instance_data.push(InstanceData {
color: color.components_linear(),
Expand Down Expand Up @@ -410,7 +463,7 @@ impl Prepare for InterfaceRectangleDrawer {
screen_size: (*screen_size).into(),
texture_position: (*texture_position).into(),
texture_size: (*texture_size).into(),
rectangle_type: 3,
rectangle_type: 4,
texture_index: 0,
padding: Default::default(),
});
Expand Down
9 changes: 7 additions & 2 deletions korangar/src/graphics/passes/interface/shader/rectangle.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,19 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {

switch (instance.rectangle_type) {
case 1u: {
// SDF
let pixel = textureSample(texture, linear_sampler, input.texture_coordinates);
color *= vec4(pixel.rgb, clamp((pixel.a - 0.5) * 2.0 / fwidth(pixel.a), 0.0, 1.0));
}
case 2u: {
// Sprite (linear filtering)
color *= textureSample(texture, linear_sampler, input.texture_coordinates);
}
case 2u: {
case 3u: {
// Sprite (nearest filtering)
color *= textureSample(texture, nearest_sampler, input.texture_coordinates);
}
case 3u: {
case 4u: {
// Text (coverage)
color *= textureSample(font_atlas, nearest_sampler, input.texture_coordinates).r;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,19 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {

switch (instance.rectangle_type) {
case 1u: {
// SDF
let pixel = textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates);
color *= vec4(pixel.rgb, clamp((pixel.a - 0.5) * 2.0 / fwidth(pixel.a), 0.0, 1.0));
}
case 2u: {
// Sprite (linear filtering)
color *= textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates);
}
case 2u: {
case 3u: {
// Sprite (nearest filtering)
color *= textureSample(textures[instance.texture_index], nearest_sampler, input.texture_coordinates);
}
case 3u: {
case 4u: {
// Text (coverage)
color *= textureSample(font_atlas, nearest_sampler, input.texture_coordinates).r;
}
Expand Down
63 changes: 58 additions & 5 deletions korangar/src/graphics/passes/postprocessing/rectangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ pub(crate) struct InstanceData {
screen_size: [f32; 2],
texture_position: [f32; 2],
texture_size: [f32; 2],
rectangle_type: u32,
texture_index: i32,
linear_filtering: u32,
padding: [u32; 2],
}

Expand Down Expand Up @@ -274,8 +274,38 @@ impl Prepare for PostProcessingRectangleDrawer {
screen_size: (*screen_size).into(),
texture_position: [0.0; 2],
texture_size: [0.0; 2],
rectangle_type: 0,
texture_index: -1,
linear_filtering: 0,
padding: Default::default(),
});
}
RectangleInstruction::Sdf {
screen_position,
screen_size,
color,
texture_position,
texture_size,
texture,
} => {
let mut texture_index = texture_views.len() as i32;
let id = texture.get_id();
let potential_index = self.lookup.get(&id);

if let Some(potential_index) = potential_index {
texture_index = *potential_index;
} else {
self.lookup.insert(id, texture_index);
texture_views.push(texture.get_texture_view());
}

self.instance_data.push(InstanceData {
color: color.components_linear(),
screen_position: (*screen_position).into(),
screen_size: (*screen_size).into(),
texture_position: (*texture_position).into(),
texture_size: (*texture_size).into(),
rectangle_type: 1,
texture_index,
padding: Default::default(),
});
}
Expand All @@ -288,6 +318,8 @@ impl Prepare for PostProcessingRectangleDrawer {
linear_filtering,
texture,
} => {
let rectangle_type = if *linear_filtering { 2 } else { 3 };

let mut texture_index = texture_views.len() as i32;
let id = texture.get_id();
let potential_index = self.lookup.get(&id);
Expand All @@ -305,8 +337,8 @@ impl Prepare for PostProcessingRectangleDrawer {
screen_size: (*screen_size).into(),
texture_position: (*texture_position).into(),
texture_size: (*texture_size).into(),
rectangle_type,
texture_index,
linear_filtering: *linear_filtering as u32,
padding: Default::default(),
});
}
Expand Down Expand Up @@ -348,8 +380,27 @@ impl Prepare for PostProcessingRectangleDrawer {
screen_size: (*screen_size).into(),
texture_position: [0.0; 2],
texture_size: [0.0; 2],
rectangle_type: 0,
texture_index: -1,
linear_filtering: 0,
padding: Default::default(),
});
}
RectangleInstruction::Sdf {
screen_position,
screen_size,
color,
texture_position,
texture_size,
texture: _,
} => {
self.instance_data.push(InstanceData {
color: color.components_linear(),
screen_position: (*screen_position).into(),
screen_size: (*screen_size).into(),
texture_position: (*texture_position).into(),
texture_size: (*texture_size).into(),
rectangle_type: 1,
texture_index: 0,
padding: Default::default(),
});
}
Expand All @@ -362,14 +413,16 @@ impl Prepare for PostProcessingRectangleDrawer {
linear_filtering,
texture: _,
} => {
let rectangle_type = if *linear_filtering { 2 } else { 3 };

self.instance_data.push(InstanceData {
color: color.components_linear(),
screen_position: (*screen_position).into(),
screen_size: (*screen_size).into(),
texture_position: (*texture_position).into(),
texture_size: (*texture_size).into(),
rectangle_type,
texture_index: 0,
linear_filtering: *linear_filtering as u32,
padding: Default::default(),
});
}
Expand Down
24 changes: 15 additions & 9 deletions korangar/src/graphics/passes/postprocessing/shader/rectangle.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ struct InstanceData {
screen_size: vec2<f32>,
texture_position: vec2<f32>,
texture_size: vec2<f32>,
rectangle_type: u32,
texture_index: i32,
linear_filtering: u32,
}

struct VertexOutput {
Expand Down Expand Up @@ -42,14 +42,20 @@ fn vs_main(
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
let instance = instance_data[input.instance_index];

if instance.texture_index == -1 {
return instance.color;
}

if instance.linear_filtering == 0 {
return textureSample(texture, nearest_sampler, input.texture_coordinates) * instance.color;
} else {
return textureSample(texture, linear_sampler, input.texture_coordinates) * instance.color;
switch (instance.rectangle_type) {
case 1u: {
let pixel = textureSample(texture, linear_sampler, input.texture_coordinates);
return vec4(pixel.rgb, clamp((pixel.a - 0.5) * 2.0 / fwidth(pixel.a), 0.0, 1.0)) * instance.color;
}
case 2u: {
return textureSample(texture, nearest_sampler, input.texture_coordinates) * instance.color;
}
case 3u: {
return textureSample(texture, linear_sampler, input.texture_coordinates) * instance.color;
}
default: {
return instance.color;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ struct InstanceData {
screen_size: vec2<f32>,
texture_position: vec2<f32>,
texture_size: vec2<f32>,
rectangle_type: u32,
texture_index: i32,
linear_filtering: u32,
}

struct VertexOutput {
Expand Down Expand Up @@ -42,14 +42,20 @@ fn vs_main(
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
let instance = instance_data[input.instance_index];

if instance.texture_index == -1 {
return instance.color;
}

if instance.linear_filtering == 0 {
return textureSample(textures[instance.texture_index], nearest_sampler, input.texture_coordinates) * instance.color;
} else {
return textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates) * instance.color;
switch (instance.rectangle_type) {
case 1u: {
let pixel = textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates);
return vec4(pixel.rgb, clamp((pixel.a - 0.5) * 2.0 / fwidth(pixel.a), 0.0, 1.0)) * instance.color;
}
case 2u: {
return textureSample(textures[instance.texture_index], nearest_sampler, input.texture_coordinates) * instance.color;
}
case 3u: {
return textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates) * instance.color;
}
default: {
return instance.color;
}
}
}

Expand Down
Loading

0 comments on commit 0e574ed

Please sign in to comment.