Render ALL decals from a for loop into a refraction texture

I have a plane, on which I project decals out of a for loop.
Then I create a refraction texture, so want to push the decal into the render list.

How can I get all the generated decals from this loop into the texture?

At the moment only - I think one, the last - is rendered into the refraction texture.

I am not a programmer, so excuse this question. I think I know technically why that is, but I cannot program it. :wink:

Cheers for hints.
Thanks. Werner

Hi yamaciller,

It’s very difficult to tell what might be going on from a verbal description alone. I searched for RefractionTexture Playgrounds and found one that I modified to refract two targets, one of which is a red checkerboard (the “texture failed to load” checkerboard, in fact) and the other is a moving grey square.

Refraction | Babylon.js Playground (babylonjs.com)

The code dealing with the RefractionTexture itself is on lines 41 through 47. Does this approach work for your scenario?

Thank you for the answer.
Basically my question is regarding a decal object, which is created in a for loop to have multiple decals. To push that into a render texture, so that all the decals from the array are visible in the render texture.
At that point, only the last decal which comes from the array is visible in the texture.

But I should not call the refraction texture in the loop?
hmm.

    const decalPositions = [
        new BABYLON.Vector3(0.1,0.0,0), 
        new BABYLON.Vector3(-0.1,0,0),
        new BABYLON.Vector3(-0.12,0.0,0.15)

    ];

    const decalSizes = [
        new BABYLON.Vector3(0.3,0.12,1), 
        new BABYLON.Vector3(0.3,0.12,1),
        new BABYLON.Vector3(0.1,0.12,1)
        

    ];

    const decalRot = [  1.5707,
                        1.5707,
                        0.8007

                     ];

    for(let i=0;i<decalPositions.length;i++)
    {
        var decal = BABYLON.MeshBuilder.CreateDecal("decal_" + i, groundMesh,
        {position: decalPositions[i], angle: decalRot[i], size: decalSizes[i]}, scene);
        decal.material = decalMaterial;
    }
    
    // Refraction Texture

    var refractionTexture = new BABYLON.RefractionTexture("th", 1024, scene);
    refractionTexture.renderList.push(groundMesh);
    refractionTexture.renderList.push(decal);
    refractionTexture.refractionPlane = new BABYLON.Plane(0, 0.0, 0, 0);
    refractionTexture.depth = 2.0;

Best. Werner

Gotcha, I think this is just a programming bug. Your variable decal is declared inside your for loop and is set to a new decal every time the loop executes, but you push the contents of that variable to refractionTexture.renderList outside the for loop. Thus, the push operation happens only once, after the loop has run and when the decal contains only the final decal. Most languages would warn you about this by telling you decal is out of scope when you try to push it, but JavaScript is kind of squishy this way. :slight_smile:

All you should have to do to fix this is move the ...push(decal) line inside your for loop, probably making it the last line of the loop. That will cause that line to be executed for every decal, not just the last one, which will cause them all to be added to the render list.

1 Like

Phantastique. Does exactly what you decribed.
Unfortunately I lack of basic programming knowledge.
But I will get better ;).
Thank you, I am very happy.
Best. Werner