Skip to content

Commit

Permalink
Fix off-by-half pixel error in textured rectangle shader (#2294)
Browse files Browse the repository at this point in the history
### What
Closes #2236

I made a 4x4 test image to verify:
<img width="1189" alt="Screenshot 2023-05-31 at 19 21 21"
src="https://github.com/rerun-io/rerun/assets/1148717/9b0f390a-7da2-4ae2-81b9-8789ea07fec2">

### 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/2294

<!-- pr-link-docs:start -->
Docs preview: https://rerun.io/preview/dd724f5/docs
<!-- pr-link-docs:end -->
  • Loading branch information
emilk committed Jun 15, 2023
1 parent 0965b15 commit beb6350
Showing 1 changed file with 24 additions and 24 deletions.
48 changes: 24 additions & 24 deletions crates/re_renderer/shader/rectangle_fs.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -36,47 +36,47 @@ fn fs_main(in: VertexOut) -> @location(0) Vec4 {
let coord = in.texcoord * Vec2(textureDimensions(texture_float).xy);
if tex_filter(coord) == FILTER_NEAREST {
// nearest
sampled_value = decode_color(textureLoad(texture_float, IVec2(coord + vec2(0.5)), 0));
sampled_value = decode_color(textureLoad(texture_float, IVec2(coord), 0));
} else {
// bilinear
let v00 = decode_color(textureLoad(texture_float, IVec2(coord) + IVec2(0, 0), 0));
let v01 = decode_color(textureLoad(texture_float, IVec2(coord) + IVec2(0, 1), 0));
let v10 = decode_color(textureLoad(texture_float, IVec2(coord) + IVec2(1, 0), 0));
let v11 = decode_color(textureLoad(texture_float, IVec2(coord) + IVec2(1, 1), 0));
let top = mix(v00, v10, fract(coord.x));
let bottom = mix(v01, v11, fract(coord.x));
sampled_value = mix(top, bottom, fract(coord.y));
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 top = mix(v00, v10, fract(coord.x - 0.5));
let bottom = mix(v01, v11, fract(coord.x - 0.5));
sampled_value = mix(top, bottom, fract(coord.y - 0.5));
}
} else if rect_info.sample_type == SAMPLE_TYPE_SINT {
let coord = in.texcoord * Vec2(textureDimensions(texture_sint).xy);
if tex_filter(coord) == FILTER_NEAREST {
// nearest
sampled_value = Vec4(textureLoad(texture_sint, IVec2(coord + vec2(0.5)), 0));
sampled_value = Vec4(textureLoad(texture_sint, IVec2(coord), 0));
} else {
// bilinear
let v00 = Vec4(textureLoad(texture_sint, IVec2(coord) + IVec2(0, 0), 0));
let v01 = Vec4(textureLoad(texture_sint, IVec2(coord) + IVec2(0, 1), 0));
let v10 = Vec4(textureLoad(texture_sint, IVec2(coord) + IVec2(1, 0), 0));
let v11 = Vec4(textureLoad(texture_sint, IVec2(coord) + IVec2(1, 1), 0));
let top = mix(v00, v10, fract(coord.x));
let bottom = mix(v01, v11, fract(coord.x));
sampled_value = mix(top, bottom, fract(coord.y));
let v00 = Vec4(textureLoad(texture_sint, IVec2(coord + vec2(-0.5, -0.5)), 0));
let v01 = Vec4(textureLoad(texture_sint, IVec2(coord + vec2(-0.5, 0.5)), 0));
let v10 = Vec4(textureLoad(texture_sint, IVec2(coord + vec2( 0.5, -0.5)), 0));
let v11 = Vec4(textureLoad(texture_sint, IVec2(coord + vec2( 0.5, 0.5)), 0));
let top = mix(v00, v10, fract(coord.x - 0.5));
let bottom = mix(v01, v11, fract(coord.x - 0.5));
sampled_value = mix(top, bottom, fract(coord.y - 0.5));
}
} else if rect_info.sample_type == SAMPLE_TYPE_UINT {
// TODO(emilk): support premultiplying alpha on this path. Requires knowing the alpha range (255, 65535, …).
let coord = in.texcoord * Vec2(textureDimensions(texture_uint).xy);
if tex_filter(coord) == FILTER_NEAREST {
// nearest
sampled_value = Vec4(textureLoad(texture_uint, IVec2(coord + vec2(0.5)), 0));
sampled_value = Vec4(textureLoad(texture_uint, IVec2(coord), 0));
} else {
// bilinear
let v00 = Vec4(textureLoad(texture_uint, IVec2(coord) + IVec2(0, 0), 0));
let v01 = Vec4(textureLoad(texture_uint, IVec2(coord) + IVec2(0, 1), 0));
let v10 = Vec4(textureLoad(texture_uint, IVec2(coord) + IVec2(1, 0), 0));
let v11 = Vec4(textureLoad(texture_uint, IVec2(coord) + IVec2(1, 1), 0));
let top = mix(v00, v10, fract(coord.x));
let bottom = mix(v01, v11, fract(coord.x));
sampled_value = mix(top, bottom, fract(coord.y));
let v00 = Vec4(textureLoad(texture_uint, IVec2(coord + vec2(-0.5, -0.5)), 0));
let v01 = Vec4(textureLoad(texture_uint, IVec2(coord + vec2(-0.5, 0.5)), 0));
let v10 = Vec4(textureLoad(texture_uint, IVec2(coord + vec2( 0.5, -0.5)), 0));
let v11 = Vec4(textureLoad(texture_uint, IVec2(coord + vec2( 0.5, 0.5)), 0));
let top = mix(v00, v10, fract(coord.x - 0.5));
let bottom = mix(v01, v11, fract(coord.x - 0.5));
sampled_value = mix(top, bottom, fract(coord.y - 0.5));
}
} else {
return ERROR_RGBA; // unknown sample type
Expand Down

0 comments on commit beb6350

Please sign in to comment.