Skip to content

TSL: Missing features, memory leaks, unexpected behavior #32969

@gkjohnson

Description

@gkjohnson

Description

I recently took dive into compute and found quite a few issues or at least unexpected behaviors I wanted to share. If desired I can make dedicated issues for any of these with more details but I figured I'd make a single list first:

  • 1. "StorageBufferAttributes" cannot be disposed

When creating a compute kernel that operations on a StorageBufferAttribute and you want to resize it, it seems to not be possible to dispose of the original StorageBufferAttribute, presumably leaving GPU memory and / or three.js references orphaned. I expected to be able to call "dispose" as we do with textures.

  • It seems there are memory leaks elsewhere, as well, such as "getArrayBufferAsync" returning a new buffer every call, but this deserves a dedicated issue I think.

  • 2. Read / Write storage buffers seem to not work in fragment shaders

Trying to use a "read/write" storage buffer throws an error saying a "read" buffer is expected. See this fiddle.

const material = new THREE.MeshBasicNodeMaterial();
const storeTex = TSL.textureStore( new THREE.StorageTexture( 1, 1 ) ).toReadWrite();
material.colorNode = TSL.wgslFn( /* wgsl */`
    fn test( storeTex: texture_storage_2d<rgba8unorm, read_write> ) -> vec4f {
        return vec4f( 1.0, 0, 0, 1 );
    }
` )( { storeTex } );
  • 3. Textures seem to not be sample-able in wgslFn

I may be misunderstanding something but when I pass a texture uniform and sampler to a wgslFn like so I'm seeing an error that the sampler is not found. See this fiddle.

const texNode = TSL.uniformTexture( tex );
const samplerNode = TSL.sampler( tex );
material.colorNode = TSL.wgslFn( /* wgsl */`
    fn test(
        tex: texture_2d<f32>, 
        smp: sampler
    ) -> vec4f {
        // return textureSample( tex, smp, vec2f( 0.0 ) );
        return vec4f( 1.0, 0, 0, 1 );
    }
` )( { tex: texNode, smp: samplerNode } );
  • 4. Reusing disposed storage textures causes an error

When rendering a material with a storage texture as the color node it will throw an error if disposed and reused. See this fiddle.

const storageTex = new THREE.StorageTexture( 1, 1 );
const material = new THREE.MeshBasicNodeMaterial();
material.colorNode = TSL.texture( storageTex, TSL.varying( TSL.uv() ) );

// first render works
const mesh = new THREE.Mesh( geometry, material );
const camera = new THREE.PerspectiveCamera();
renderer.render( mesh, camera );

// adjusting the size of the storage texture or resizing it an error
storageTex.setSize( 10, 10 );
renderer.render( mesh, camera );
  • 5. textureStore, storage nodes cannot be initialized to null

When initializing a reusable kernel / shader it's nice to be able to initialize values to "null", as you can with texture uniforms, so they can be assigned later before initial use rather than having to create a dummy buffer. See this fiddle

I ran into some other issues, as well, but I'll have to work on understanding how to reproduce them more simply.

Reproduction steps

See above

Code

See above

Live example

See above

Screenshots

No response

Version

r182

Device

No response

Browser

No response

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    TSLThree.js Shading Language

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions