Three.js 对数深度缓冲区+;正交照相机

Three.js 对数深度缓冲区+;正交照相机,three.js,Three.js,我正在尝试将对数深度缓冲区与正交摄影机一起使用,并遇到了一些有趣的结果。我在这里构建了一个示例: 左侧的渲染器(红色节点)使用标准的线性深度缓冲区(1到1000)。选择“透视”(Perspective)或“正交”(Orthographic)将使用选定的摄影机类型重新渲染场景,并且这两种方式看起来都能按预期工作 右侧的渲染器(绿色节点)使用对数深度缓冲区(1e-6到1e27)。与左示例一样,选择摄影机将使用该摄影机重新渲染场景。但在这种情况下,只有透视摄影机按预期工作。选择“正交”后,结将“解开”

我正在尝试将对数深度缓冲区与正交摄影机一起使用,并遇到了一些有趣的结果。我在这里构建了一个示例:

左侧的渲染器(红色节点)使用标准的线性深度缓冲区(
1
1000
)。选择“透视”(Perspective)或“正交”(Orthographic)将使用选定的摄影机类型重新渲染场景,并且这两种方式看起来都能按预期工作

右侧的渲染器(绿色节点)使用对数深度缓冲区(
1e-6
1e27
)。与左示例一样,选择摄影机将使用该摄影机重新渲染场景。但在这种情况下,只有透视摄影机按预期工作。选择“正交”后,结将“解开”。看起来它根本没有考虑深度缓冲区

是我用错了,还是这里发生了什么事

var宽度=250,
高度=250,
背景=0xCCCC;
var gl1=new THREE.WebGLRenderer({
反别名:是的,
对数深度缓冲区:false
}),
gl2=新的三个WebGL2渲染器({
反别名:是的,
对数深度缓冲区:true
}),
场景1=新的三个场景(),
场景2=新的三个场景(),
s1pCam=新的三透视照相机(
28,
宽度/高度,
1.
1000
),
s1oCam=新的三轴正交摄影机(-1*(宽度/高度),
1*(宽度/高度),
1, -1,
1.
1000),
下车1=新的三个环境灯(0x333333),
dLight1=新的三方向光(0xffffff,0.75);
s1pCam位置设置(0,0,100);
s1pCam.观察(场景1.位置);
s1oCam位置设置(0,0,100);
s1oCam.注视(场景1.位置);
dLight1.position.set(0,0100);
dLight1.lookAt(新的三向量3(0,0,-1));
//计算正交平截头体
var modelCenter=new THREE.Vector3(),
tmpCamPosition=s1pCam.position.clone(),
camTarget=new THREE.Vector3(),
radFOV=(Math.PI/180.)*s1pCam.fov;
modelCenter.sub(camTarget);
tmpCamPosition.sub(camTarget);
var projectedLocation=modelCenter.projectOnVector(tmpCamPosition);
var距离=tmpCamPosition.distanceTo(项目位置);
var半高=数学tan(radFOV/2.)*距离;
var半宽=半高*s1pCam.aspect;
s1oCam.left=-半宽;
s1oCam.right=半宽;
s1oCam.top=半高;
s1oCam.bottom=-半高;
s1oCam.zoom=s1pCam.zoom;
s1oCam.updateProjectMatrix();
var s2pCam=s1pCam.clone(),
s2oCam=s1oCam.clone(),
aLight2=aLight1.clone(),
dLight2=dLight1.clone();
s2pCam.near=1e-6;
s2pCam.far=1e27;
s2oCam.near=1e-6;
s2oCam.far=1e27;
场景1.添加(s1pCam);
场景1.添加(s1oCam);
场景1.添加(下车1);
场景1.添加(dLight1);
场景1.添加(新的3.Mesh(新的3.TorusKnotGeometry(10,4100,32)),新的3.MeshPhongMaterial({
颜色:“红色”
})));
场景2.添加(s2pCam);
场景2.添加(s2oCam);
场景2.添加(下车2);
场景2.添加(dLight2);
场景2.添加(新的3.Mesh)(新的3.TorusKnotGeometry(10,4100,32)),新的3.MeshPhongMaterial({
颜色:“绿色”
})));
document.getElementById(“view1”).appendChild(gl1.doElement);
document.getElementById(“view2”).appendChild(gl2.doElement);
gl1.设置尺寸(宽度、高度);
gl1.setClearColor(背景);
gl2.设置尺寸(宽度、高度);
gl2.setClearColor(背景);
gl1.渲染(场景1,s1pCam);
gl2.渲染(场景2,s2pCam);
功能手柄摄像机量程(e){
调试器;
if(gl1&&e.target.id.indexOf(“1”)!=-1){
gl1.渲染(场景1,(例如,target.id.indexOf(“p”)!==-1)?s1pCam:s1oCam);
}否则如果(gl2){
gl2.渲染(场景2,(e.target.id.indexOf(“p”)!==-1)?s2pCam:s2oCam);
}
}
document.getElementById(“v1p”).addEventListener(“单击”,handleCameraChanges);
document.getElementById(“v1o”).addEventListener(“单击”,handleCameraChanges);
document.getElementById(“v2p”).addEventListener(“单击”,handleCameraChanges);
document.getElementById(“v2o”).addEventListener(“单击”,handleCameraChanges)
.view{
显示:内联块;
}

标准深度缓冲器
观点
正字法
对数深度缓冲器 观点
正交
这已在PR中得到解决,将在r109中发布

下面是与上面完全相同的示例,使用r109。感谢参与修复的所有人

var宽度=250,
高度=250,
背景=0xCCCC;
var gl1=new THREE.WebGLRenderer({
反别名:是的,
对数深度缓冲区:false
}),
gl2=新的三个WebGL2渲染器({
反别名:是的,
对数深度缓冲区:true
}),
场景1=新的三个场景(),
场景2=新的三个场景(),
s1pCam=新的三透视照相机(
28,
宽度/高度,
1.
1000
),
s1oCam=新的三轴正交摄影机(-1*(宽度/高度),
1*(宽度/高度),
1, -1,
1.
1000),
下车1=新的三个环境灯(0x333333),
dLight1=新的三方向光(0xffffff,0.75);
s1pCam位置设置(0,0,100);
s1pCam.观察(场景1.位置);
s1oCam位置设置(0,0,100);
s1oCam.注视(场景1.位置);
dLight1.position.set(0,0100);
dLight1.lookAt(新的三向量3(0,0,-1));
//计算正交平截头体
var modelCenter=new THREE.Vector3(),
tmpCamPosition=s1pCam.position.clone(),
camTarget=new THREE.Vector3(),
radFOV=(Math.PI/180.)*s1pCam.fov;
modelCenter.sub(camTarget);
tmpCamPosition.sub(camTarget);
var projectedLocation=modelCenter.projectOnVector(tmpCamPosition);
var距离=tmpCamPosition.distanceTo(项目位置);
var半高=数学tan(radFOV/2.)*距离;
var半宽=半高*s1pCam.aspect;
s1oCam.left=-半宽;
s1oCam.right=半宽;
s1oCam.top=半高;
s1oCam.bottom=-半高;
s1oCam.zoom=s1pCam.zoom;
s1oCam.updateProjectMatrix();
var s2pCam=s1pCam.clone(),
s2oCam=s1oCam.clone(),
aLight2=aLight1.clone(),
dLight2=dLight1.clone();
s2pCam.near=1e-6;
s2pCam.far=1e27;
s2oCam.near=1e-6;
s2oCam.far=1e27;
场景1.添加(s1pCam);
场景1.添加(s1oCam);
场景1.添加(下车1);
场景1.添加(dLight1);
场景1.添加(新T