我想缓存一个帧,然后根据这个帧渲染另一个场景,该怎么做?
我设置了两个场景,一个是物理场景,一个是光标场景,因为物理场景可能不会改变。
现在我使用2个画布,一个在顶部,并使用透明背景来解决问题。
let canvas = document.createElement("canvas");
canvas.style.position = "absolute"
canvas.style.zIndex = "100px";
canvas.style.pointerEvents = "none";
canvas.style.width = "100%";
canvas.style.height = "100%";
canvas.style.left = "0px";
canvas.style.top = "0px";
el.appendChild(canvas);
render = new THREE.WebGLRenderer({ canvas: canvas, clearColor: 0, alpha: true })
答案 0 :(得分:2)
如果我正确理解你,你想渲染一个场景,然后在第一个场景的顶部渲染第二个场景。这实际上很容易做到,尽管你可以通过执行错误的操作轻易地导致意外结果。
首先,告诉渲染器不要自动清除缓冲区:
renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true });
renderer.autoClear = false;
接下来,在渲染第一个场景之前,您需要手动清除缓冲区。如果你不清楚这里,那么上一张图片将保留在画布上。
renderer.clear();
renderer.render(scene1, camera1);
渲染第一个场景时,您需要确保第二个场景将在第一个场景的顶部渲染。调用renderer.clear();
会导致它删除第一个场景。相反,您只想清除深度缓冲区。这将删除渲染器之前的所有深度信息,并使其在旧的像素之上绘制所有新像素。
renderer.clearDepth();
renderer.render(scene2, camera2);
无法清除深度缓冲区意味着渲染器会记住所有scene1
对象的位置(空间),并且它会将scene2
对象渲染为好像它们占用与{{scene1
相同的空间1}}。
此时,您应该看到第一个场景呈现在第一个场景之上,并且它们都被绘制到同一个画布上。
如果您有任何疑问,或希望我扩展上述任何步骤,请在下方发表评论。
three.js r88
<强>更新强>
这似乎是一种hacky方式,所以如果有人有更好的想法,请加入。我在下面的代码中做的是使背景渲染为可选,并使用第一个渲染的场景作为画布背后的背景。在我的例子中,我允许背景每1~1渲染一次。仍可以requestAnimationFrame
允许的完整帧速率操作红色立方体。
有几点需要注意:
如果要捕获完整渲染的图像,必须在渲染renderWithBackground === true
后捕获。在所有其他情况下,画布实际上只包含scene2
。
此外,第一帧渲染黑色背景,我不知道为什么。我现在还没有时间继续调试它。
var renderer, scene1, scene2, camera1, camera2, controls, bgCube, fgCube;
var renderWithBackground = true;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
function populateScenes() {
var cubeGeo1 = new THREE.BoxBufferGeometry(15, 15, 15),
cubeMat1 = new THREE.MeshPhongMaterial({
color: "green"
});
bgCube = new THREE.Mesh(cubeGeo1, cubeMat1);
scene1.add(bgCube);
var cubeGeo2 = new THREE.BoxBufferGeometry(5, 5, 5),
cubeMat2 = new THREE.MeshPhongMaterial({
color: "red"
});
fgCube = new THREE.Mesh(cubeGeo2, cubeMat2);
scene2.add(fgCube);
}
function init() {
document.body.style.backgroundColor = "slateGray";
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
document.body.style.overflow = "hidden";
document.body.style.margin = "0";
document.body.style.padding = "0";
scene1 = new THREE.Scene();
scene2 = new THREE.Scene();
camera1 = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera1.position.z = 50;
scene1.add(camera1);
camera2 = camera1.clone();
scene2.add(camera2);
controls = new THREE.TrackballControls(camera2, renderer.domElement);
controls.dynamicDampingFactor = 0.5;
controls.rotateSpeed = 3;
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera1.add(light);
camera2.add(light.clone());
setInterval(function() {
renderWithBackground = true;
}, 1000);
resize();
window.onresize = resize;
populateScenes();
animate();
}
function resize() {
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
if (renderer && camera1 && camera2 && controls) {
renderer.setSize(WIDTH, HEIGHT);
camera1.aspect = WIDTH / HEIGHT;
camera1.updateProjectionMatrix();
camera2.aspect = WIDTH / HEIGHT;
camera2.updateProjectionMatrix();
controls.handleResize();
}
}
function render() {
renderer.clear();
if (renderWithBackground) {
renderWithBackground = false;
renderer.render(scene1, camera1);
document.body.style.backgroundImage = "url('" + renderer.domElement.toDataURL() + "')";
renderer.clearDepth();
}
renderer.render(scene2, camera2);
}
function animate() {
bgCube.rotation.x += 0.001;
bgCube.rotation.y += 0.002;
bgCube.rotation.z += 0.003;
requestAnimationFrame(animate);
render();
controls.update();
}
function threeReady() {
init();
}
(function() {
function addScript(url, callback) {
callback = callback || function() {};
var script = document.createElement("script");
script.addEventListener("load", callback);
script.setAttribute("src", url);
document.head.appendChild(script);
}
addScript("https://threejs.org/build/three.js", function() {
addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() {
addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {
threeReady();
})
})
})
})();
&#13;