Artifacts on smoke trail


I had the base of a pingpong texture swap system set up creating a smoke trail and working great. I wanted to change the background color to something other than black. I think I’m on the right track but there are these wierd artifacts that appear when I draw the smoke, and there’s also a dark line that scrolls up the page continuously… Can anyone see what I’m doing wrong? Any clues would be super appreciated!

my thinking:

  • I create a function that generates a texture that contains a color
function createInitialTexture(renderer) {
    var width = window.innerWidth;
    var height = window.innerHeight;

    var renderTarget = new THREE.WebGLRenderTarget(width, height);
    renderTarget.texture.wrapS = THREE.ClampToEdgeWrapping;
    renderTarget.texture.wrapT = THREE.ClampToEdgeWrapping;
    renderTarget.texture.minFilter = THREE.LinearFilter;

    var gradientScene = new THREE.Scene();
    var gradientCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);

    var geometry = new THREE.PlaneGeometry(2, 2);

    var material = new THREE.ShaderMaterial({
        uniforms: {
            res: { type: "v2", value: new THREE.Vector2(width, height) },
        vertexShader: document.getElementById("vertexShader").textContent,
        fragmentShader: document.getElementById("gradientFragShader").textContent,

    var mesh = new THREE.Mesh(geometry, material);

    renderer.render(gradientScene, gradientCamera);

    return renderTarget.texture;
  • I assign it to one of the ping pong textures here :
function buffer_texture_setup() {
    let initialTexture = createInitialTexture(renderer);

    bufferScene = new THREE.Scene();

    textureA = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter });
    textureB = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter });

    bufferMaterial = new THREE.ShaderMaterial({
        uniforms: {
            bufferTexture: { type: "t", value: initialTexture },
            res: { type: 'v2', value: new THREE.Vector2(window.innerWidth, window.innerHeight) },
            smokeSource: { type: "v3", value: new THREE.Vector3(0, 0, 0) }
        fragmentShader: document.getElementById('fragShader').innerHTML

    plane = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight);
    bufferObject = new THREE.Mesh(plane, bufferMaterial);

    finalMaterial = new THREE.MeshBasicMaterial({ map: textureB.texture });
    quad = new THREE.Mesh(plane, finalMaterial);

full pen is here:

the goal is to get something close to this… I really feel like I’m not so far but I’m definitely stuck :smiling_face_with_tear:


I’m not sure what the exact issue is, but I wonder if the gradient texture needs to be fed into the simulation shader as well? Otherwise it will be “fading out” to black, since the buffers are never getting refreshed with the gradient? So instead of outputting the color, perhaps output a mix of the color + the gradient texture sample?

1 Like

textureA type:THREE.HalfFloatType, textureB type:THREE.HalfFloatType, etc.


oh wow, thank you! I totally missed the types. Much appreciated. :pray: :blush:

1 Like

In my example no additive. Thats why smoke more dark.


Yes I saw! It’s great :slight_smile: I understand a lot better where I was going wrong now.

Some fluids: