Three.js。如何为场景背景而不是颜色或纹理使用自定义 material?
Three.js. How do I use a custom material for a scene background rather then color or texture?
scene
的文档说颜色或纹理可用于 scene.background
。我想将 ShaderMaterial
与我自己的自定义着色器一起使用。我该怎么做?
具体来说,我想在前景元素后面绘制一个色带。这是片段着色器:
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
是具有值 window.innerWidth
、window.innerHeight
的 uniform
vec2
您需要手动创建两个渲染通道。一个用简单的 Camera
渲染背景平面,第二个渲染场景的其余部分。您可以使用最基本的 Camera class,因为您不会使用变换或投影矩阵:
// 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.
请注意,渲染器的 autoClear = false
属性确保它不会在每次 render()
调用之间清除缓冲区;你必须在每帧开始时手动清除它。
scene
的文档说颜色或纹理可用于 scene.background
。我想将 ShaderMaterial
与我自己的自定义着色器一起使用。我该怎么做?
具体来说,我想在前景元素后面绘制一个色带。这是片段着色器:
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
是具有值 window.innerWidth
、window.innerHeight
uniform
vec2
您需要手动创建两个渲染通道。一个用简单的 Camera
渲染背景平面,第二个渲染场景的其余部分。您可以使用最基本的 Camera class,因为您不会使用变换或投影矩阵:
// 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.
请注意,渲染器的 autoClear = false
属性确保它不会在每次 render()
调用之间清除缓冲区;你必须在每帧开始时手动清除它。