Using the result of a Render (inside a Shader) to Render the real scene

Hello, Thanks for your time in advance,

My situation is the next:

I have an object using a shader material, the object is inside a scene. Now, I want to use the rendered scene to generate a cubeMap using a cubeCamera at the center of that scene. Then, I want to use the resultant texture (from that cubeCamera) inside a new shader and render the “real final scene”. That would be all.

I tried with a composer,

var renderPass = new THREE.RenderPass(this.scene, this.camera);
var finalPass = new THREE.ShaderPass(newShaderMaterial);

this.composer.addPass(renderPass);
this.composer.addPass(finalPass);
finalPass.renderToScreen = true;

// inside the animate function

this.composer.render();

The scene have the cubeCamera and the object (using the first shader).
But on the “finalPass” the shader is being excuted per (I need it to be excuted per vertex/fragment and receive the cubeMap generated on the preview pass). Also, the final pass/render is the only one that should be seen. Any tip?

The first shader used do not need uniforms, and the mesh (Object3D) was created using that shader.

let shaderMat = new THREE.ShaderMaterial(normalMapShader);
let mesh = new THREE.Mesh(geometry, shaderMat);

The cube camera was created and included in the scene:

this.cubeCamera = new THREE.CubeCamera(0.1, 1000, 1024);
this.scene.add(this.cubeCamera);

this.cubeCamera.renderTarget.texture.generateMipmaps = false;
this.cubeCamera.renderTarget.texture.magFilter = THREE.NearestFilter;
this.cubeCamera.renderTarget.texture.minFilter = THREE.NearestFilter;
this.cubeCamera.renderTarget.texture.format = THREE.RGBAFormat;
this.cubeCamera.update(this.renderer, this.scene);

And using the composer with just the RenderPass it works as it should, but, first question is: 1) Is the cubeMap already generated? Is it inside this.cubeCamera.renderTarget or this.cubeCamera.renderTarget.texture?

Then, how can I render another scene without affecting the previous cubeMap and using it as a uniform of the newShader?.

What I have been trying:

this.newUniforms = {
	cubeMap: {
		value: null
	},
}

let newShaderMaterial = new THREE.ShaderMaterial(newTracingShader);
newShaderMaterial.uniforms = this.newUniforms;
this.newUniforms.cubeNormalMap.value = this.cubeCamera.renderTarget.texture;

But I couldnt confirm if the texture was passed correctly, and as i said the shader is being executed per pixel instead per vertex/fragment (geometry). Btw, if anyone can teach me how to enclose a piece of code (here, in the forum), I would be grateful :slight_smile:

No, just rendering the scene does not update the cube camera. Like demonstrated in the following example, you have to call CubeCamera.update() per frame. Only then the internal WebGLRenderTargetCube is updated.

https://threejs.org/examples/webgl_materials_cubemap_dynamic

I’ve updated your code with the respective formatting. Just use three ` to start and end a code section.

1 Like