1

The docs for scene say a color or texture can be used for scene.background. I would like to use a ShaderMaterial with my own custom shaders. How can I do this?

Specifically, I want to paint a color ramp behind the foreground elements. Here is the fragment shader:

uniform vec2 uXYPixel;
void main() {
    vec2 xy = vec2(gl_FragCoord.x/uXYPixel.x, gl_FragCoord.y/uXYPixel.y);
    gl_FragColor.rgb = vec3(xy.x, xy.y, 0);
    gl_FragColor.a = 1.0;
}

uXYPixel is a uniform vec2 with the values window.innerWidth, window.innerHeight

dugla
  • 12,774
  • 26
  • 88
  • 136
  • 1
    An answer was also provided here: https://discourse.threejs.org/t/how-to-i-use-a-material-for-scene-background-rather-then-color-or-texture/6477 – Mugen87 Mar 10 '19 at 19:03
  • Yep. Not supported. I'll have to try another approach. – dugla Mar 10 '19 at 20:40
  • maybe you could have the three.js scene transparent the use something like [this (shaderback.js)](https://github.com/llewelld/shaderback.js) for the background – 2pha Mar 12 '19 at 00:48
  • I have a working example here: https://turner.github.io/cameraplane/. I discuss the issues with the three.js implementation over on discord here https://discourse.threejs.org/t/using-orbitcontrols-with-manual-object-transformation-causes-a-wobbling-object/6606/4. Video is here: https://www.youtube.com/watch?v=4g0lQPC4RbE – dugla Mar 18 '19 at 13:55

1 Answers1

1

You'd need to manually create two render passes. One that renders the background plane with a simple Camera, and the second one that renders the rest of the scene. You can use the most basic Camera class since you won't be using transformation or projection matrices:

// Set renderer with no autoclear
var renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
document.body.append(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);

// Set up background scene
var bgScene = new THREE.Scene();
var bgCam = new THREE.Camera();
var bgGeom = new THREE.PlaneBufferGeometry(2, 2);
var bgMat = new THREE.ShaderMaterial({
    // Add shader stuff in here
    // ..
    // Disable depth so it doesn't interfere with foreground scene
    depthTest: false,
    depthWrite: false
});
var bgMesh = new THREE.Mesh(bgGeom, bgMat);
bgScene.add(bgMesh);

// Set up regular scene
var scene = new THREE.Scene();
var cam = new THREE.PerspectiveCamera(45, w/h, 1, 100);

function update() {
    // Clear previous frame
    renderer.clear();

    // Background render pass
    renderer.render(bgScene, bgCam);

    // Foreground render pass
    renderer.render(scene, cam);

    requestAnimationFrame(update);
}

update();

Here you can see a working example.

Notice that the renderer's autoClear = false attribute makes sure it doesn't clear the buffer in between each render() call; you'll have to clear it manually at the beginning of each frame.

M -
  • 26,908
  • 11
  • 49
  • 81
  • Thanks. Marquizzo. I'll give you this one. I am actually going a different route. I will use a technique I've implemented before. I position a quad at the camera "far" distance and keep it oriented orthogonal to the camera. This allows me total flexibility. I can even place a translucent plane at the "near" distance for interesting overlay looks. I'll post the code on discourse when I have it ported to three.js. – dugla Mar 12 '19 at 21:13
  • That's a good alternative! You should post the answer here too so others can learn from your approach. – M - Mar 12 '19 at 22:03
  • Yep. Will do. Cheers. – dugla Mar 13 '19 at 13:40
  • I have a working example here: https://turner.github.io/cameraplane/. I discuss the issues with the three.js implementation over on discord here https://discourse.threejs.org/t/using-orbitcontrols-with-manual-object-transformation-causes-a-wobbling-object/6606/4. Video is here: https://www.youtube.com/watch?v=4g0lQPC4RbE – dugla Mar 18 '19 at 13:51
  • The remaining issue I am having is the camera transform is out of sync with the manually applied transform to the backdrop quad resulting in objectionable wobbling and jiggling of the backdrop. Not sure why this is happening. – dugla Mar 18 '19 at 13:55