Why readPixels get wrong data from RenderTargetTexture?

I’m trying to use RenderTargetTexture to get the output of a custom shader (for learning with general computing)

I display the results of readPixels on another mesh. The phenomenon looks normal, but there are obvious errors in the data.

I can’t get the correct pixel color, such as red/green, maybe it’s a color space conversion issue? But I didn’t find the right solution

The colors are obviously wrong in some areas (there shouldn’t be a continuous white/black color) and I can’t confirm the cause of the problem

Here is the PG:

Here’s what I’m seeing:

I think it’s ok?

The issue is how you create your rawtexture here, you need to provide channels separately with the according type: https://playground.babylonjs.com/#IDSCIG#2

1 Like

The correct color is this

Yes, this is a solution, but is there no way to support unsigned int type input?

    const colorMap = new Uint8ClampedArray(
    // [
    //     0xff0000ff, 0x00ff00ff, 0x0000ffff, 0xffff00ff, 0xff00ffff, 0x00ffffff, 0x000000ff, 0xffffffff,
    //     0xf0f0f0ff
    // ]
    
    [ 255, 0,   0,   255,
      0,   255, 0,   255,
      0,   0,   255, 255,

      255, 255, 0,   255,
      255, 0,   255, 255,
      0,   255, 255, 255,

      0,   0,   0,   255,
      255, 255, 255, 255,
      127, 127, 127, 255,
    ])
    const inTex = BABYLON.RawTexture.CreateRGBATexture(
        colorMap,
        3,
        3,
        scene,
        false,
        false,
        BABYLON.Texture.NEAREST_SAMPLINGMODE,
        BABYLON.Engine.TEXTURETYPE_UNSIGNED_BYTE
    )

Because my input is not color, but needs to be calculated, so unsigned int or float is what I need.

I also made some strange discoveries

  1. If the size of the ground mesh is set to 1, the obtained RTT will be stretched strangely and cannot be applied correctly to the new ground mesh.

    // var ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 5, height: 5 }, scene)
        var ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 1, height: 1 }, scene)
    
    Screenshots of my local experiment
    

    https://playground.babylonjs.com/#IDSCIG#4

  2. If I continue to reduce the size of the RTT (say 10*10), the correct data will not be read

     // render to texture
     // const renderTarget = new BABYLON.RenderTargetTexture(
     //     'rtt',
     //     100,
     //     scene,
     //     false,
     //     false
     //     // BABYLON.Constants.TEXTURETYPE_FLOAT
     // )
     const renderTarget = new BABYLON.RenderTargetTexture(
         'rtt',
         10,
         scene,
         false,
         false
         // BABYLON.Constants.TEXTURETYPE_FLOAT
     )
    

    Screenshots of my local experiment

    https://playground.babylonjs.com/#IDSCIG#5

I’m not sure what you want to achieve in 1. Do you want the color block to fill the entire plan?

Regarding 2, the plane rendered in the 10x10 rtt is too small and is not even a pixel wide/tall, so it does not appear.

You can use a float texture like this:

1 Like

Thanks, regarding 1, I want the entire area to be filled (or I don’t understand why the entire area is not filled)

If you want to fill the whole texture, you will have to create an additional camera and set it to the rtt (renderTarget.activeCamera = your_camera). You will have to calculate the parameters of this camera so that, when rendered, your mesh fills the whole texture.

Thank you, that’s the reason