The nodes certainly do not cover the entire range of functions of WGSL. The “textureStore” node came with r156. Sunag kindly developed this when I asked for it and merged it into r156. But now with r157 there will be something else that will improve the work with it, the StorageTexture class. That’s really great. In my opinion, this makes DataTextures obsolete. With the node system as it currently is, I can do everything I did before in glsl.
Here is a wgsl example in r156 from me. But I will adapt that with r157, because the StorageTexture class that comes with r157 will be more practical than the THREE.Texture()
const butterflyWGSL = wgslFn(`
fn computeWGSL(
storageTex: texture_storage_2d<rgba8unorm, write>,
index: u32,
resolution: f32,
) -> void {
var posX = index % u32(log2(resolution));
var posY = index / u32(resolution);
let indexUV = vec2u( posX, posY );
let N: f32 = resolution;
var k: f32 = (f32(posY) * N/pow(2, f32(posX) + 1)) % N;
var twiddle: vec2<f32> = vec2<f32>(cos(2 * PI * k / N), sin(2 * PI * k / N));
var butterflyspan: f32 = pow(2, f32(posX));
var butterflywing: u32 = 0;
if(f32(posY) % pow(2, f32(posX) + 1 ) < pow(2, f32(posX))){
butterflywing = 1;
}
else{
butterflywing = 0;
}
if(u32(posX) == 0){
if(butterflywing == 1){
textureStore(storageTex, indexUV, vec4f(twiddle.x, twiddle.y, f32(bitReverse(posY)), f32(bitReverse(posY + 1))));
}
else{
textureStore(storageTex, indexUV, vec4f(twiddle.x, twiddle.y, f32(bitReverse(posY - 1)), f32(bitReverse(posY)) ));
}
}
else{
if(butterflywing == 1){
textureStore(storageTex, indexUV, vec4f(twiddle.x, twiddle.y, f32(posY), f32(posY) + butterflyspan ));
}
else{
textureStore(storageTex, indexUV, vec4f(twiddle.x, twiddle.y, f32(posY) - butterflyspan, f32(posY) ));
}
}
}
const PI: f32 = 3.141592653;
fn bitReverse(value: u32) -> u32 {
var numBits: u32 = 32u;
var result: u32 = 0u;
for(var i: u32 = 0u; i < numBits; i = i + 1u){
result = result | (((value >> i) & 1u) << (numBits - 1u - i));
}
return result;
}
`);
this.butterflyParams = {
resolution: 512,
workgroup_size: [1, 16, 1],
}
this.butterflyTexture = new THREE.Texture();
this.butterflyTexture.image = {width: Math.log2(this.butterflyParams.resolution), height: this.butterflyParams.resolution};
this.butterflyTexture.magFilter = this.butterflyTexture.minFilter = THREE.NearestFilter;
this.butterflyCall = butterflyWGSL({
storageTex: textureStore(this.butterflyTexture),
index: instanceIndex,
resolution: this.butterflyParams.resolution,
});
this.computeButterfly = this.butterflyCall.compute(this.butterflyParams.resolution * this.butterflyParams.resolution);
this.renderer.compute(this.computeButterfly, this.butterflyParams.workgroup_size);
If you want to change uniforms as usual in glsl, you have to define them as such. In my case here, the “resolution: 512” in the params are a constant that cannot be changed.
Here I have a simple example of where I use the time. I can then use this as a uniform as usual:
The node system is already very advanced. And it is very well thought out. The developers have done a very good job 