Set SamplerCube uniform from cubemap asset

How can I set a uniform of type ‘samplerCube’ in a custom shader given an asset of type ‘cubemap’ ?

I tried

// ...
MyScript.attributes.add('reflectionTexture', {
    type: 'asset',
    assetType: 'cubemap',
    title: 'reflectionTexture',
    description: 'reflection cubemap'

// ...

    graphicsDevice.scope.resolve("uSomeMatrix").setValue(; // works
    graphicsDevice.scope.resolve("uSomeFloat").setValue(1.0); // works

    // but how to set samplerCube?
    //graphicsDevice.scope.resolve("uSomeSamplerCube").setValue(this.reflectionTexture); // does not work
    //graphicsDevice.scope.resolve("uSomeSamplerCube").setValue(; // does not work
    //graphicsDevice.scope.resolve("uSomeSamplerCube").setValue(this.reflectionTexture.resource); // does not work
    //graphicsDevice.scope.resolve("uSomeSamplerCube").setValue(this.reflectionTexture.resources); // does not work

// rendercode...

so, how do I properly set a samplerCube uniform on the graphics device before rendering?

Hello! This is how I use cubemap attribute from script in FS:

In my case, I am making my own shader, so I am setting parameters on my material (I am not so sure about your graphicsDevice.scope.resolve("uSomeUniform").setValue(someValue), never saw or used that.

But setting cubemap as uniform attribute is done as any other parameter:
this.material.setParameter('uCubemap', this.cubemap.resource);

Thanks but I’m not using materials, as I’m using GraphicsDevice.draw() to render primitives and I’m using custom shaders (that I set with GraphicsDevice.setShader).

Okay, well anyway you you are setting uniforms through graphicsDevice.scope it should work the same way as setting it through material. Just a question - what do you mean exactly by ‘does not work’? When you try textureCube() in GLSL, is your mesh all black? I had this same issue and figured out it was due to using default playcanvas cubemap (heliport) as my input cubemap for the shader, when the cubemap was prefiltered and in Playcanvas render settings it had Mip value set to 2. When changed back to 1, it worked.

The model does not render at all and I’m getting the following GLSL errors:

[.Offscreen-For-WebGL-000001F27635CC70]RENDER WARNING: there is no texture bound to the unit 0
[.Offscreen-For-WebGL-000001F27635CC70]GL ERROR :GL_INVALID_OPERATION : glTexImage2D: <- error from previous GL command
[.Offscreen-For-WebGL-000001F27635CC70]GL ERROR :GL_INVALID_OPERATION : glFramebufferTexture2D: <- error from previous GL command
WebGL: too many errors, no more errors will be reported to the console for this context.

This is my test fragmentshader:

varying mediump vec4 vUvgrab;

uniform sampler2D uSomeTexture;
uniform samplerCube uSomeSamplerCube;

void main(void)
    lowp vec4 col = texture2DProj(uSomeTexture, vUvgrab);
    lowp vec4 refraction = textureCube(uSomeSamplerCube, vec3(1,0,0));    
    gl_FragColor = col;

It doesn’t really matter whether or not I use ‘refraction’ in the final gl_FragColor (so if I return for example col + refraction, the result is the same). The shader compiles, but the model doesn’t render and I’m getting above warnings/errors. If I uncomment the line with the textureCube() call, then my model renders yellow as expected (uSomeTexture is a 1x1 pixel yellow texture) and there are no warnings/errors.

//edit: IFF I prefilter the cubemap, the app won’t start at all and I’m getting a

Error loading scripts. Open the browser console for details.

with the following in the console:

Uncaught RangeError: Invalid typed array length: 32
    at new Uint32Array (<anonymous>)
    at (playcanvas-stable.dbg.js:34825)
    at ResourceLoader.<anonymous> (playcanvas-stable.dbg.js:33939)
    at Object.callback (playcanvas-stable.dbg.js:34764)
    at Object._onSuccess (playcanvas-stable.dbg.js:20888)
    at Object._onReadyStateChange (playcanvas-stable.dbg.js:20850)
    at Object.<anonymous> (playcanvas-stable.dbg.js:20805)
1 Like

Got the same error. Cubemap here is much more difficult to use than Unity

By changing the cubemap’s textures’ compression setting, delete and re-prefilter, switching scene’s skybox, it somehow fixed tthe “Uncaught RangeError: Invalid typed array length: 32” problem. but i still can’t make my shader use the correct lod of cubemap