Logarithmic Depth Buffer + Orthographic Camera

孤街醉人 提交于 2019-12-23 11:47:09

问题


I'm trying to use the Logarithmic Depth Buffer with an Orthographic camera, and encountering some interesting results. I've constructed a sample here: http://jsfiddle.net/TheJim01/05up96m0/

The renderer on the left (the red knot) uses a standard linear depth buffer (1 to 1000). Selecting Perspective or Orthographic will re-render the scene with the selected camera type, and both appear to work as expected.

The renderer on the right (the green knot) uses a logarithmic depth buffer (1e-6 to 1e27). As with the left sample, selecting a camera will re-render the scene with that camera. But in this case, only the Perspective camera works as expected. When Orthographic is selected, the knot "unties". It looks almost like it's not considering the depth buffer at all.

Am I using it wrong, or is something else going on here?

var WIDTH = 250,
  HEIGHT = 250,
  BACKGROUND = 0xcccccc;

var gl1 = new THREE.WebGLRenderer({
    antialias: true,
    logarithmicDepthBuffer: false
  }),
  gl2 = new THREE.WebGLRenderer({
    antialias: true,
    logarithmicDepthBuffer: true
  }),
  scene1 = new THREE.Scene(),
  scene2 = new THREE.Scene(),
  s1pCam = new THREE.PerspectiveCamera(
    28,
    WIDTH / HEIGHT,
    1,
    1000
  ),
  s1oCam = new THREE.OrthographicCamera(-1 * (WIDTH / HEIGHT),
    1 * (WIDTH / HEIGHT),
    1, -1,
    1,
    1000),
  aLight1 = new THREE.AmbientLight(0x333333),
  dLight1 = new THREE.DirectionalLight(0xffffff, 0.75);

s1pCam.position.set(0, 0, 100);
s1pCam.lookAt(scene1.position);
s1oCam.position.set(0, 0, 100);
s1oCam.lookAt(scene1.position);
dLight1.position.set(0, 0, 100);
dLight1.lookAt(new THREE.Vector3(0, 0, -1));

// calculate ortho frustum
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 distance = tmpCamPosition.distanceTo(projectedLocation);
var halfHeight = Math.tan(radFOV / 2.) * distance;
var halfWidth = halfHeight * s1pCam.aspect;
s1oCam.left = -halfWidth;
s1oCam.right = halfWidth;
s1oCam.top = halfHeight;
s1oCam.bottom = -halfHeight;
s1oCam.zoom = s1pCam.zoom;
s1oCam.updateProjectionMatrix();

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;

scene1.add(s1pCam);
scene1.add(s1oCam);
scene1.add(aLight1);
scene1.add(dLight1);
scene1.add(new THREE.Mesh(new THREE.TorusKnotGeometry(10, 4, 100, 32), new THREE.MeshPhongMaterial({
  color: 'red'
})));

scene2.add(s2pCam);
scene2.add(s2oCam);
scene2.add(aLight2);
scene2.add(dLight2);
scene2.add(new THREE.Mesh(new THREE.TorusKnotGeometry(10, 4, 100, 32), new THREE.MeshPhongMaterial({
  color: 'green'
})));

document.getElementById("view1").appendChild(gl1.domElement);
document.getElementById("view2").appendChild(gl2.domElement);

gl1.setSize(WIDTH, HEIGHT);
gl1.setClearColor(BACKGROUND);

gl2.setSize(WIDTH, HEIGHT);
gl2.setClearColor(BACKGROUND);

gl1.render(scene1, s1pCam);
gl2.render(scene2, s2pCam);

function handleCameraChanges(e) {
  debugger;
  if (gl1 && e.target.id.indexOf("1") !== -1) {
    gl1.render(scene1, (e.target.id.indexOf("p") !== -1) ? s1pCam : s1oCam);
  } else if (gl2) {
    gl2.render(scene2, (e.target.id.indexOf("p") !== -1) ? s2pCam : s2oCam);
  }
}

document.getElementById("v1p").addEventListener("click", handleCameraChanges);
document.getElementById("v1o").addEventListener("click", handleCameraChanges);
document.getElementById("v2p").addEventListener("click", handleCameraChanges);
document.getElementById("v2o").addEventListener("click", handleCameraChanges);
.view {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/108/three.min.js"></script>

<fieldset id="view1" class="view">
  <legend>Standard Depth Buffer</legend>
  <label><input id="v1p" type="radio" name="cameraMode1" checked />Perspective</label>
  <label><input id="v1o" type="radio" name="cameraMode1" />Orthographic</label><br>
</fieldset>

<fieldset id="view2" class="view">
  <legend>Logarithmic Depth Buffer</legend>
  <label><input id="v2p" type="radio" name="cameraMode2" checked />Perspective</label>
  <label><input id="v2o" type="radio" name="cameraMode2" />Orthographic</label><br></fieldset>

回答1:


This has been resolved in PR 17442, set for release in r109.

r109 was released on 30 September, 2019.

Here is the exact same example as above, using r109. Thanks to everyone involved in the fix!

var WIDTH = 250,
  HEIGHT = 250,
  BACKGROUND = 0xcccccc;

var gl1 = new THREE.WebGLRenderer({
    antialias: true,
    logarithmicDepthBuffer: false
  }),
  gl2 = new THREE.WebGLRenderer({
    antialias: true,
    logarithmicDepthBuffer: true
  }),
  scene1 = new THREE.Scene(),
  scene2 = new THREE.Scene(),
  s1pCam = new THREE.PerspectiveCamera(
    28,
    WIDTH / HEIGHT,
    1,
    1000
  ),
  s1oCam = new THREE.OrthographicCamera(-1 * (WIDTH / HEIGHT),
    1 * (WIDTH / HEIGHT),
    1, -1,
    1,
    1000),
  aLight1 = new THREE.AmbientLight(0x333333),
  dLight1 = new THREE.DirectionalLight(0xffffff, 0.75);

s1pCam.position.set(0, 0, 100);
s1pCam.lookAt(scene1.position);
s1oCam.position.set(0, 0, 100);
s1oCam.lookAt(scene1.position);
dLight1.position.set(0, 0, 100);
dLight1.lookAt(new THREE.Vector3(0, 0, -1));

// calculate ortho frustum
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 distance = tmpCamPosition.distanceTo(projectedLocation);
var halfHeight = Math.tan(radFOV / 2.) * distance;
var halfWidth = halfHeight * s1pCam.aspect;
s1oCam.left = -halfWidth;
s1oCam.right = halfWidth;
s1oCam.top = halfHeight;
s1oCam.bottom = -halfHeight;
s1oCam.zoom = s1pCam.zoom;
s1oCam.updateProjectionMatrix();

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;

scene1.add(s1pCam);
scene1.add(s1oCam);
scene1.add(aLight1);
scene1.add(dLight1);
scene1.add(new THREE.Mesh(new THREE.TorusKnotGeometry(10, 4, 100, 32), new THREE.MeshPhongMaterial({
  color: 'red'
})));

scene2.add(s2pCam);
scene2.add(s2oCam);
scene2.add(aLight2);
scene2.add(dLight2);
scene2.add(new THREE.Mesh(new THREE.TorusKnotGeometry(10, 4, 100, 32), new THREE.MeshPhongMaterial({
  color: 'green'
})));

document.getElementById("view1").appendChild(gl1.domElement);
document.getElementById("view2").appendChild(gl2.domElement);

gl1.setSize(WIDTH, HEIGHT);
gl1.setClearColor(BACKGROUND);

gl2.setSize(WIDTH, HEIGHT);
gl2.setClearColor(BACKGROUND);

gl1.render(scene1, s1pCam);
gl2.render(scene2, s2pCam);

function handleCameraChanges(e) {
  debugger;
  if (gl1 && e.target.id.indexOf("1") !== -1) {
    gl1.render(scene1, (e.target.id.indexOf("p") !== -1) ? s1pCam : s1oCam);
  } else if (gl2) {
    gl2.render(scene2, (e.target.id.indexOf("p") !== -1) ? s2pCam : s2oCam);
  }
}

document.getElementById("v1p").addEventListener("click", handleCameraChanges);
document.getElementById("v1o").addEventListener("click", handleCameraChanges);
document.getElementById("v2p").addEventListener("click", handleCameraChanges);
document.getElementById("v2o").addEventListener("click", handleCameraChanges);
.view {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>

<fieldset id="view1" class="view">
  <legend>Standard Depth Buffer</legend>
  <label><input id="v1p" type="radio" name="cameraMode1" checked />Perspective</label>
  <label><input id="v1o" type="radio" name="cameraMode1" />Orthographic</label><br>
</fieldset>

<fieldset id="view2" class="view">
  <legend>Logarithmic Depth Buffer</legend>
  <label><input id="v2p" type="radio" name="cameraMode2" checked />Perspective</label>
  <label><input id="v2o" type="radio" name="cameraMode2" />Orthographic</label><br></fieldset>


来源:https://stackoverflow.com/questions/37733259/logarithmic-depth-buffer-orthographic-camera

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!