videoTexture on iOS is very bright / "washed-out"

Hi everyone,

Since upgrading to PlayCanvas Engine 2.0 (currently 2.23.1), videos loaded from external URLs appear washed out and desaturated on iOS. The same videos looked correct before the upgrade, and other scene materials render correctly.

I’m using a dynamically created pc.Texture with videoTexture.setSource(video) and displaying it through a StandardMaterial’s emissiveMap.

I’ve tried both PIXELFORMAT_R8_G8_B8 and PIXELFORMAT_SRGBA8, as well as disabling tone mapping on the material, but the issue persists on iOS. Android and desktop work correctly with SRGBA8.

Could this be related to sRGB handling or video texture uploads in Engine 2.0? Is there a recommended configuration or known issue?

// Create a texture to hold the video frame data

    this.videoTexture = new pc.Texture(app.graphicsDevice, {

        // format: pc.PIXELFORMAT_R8_G8_B8,

        format: pc.PIXELFORMAT_SRGBA8,

        srgb: true,  

        // minFilter: pc.FILTER_LINEAR_MIPMAP_LINEAR,

        minFilter: pc.FILTER_LINEAR,

        magFilter: pc.FILTER_LINEAR,

        addressU: pc.ADDRESS_CLAMP_TO_EDGE,

        addressV: pc.ADDRESS_CLAMP_TO_EDGE,

        mipmaps: false

    });




    this.videoTexture.setSource(video);

The material configuration via script:

  this.app.on(this.playEvent, function (videoTexture) {

        var material = this.screenMaterial.resource;

        material.emissiveMap = videoTexture;

        material.emissive.set(1, 1, 1);

        material.emissiveVertexColor = false;

        material.vertexColorGamma = false;

        material.useTonemap = false;

        material.update();

    }, this);

I haven’t been able to figure out the cause of the issue on iOS. I’ve tried different texture formats, checked the material settings, and disabled other rendering options, but nothing has fixed it.

Since last year’s video also looks washed out now, even though it rendered correctly before, I suspect this might be related to the Engine 2.0 update rather than the video files themselves.

Thanks for any ideas or suggestions!

Not sure what the problem is, see if the example gives you some ideas: PlayCanvas Examples

But you seem to be doing the right thing.

Are you saying this is a problem on iOS only, but not elsewhere?

@mvaligursky

Yes, it’s weird. I’m loading a video from a URL, and with the current setup, it looks fine in Android and desktop browsers. However, on iOS, the video appears washed out.

I didn’t have this issue with Engine V1, which I tested using last year’s video. The problem seems to occur with Engine V2.

I also took screenshots of the same scene from the video on both devices. The iOS screenshot looks brighter and more washed out, while the Android screenshot has the correct, more saturated colors. It’s the exact same video, but it looks noticeably different on iOS.

How it should look / Android:

iOS:

Note: on the specific iOS devices it is much more recognizable - basically its a customer feedback i have to fix.

I got an agent to look at this, and this is the result, please try it.

This is a WebKit bug: uploading a video to an sRGB texture format (SRGB8_ALPHA8) skips the sRGB-to-linear conversion, so the colours end up gamma-encoded twice and look washed out: 222822 – WebGL2: Video upload to SRGB8_ALPHA8 does not match upload to SRGB8

Note that srgb: true converts any format you pass to its sRGB variant, so your R8_G8_B8 test was actually SRGB8 as well.

The workaround is to use a non-sRGB format without the srgb flag. The engine then decodes gamma in the shader, which avoids Safari’s broken path and looks the same on all platforms:

this.videoTexture = new pc.Texture(app.graphicsDevice, {
    format: pc.PIXELFORMAT_RGBA8,
    minFilter: pc.FILTER_LINEAR,
    magFilter: pc.FILTER_LINEAR,
    addressU: pc.ADDRESS_CLAMP_TO_EDGE,
    addressV: pc.ADDRESS_CLAMP_TO_EDGE,
    mipmaps: false
});

This is also what the video texture example does.