mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 02:56:17 -10:00
Shader packs: a texel offset given as a parameter moves the coordinate
GLSL asks a texel offset to be a constant expression; GL drivers also take one a function receives as a `const in ivec2` parameter (Arc's FXAA samples its neighbours that way, so its final pass was skipped in every dimension). Such an offset now moves the coordinate by that many texels of the base level; a constant one stays an offset.
This commit is contained in:
1 parent
1da773a501
commit
623aa1d3ea
2 files changed
+79
-1
No files matched your search
@@ -162,6 +162,36 @@ fn a_matrix_built_from_one_vector_takes_its_components_column_by_column() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_texel_offset_a_function_gets_as_a_parameter_moves_the_coordinate() {
|
||||
// Arc's FXAA: `textureLodOffset(tex, uv, 0.0, offset)` with `const in ivec2 offset`.
|
||||
let module = assert_terrain_translates(
|
||||
"#version 330\nuniform sampler2D colortex4;\n\
|
||||
float lumaAt(const in vec2 uv, const in ivec2 offset) {\n\
|
||||
return textureLodOffset(colortex4, uv, 0.0, offset).r + textureOffset(colortex4, uv, offset).g;\n}\n\
|
||||
layout(location = 0) out vec4 color;\n\
|
||||
void main() { color = vec4(lumaAt(vec2(0.5), ivec2(0, -1)), textureOffset(colortex4, vec2(0.5), ivec2(1, 0)).r, 0.0, 1.0); }\n",
|
||||
);
|
||||
// The constant offset in `main` stays an offset.
|
||||
let offsets = module
|
||||
.functions
|
||||
.iter()
|
||||
.map(|(_, f)| &f.expressions)
|
||||
.chain(module.entry_points.iter().map(|e| &e.function.expressions))
|
||||
.flat_map(|e| e.iter())
|
||||
.filter(|(_, e)| {
|
||||
matches!(
|
||||
e,
|
||||
naga::Expression::ImageSample {
|
||||
offset: Some(_),
|
||||
..
|
||||
}
|
||||
)
|
||||
})
|
||||
.count();
|
||||
assert_eq!(offsets, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integer_samplers_read_through_the_float_sampling_functions() {
|
||||
// Mello, Voyager, Exposa, Reverie: `uint mask = texture(colortex3, uv).r` on a usampler2D.
|
||||
|
||||
+49
-1
@@ -2582,12 +2582,60 @@ fn texture_call(
|
||||
ctx.conversion(array_index_expr, meta, Scalar::I32)?;
|
||||
}
|
||||
|
||||
// A texel offset must be a constant expression, but GL drivers also take one a
|
||||
// function gets as a parameter (`const in ivec2 offset`, Arc's FXAA). Such an offset
|
||||
// moves the coordinate by that many texels of the base level instead.
|
||||
let mut coordinate = comps.coordinate;
|
||||
let mut offset = offset;
|
||||
if let Some(by) = offset.filter(|&o| !ctx.local_expression_kind_tracker.is_const(o)) {
|
||||
let size = ctx.add_expression(
|
||||
Expression::ImageQuery {
|
||||
image,
|
||||
query: ImageQuery::Size { level: None },
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
let size = ctx.add_expression(
|
||||
Expression::As {
|
||||
expr: size,
|
||||
kind: Sk::Float,
|
||||
convert: Some(4),
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
let by = ctx.add_expression(
|
||||
Expression::As {
|
||||
expr: by,
|
||||
kind: Sk::Float,
|
||||
convert: Some(4),
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
let shift = ctx.add_expression(
|
||||
Expression::Binary {
|
||||
op: BinaryOperator::Divide,
|
||||
left: by,
|
||||
right: size,
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
coordinate = ctx.add_expression(
|
||||
Expression::Binary {
|
||||
op: BinaryOperator::Add,
|
||||
left: coordinate,
|
||||
right: shift,
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
offset = None;
|
||||
}
|
||||
|
||||
Ok(ctx.add_expression(
|
||||
Expression::ImageSample {
|
||||
image,
|
||||
sampler,
|
||||
gather: None, //TODO
|
||||
coordinate: comps.coordinate,
|
||||
coordinate,
|
||||
array_index,
|
||||
offset,
|
||||
level,
|
||||
|
||||
Reference in new issue
Block a user