Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the idiomatic replacement for glsl output parameters in wgsl?

Tags:

wgsl

In glsl and hlsl, I can define a function like this:

float voronoi(vec2 x, out int2 cell) {
    cell = ...
    return ...
}

However, it doesn't seem like this is possible in wgsl.

What's the intended replacement for this? I guess I could define a VoronoiResult struct, but it seems overly boilerplate heavy:

struct VoronoiResult {
    cell: vec2<i32>;
    distance: f32;
};

fn voronoi(x: vec2<f32>) -> VoronoiResult {
    // ...
    var ret: VoronoiResult;
    ret.distance = distance;
    ret.cell = cell;
    return ret;
}
like image 882
bobbaluba Avatar asked Nov 30 '25 02:11

bobbaluba


2 Answers

The equivalent would be to use a pointer argument:

fn voronoi(x: vec2<f32>, cell: ptr<function, vec2<i32>>) -> f32 {
    *cell = vec2(1, 2);
    return 1.f;
}

@compute @workgroup_size(1)
fn main() {
  var a: vec2<i32>;
  var f = voronoi(vec2(1.f, 1.f), &a);
}

This produces the HLSL:

float voronoi(float2 x, inout int2 cell) {
  cell = int2(1, 2);
  return 1.0f;
}

[numthreads(1, 1, 1)]
void main() {
  int2 a = int2(0, 0);
  float f = voronoi((1.0f).xx, a);
  return;
}

You can also make the struct version shorter by using the struct initializer:

struct Out {
  cell: vec2<i32>,
  val: f32,
}

fn voronoi(x: vec2<f32>) -> Out {
    return Out(vec2(1, 2), 1.f);
}

@compute @workgroup_size(1)
fn main() {
  var f = voronoi(vec2(1.f, 1.f));
}
like image 123
dj2 Avatar answered Dec 02 '25 05:12

dj2


The builtin functions modf and frexp, which also need to return two values, solve this by returning structs. In fact, these functions originally returned one of the values via a pointer, but were changed to return a struct after some discussion.

So I guess returning a struct can now be considered idiomatic.

like image 29
dpi Avatar answered Dec 02 '25 03:12

dpi