8

I'm using AFrame to make a 360 panorama viewer, and I made a custom component to use a cubemap for the sky.

The texture with the 6 cube faces is loaded by a THREE.CubeTextureLoader and then I execute the following code.

var shader = THREE.ShaderLib['cube'];
shader.uniforms['tCube'].value = texture;

var skyBoxMaterial = new THREE.ShaderMaterial({
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: shader.uniforms,
    depthTest: false,
    side: THREE.BackSide,
    transparent: true
});

var size = 1000;
var skyBoxGeometry = new THREE.CubeGeometry(size, size, size);

return new THREE.Mesh(skyBoxGeometry, skyBoxMaterial);

It returns the object that I use on my entity with the setObject3D function.

With version 0.9.2 of AFrame (which uses v0.102.2 of Three) this code works perfectly and I get the cube as intended. With version 1.0.1 (which uses v0.111.5), I get a problem cause ShaderLib was modified and the tCube uniformd does not exist anymore. I saw that there's an envMap uniform apparently serving the same purpose but when I set my texture on this attribute, I get WebGLProgram shader errors in the console

index.js:27291 THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog invalid shaders
THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:308: 'envColor' : undeclared identifier
ERROR: 0:308: '=' : dimension mismatch
ERROR: 0:308: 'assign' : cannot convert from 'const highp float' to 'FragColor mediump 4-component vector of float'

Did anyone experiment the same issue or can help me on how to resolve it please? Do I need to manage my texture differently or is there an alternative to this use of shaders for a cubemap ?

Thanks!

1 Answers1

7

Try to enhance your code with this snippet:

Object.defineProperty( skyBoxMaterial, 'envMap', {

    get: function () {

        return this.uniforms.envMap.value;

    }

} );

BTW: It's highly recommended to use Scene.background if you need a skybox. In your case:

scene.background = texture;

three.js R111

Mugen87
  • 28,829
  • 4
  • 27
  • 50
  • Thanks @Mugen87 ! I just needed to remove the .material from your code snippet to make it work :) Could you explain why this line was not needed in the previous version? I know about scene.background but it does not fit my needs as I want to manage fades between scenes and it requires that I load 2 cubemaps and make one fade out as the other one fades in. – Stéphane Albanese Dec 23 '19 at 12:34
  • Sorry, for the typo. I've edited the answer in order to correct the code. `three.js` has refactored the way (PBR) environment maps are implemented. The cube shader is actually intended for internal use so the change was not explicitly noted in the [migration guide](https://github.com/mrdoob/three.js/wiki/Migration-Guide). – Mugen87 Dec 23 '19 at 13:13
  • Hello @Mugen87, sorry to bring back this issue but now I got something weird with R116 after upgrading aframe. In the function I do var shader = Object.assign({}, THREE.ShaderLib['cube']); shader.uniforms.envMap.value = texture; to initialise the shader and then set the texture, which works fine, but what I noticed since the upgrade is that if I have two instances of the cubemap (with different ids and textures), they now share the same texture, which was not the case before. Was there a significant change that could explain this behaviour? – Stéphane Albanese Jun 17 '20 at 10:01
  • There were changes to envMap related code however I can't tell you how it affects the usage of custom sky boxes. Any chances to demonstrate the issue with a live example https://jsfiddle.net/6o28xgkq/ (possibly without a-frame)? – Mugen87 Jun 17 '20 at 10:24
  • I kinda made a framework around aframe with custom components and everything so I need to extract the relevant parts to build an example but I'll do that, thanks! Just to add information, what I noticed is that the Mesh objects of my cubemaps had different ids, it was just the shader that was shared, as if the shader object was not cloned but referenced instead. The goal of my Object.assign was precisely to avoid that, which worked fine before the update. I'll comment again when I have a bare three js example, thanks for your help :) – Stéphane Albanese Jun 17 '20 at 10:43
  • Hi @Mugen87, I made a jsfiddle as requested and manage to reproduce the issue, here it is : https://jsfiddle.net/e67d03po/21/ Thanks a lot for your help, it's really appreciated, have a nice day – Stéphane Albanese Jun 18 '20 at 08:56
  • 1
    Okay, I bothered you for nothing, I understood what's wrong while writing and reading the ShaderLib code a bit more. It was a problem of referencing instead of cloning. I fixed it like this and it works perfectly : https://jsfiddle.net/ty85a4Ln/ At least I understood something new :) Sorry for bothering you and thanks for the help! Cheers – Stéphane Albanese Jun 18 '20 at 09:15