Skip to content

Commit

Permalink
Fix texture clamping and color gradient selection being displayed inc…
Browse files Browse the repository at this point in the history
…orrectly (#2394)

<!--
Open the PR up as a draft until you feel it is ready for a proper
review.

Do not make PR:s from your own `main` branch, as that makes it difficult
for reviewers to add their own fixes.

Add any improvements to the branch as new commits to make it easier for
reviewers to follow the progress. All commits will be squashed to a
single commit once the PR is merged into `main`.

Make sure you mention any issues that this PR closes in the description,
as well as any other related issues.

To get an auto-generated PR description you can put "copilot:summary" or
"copilot:walkthrough" anywhere.
-->

### What

Rectangle texture samples are now clamped to border

Before:
<img width="480" alt="image"
src="https://github.com/rerun-io/rerun/assets/1220815/e6286fc8-c317-4717-b432-e4f73cbf5114">


After:
<img width="491" alt="image"
src="https://github.com/rerun-io/rerun/assets/1220815/5171ef00-d409-48e0-856b-e66aca488ff1">



### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)

<!-- This line will get updated when the PR build summary job finishes.
-->
PR Build Summary: https://build.rerun.io/pr/2394

<!-- pr-link-docs:start -->
Docs preview: https://rerun.io/preview/79e93ca/docs
Examples preview: https://rerun.io/preview/79e93ca/examples
<!-- pr-link-docs:end -->
  • Loading branch information
Wumpf authored Jun 13, 2023
1 parent 76e7c9d commit e155fe8
Showing 1 changed file with 43 additions and 18 deletions.
61 changes: 43 additions & 18 deletions crates/re_renderer/shader/rectangle_fs.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ fn decode_color(sampled_value: Vec4) -> Vec4 {
return rgba;
}

/// Takes a floating point texel coordinate and outputs a integer texel coordinate
/// on the neighrest neighbor, clamped to the texture edge.
fn clamp_to_edge_nearest_neighbor(coord: Vec2, texture_dimension: Vec2) -> IVec2 {
return IVec2(clamp(floor(coord), Vec2(0.0), texture_dimension - Vec2(1.0)));
}

/// Takes a floating point texel coordinate and outputs the four integer texel coordinates that are used for bilinear filtering.
/// All four samples are clamped to the texture edge.
fn clamp_to_edge_bilinear_samples(coord: Vec2, texture_dimension: Vec2) -> array<IVec2, 4> {
let v00 = clamp_to_edge_nearest_neighbor(coord + vec2(-0.5, -0.5), texture_dimension);
let v01 = clamp_to_edge_nearest_neighbor(coord + vec2(-0.5, 0.5), texture_dimension);
let v10 = clamp_to_edge_nearest_neighbor(coord + vec2( 0.5, -0.5), texture_dimension);
let v11 = clamp_to_edge_nearest_neighbor(coord + vec2( 0.5, 0.5), texture_dimension);
return array<IVec2, 4>(IVec2(v00), IVec2(v01), IVec2(v10), IVec2(v11));
}

fn filter_bilinear(coord: Vec2, v00: Vec4, v01: Vec4, v10: Vec4, v11: Vec4) -> Vec4 {
let top = mix(v00, v10, fract(coord.x - 0.5));
let bottom = mix(v01, v11, fract(coord.x - 0.5));
Expand All @@ -51,42 +67,51 @@ fn fs_main(in: VertexOut) -> @location(0) Vec4 {
// Sample the main texture:
var normalized_value: Vec4;
if rect_info.sample_type == SAMPLE_TYPE_FLOAT {
let coord = in.texcoord * Vec2(textureDimensions(texture_float).xy);
let texture_dimensions = Vec2(textureDimensions(texture_float).xy);
let coord = in.texcoord * texture_dimensions;
if tex_filter(coord) == FILTER_NEAREST {
// nearest
normalized_value = decode_color(textureLoad(texture_float, IVec2(coord), 0));
normalized_value = decode_color(textureLoad(texture_float,
clamp_to_edge_nearest_neighbor(coord, texture_dimensions), 0));
} else {
// bilinear
let v00 = decode_color(textureLoad(texture_float, IVec2(coord + vec2(-0.5, -0.5)), 0));
let v01 = decode_color(textureLoad(texture_float, IVec2(coord + vec2(-0.5, 0.5)), 0));
let v10 = decode_color(textureLoad(texture_float, IVec2(coord + vec2( 0.5, -0.5)), 0));
let v11 = decode_color(textureLoad(texture_float, IVec2(coord + vec2( 0.5, 0.5)), 0));
let sample_positions = clamp_to_edge_bilinear_samples(coord, texture_dimensions);
let v00 = decode_color(textureLoad(texture_float, sample_positions[0], 0));
let v01 = decode_color(textureLoad(texture_float, sample_positions[1], 0));
let v10 = decode_color(textureLoad(texture_float, sample_positions[2], 0));
let v11 = decode_color(textureLoad(texture_float, sample_positions[3], 0));
normalized_value = filter_bilinear(coord, v00, v01, v10, v11);
}
} else if rect_info.sample_type == SAMPLE_TYPE_SINT {
let coord = in.texcoord * Vec2(textureDimensions(texture_sint).xy);
let texture_dimensions = Vec2(textureDimensions(texture_sint).xy);
let coord = in.texcoord * texture_dimensions;
if tex_filter(coord) == FILTER_NEAREST {
// nearest
normalized_value = decode_color(Vec4(textureLoad(texture_sint, IVec2(coord), 0)));
normalized_value = decode_color(Vec4(textureLoad(texture_sint,
clamp_to_edge_nearest_neighbor(coord, texture_dimensions), 0)));
} else {
// bilinear
let v00 = decode_color(Vec4(textureLoad(texture_sint, IVec2(coord + vec2(-0.5, -0.5)), 0)));
let v01 = decode_color(Vec4(textureLoad(texture_sint, IVec2(coord + vec2(-0.5, 0.5)), 0)));
let v10 = decode_color(Vec4(textureLoad(texture_sint, IVec2(coord + vec2( 0.5, -0.5)), 0)));
let v11 = decode_color(Vec4(textureLoad(texture_sint, IVec2(coord + vec2( 0.5, 0.5)), 0)));
let sample_positions = clamp_to_edge_bilinear_samples(coord, texture_dimensions);
let v00 = decode_color(Vec4(textureLoad(texture_sint, sample_positions[0], 0)));
let v01 = decode_color(Vec4(textureLoad(texture_sint, sample_positions[1], 0)));
let v10 = decode_color(Vec4(textureLoad(texture_sint, sample_positions[2], 0)));
let v11 = decode_color(Vec4(textureLoad(texture_sint, sample_positions[3], 0)));
normalized_value = filter_bilinear(coord, v00, v01, v10, v11);
}
} else if rect_info.sample_type == SAMPLE_TYPE_UINT {
let coord = in.texcoord * Vec2(textureDimensions(texture_uint).xy);
let texture_dimensions = Vec2(textureDimensions(texture_uint).xy);
let coord = in.texcoord * texture_dimensions;
if tex_filter(coord) == FILTER_NEAREST {
// nearest
normalized_value = decode_color(Vec4(textureLoad(texture_uint, IVec2(coord), 0)));
normalized_value = decode_color(Vec4(textureLoad(texture_uint,
clamp_to_edge_nearest_neighbor(coord, texture_dimensions), 0)));
} else {
// bilinear
let v00 = decode_color(Vec4(textureLoad(texture_uint, IVec2(coord + vec2(-0.5, -0.5)), 0)));
let v01 = decode_color(Vec4(textureLoad(texture_uint, IVec2(coord + vec2(-0.5, 0.5)), 0)));
let v10 = decode_color(Vec4(textureLoad(texture_uint, IVec2(coord + vec2( 0.5, -0.5)), 0)));
let v11 = decode_color(Vec4(textureLoad(texture_uint, IVec2(coord + vec2( 0.5, 0.5)), 0)));
let sample_positions = clamp_to_edge_bilinear_samples(coord, texture_dimensions);
let v00 = decode_color(Vec4(textureLoad(texture_uint, sample_positions[0], 0)));
let v01 = decode_color(Vec4(textureLoad(texture_uint, sample_positions[1], 0)));
let v10 = decode_color(Vec4(textureLoad(texture_uint, sample_positions[2], 0)));
let v11 = decode_color(Vec4(textureLoad(texture_uint, sample_positions[3], 0)));
normalized_value = filter_bilinear(coord, v00, v01, v10, v11);
}
} else {
Expand Down

0 comments on commit e155fe8

Please sign in to comment.