rendiation
rendiation copied to clipboard
Investigate how to express the global scope dependency in wgsl_fn!()
The below example shows too much input in the function definition. This is largely due to the current limitation: we don't support global scope dependency now.
wgsl_fn!(
fn linear_blur(
direction: vec2<f32>,
weights: array<f32, 32>,
weight_count: i32,
texture: texture_2d<f32>,
sp: sampler,
uv: vec2<f32>,
texel_size: vec2<f32>,
) -> vec4<f32> {
let sample_offset = texel_size * direction;
var sum: vec4<f32>;
for (var i: i32 = 2; i < weight_count; i++) {
let samples = textureSample(texture, sp, uv + f32(i) * sample_offset);
sum = lin_space(1.0, sum, weights[i].inner, samples);
}
return sum;
}
);
One promising design may be:
//##uniform weights: array<f32, 32>,
//##uniform weight_count: i32,
//##uniform texture: texture_2d<f32>,
//##uniform sp: sampler,
wgsl_fn!(
fn linear_blur(
direction: vec2<f32>,
sp: sampler,
uv: vec2<f32>,
texel_size: vec2<f32>,
) -> vec4<f32> {
let sample_offset = texel_size * direction;
var sum: vec4<f32>;
for (var i: i32 = 2; i < weight_count; i++) {
let samples = textureSample(texture, sp, uv + f32(i) * sample_offset);
sum = lin_space(1.0, sum, weights[i].inner, samples);
}
return sum;
}
);
At the call site, we expand to this:
impl<'a, T> ShaderGraphProvider for LinearBlurTask<'a, T> {
fn build(
&self,
builder: &mut ShaderGraphRenderPipelineBuilder,
) -> Result<(), ShaderGraphBuildError> {
builder.log_result = true;
builder.fragment(|builder, binding| {
let config = binding.uniform_by(self.config, SB::Material).expand();
let uv = builder.query::<FragmentUv>()?.get();
let size = builder.query::<TexelSize>()?.get();
let blurred = linear_blur {
weights: binding.uniform_by(&self.weights.weights, SB::Material);
weight_count: binding.uniform_by(&self.weights.weight_count, SB::Material);
input: binding.uniform_by(&self.input, SB::Material);
sp: binding.uniform::<GPUSamplerView>(SB::Material);
}.call(
config.direction,
uv,
size,
) // or use the nightly closure feature
builder.set_fragment_out(0, blurred)
})
}
}
The line of code doesn't save, but only for passing the wgsl validation case that:
fn test(a: array<vec4<f32>,8u>) {
for(var i:i32 = 0; i<count; i++){
let a = a[i]; // validation err , must be const expr, even if the a is from uniform..
}
}
var<uniform> global: array<vec4<f32>,8u>;
fn test(a: array<vec4<f32>,8u>) {
for(var i:i32 = 0; i<count; i++){
let a = global[i]; // validation ok
}
}