Javascript 在THREE.js(3D渲染目标)中使场景成为3D纹理

Javascript 在THREE.js(3D渲染目标)中使场景成为3D纹理,javascript,three.js,webgl,Javascript,Three.js,Webgl,我正在看THREE.js示例,想知道如何防止渲染为纹理的场景“变平”。换句话说,当设置为WebGLRenderTarget时,场景将失去具有深度的错觉 我到处都找过了,包括在THREE.js文档中,没有发现有人提到这种功能,可能是因为它会给用户的处理器带来不必要的巨大负载(非常特殊的情况除外)。也许这在纯WebGL中是可能的 编辑:下层选民-为什么这个问题很糟糕?我对这件事做了重要的研究,但由于我是WebGL的新手,我无法准确地说出无意义的代码。。。如何改进我的查询?因为THREE.js会“展平

我正在看THREE.js示例,想知道如何防止渲染为纹理的场景“变平”。换句话说,当设置为
WebGLRenderTarget
时,场景将失去具有深度的错觉

我到处都找过了,包括在THREE.js文档中,没有发现有人提到这种功能,可能是因为它会给用户的处理器带来不必要的巨大负载(非常特殊的情况除外)。也许这在纯WebGL中是可能的

编辑:下层选民-为什么这个问题很糟糕?我对这件事做了重要的研究,但由于我是WebGL的新手,我无法准确地说出无意义的代码。。。如何改进我的查询?

因为THREE.js会“展平”它渲染的每个场景,所以所需要的只是改变透视(相对于主场景的主摄影机),以保持渲染目标中的深度错觉。这里有一个可以做到这一点的框架:

var scene = new THREE.Scene(),
    rtScene = new THREE.Scene(),
    camera = new THREE.PerspectiveCamera( ..... ),
    rtCamera = new THREE.PerspectiveCamera( ..... ),
    rtCube = new THREE.Mesh(new THREE.CubeGeometry(1,1,1), new THREE.MeshSimpleMaterial({ color: 0x0000ff }),
    rtTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat }),
    material = new THREE.MeshBasicMaterial({ map: rtTexture }),
    cube = new THREE.Mesh(new THREE.CubeGeometry(1,1,1), material);

function init() {
  //manipulate cameras
  //add any textures, lighting, etc

  rtScene.add( rtCube );
  scene.add( cube );
}

function update() {
   //some function of cube.rotation & cube.position
   //that changes the rtCamera rotation & position,
   //depending on the desired effect.
}

function animate() {
  requestAnimationFrame( animate );
  render();
}

function render() {
  renderer.clear();
  update();
  renderer.render( rtScene, rtCamera, rtTexture, true );
  renderer.render( scene, camera );
}

init();
animate();

在我的代码中,我假设
相机
立方体
绕y轴旋转时将保持静止。每个面都有自己的
材质更新实例
。每个面的update()函数都是一组三角乱码,可以很容易地用余弦定律推导出来。一旦本地工作正常,我将发布一个JSFIDLE示例。

如果有意义,我认为您希望使用屏幕空间投影而不是UV投影。以电视为例,在移动相机时,屏幕上的UV点会发生变换。你想要的东西是固定不动的,不管你移动多少,你都在看同一件东西。我不确定在没有着色器的情况下如何实现这一点,但在片段着色器中,您有gl_FragCoord(1)为什么不修改示例并使用透视摄影机而不是地形摄影机,并将渲染目标用作平面的纹理,而不是球体的纹理。这就是电影院里发生的事情。请参阅(2)此处不涉及不必要的“重大负载”。感谢您的回复!(1) 我理解你的意思(并且已经尝试过),但这并不能阻止“扁平化”。在我引用的例子中,球体上投影的曲率有点误导。WebGL似乎只在投影表面上渲染2D深度错觉(这是有充分理由的,这就是我提到处理器负载的原因)。当投影表面相对于相机旋转时,幻觉消失,你可以看出渲染表面很像电影屏幕,而不是真实的三维深度。你的例子确实给了我一个好主意,我可能很快就能发布我自己问题的答案。对不起,我不知道你在说什么。。。如果您无法回答自己的问题,也许其他人可以帮助您。“换句话说,场景在设置为WebGLRenderTarget时失去了深度的错觉。”这意味着什么?渲染目标可以在一端存储许多不同的内容,而在另一端,无论何时使用three.js,您都可以在屏幕上查看渲染目标的内容。你在说什么深度损失?这个链接可能很有用:@pailhead这正是重点,WebGL从不渲染深度,只是它的一种幻觉(在2D中绘制东西,使它们看起来像在3D中)。问题是,对于使用未与主场景的摄影机对齐的
WebGLRenderTarget
的任何对象,渲染目标看起来像电视屏幕,而不像具有实际深度的对象(并且出于显而易见的原因,您并不总是想要渲染目标上的深度)。要解决这个问题,您只需在
rtScene
中操纵相机即可保持深度。这个链接确实帮助我了解了更多关于THREE's相机的工作原理,谢谢!我的问题涉及到一个类似于金字塔视场的错觉,所以它与本次讨论有关。我将对此做一些实验,然后再给你们回复。听起来它可能比我的解决方案更有效。