问题
I have a few CubeGeometry objects rendered on the CanvasRenderer. I am getting some clipping issues due to depth sorting as shown on the following image.
Now I have seen the responses on here that this is due to limitations in CanvasRenderer and I have tried applying a few things to get a better result but there is still the clipping issues. I have overdraw set to 1 and I have increased segments as much as I can without impacting performance too much.
The image looks correct in the WebGLRenderer but it is not widely supported yet so before I give up on the CanvasRenderer I would like to exhaust all options. Anyone have any other ideas to try?
code for reference:
function SolidWood( length, width, thickness )
{
this.ID = -1;
this.name = "Unknown";
this.dimensions = {};
this.dimensions.length = length;
this.dimensions.width = width;
this.dimensions.thickness = thickness;
this.properties = {};
this.properties.color = 0x00ff00;
this.properties.wireframe = false;
this.properties.shading = THREE.SmoothShading;
this.properties.overdraw = 1.0;
this.geometry = null;
this.material = null;
this.mesh = null;
}
SolidWood.prototype.BuildGeometry = function(){
var segs = (Detector.webgl ? 1 : 8);
this.geometry = new THREE.CubeGeometry(this.dimensions.width, this.dimensions.length, this.dimensions.thickness
, segs, segs, segs);
};
SolidWood.prototype.BuildMaterial = function(){
this.properties.ambient = this.properties.color;
this.material = new THREE.MeshLambertMaterial( this.properties );
};
SolidWood.prototype.BuildMesh = function(){
this.mesh = new THREE.Mesh(this.geometry, this.material)
};
SolidWood.prototype.BuildAll = function(){
this.BuildGeometry();
this.BuildMaterial();
this.BuildMesh();
};
var camera, scene, renderer, controls, light;
var panel = {};
var HEIGHT, WIDTH;
var $container = $('#content-gallery-content');
var $speed = $('#speed');
init();
animate();
function init() {
WIDTH = 400;
HEIGHT = 300;
camera = new THREE.PerspectiveCamera( 60, WIDTH / HEIGHT, .001, 1000 );
camera.position.z = 30;
camera.position.y = 5;
camera.lookAt(new THREE.Vector3(0,0,0));
scene = new THREE.Scene();
light = new THREE.PointLight(0xffffff, 0.75, 0.0);
light.position.set(0, -30, 0);
scene.add(light);
scene.add(new THREE.AmbientLight(0xb0b0b0));
//build our panel
panel.crossmembersCount = 2;
panel.membersPerFoot = 4;
panel.memberWidth = 2.5;
panel.memberWidthHalf = panel.memberWidth/2;
panel.degrees90 = ((90*Math.PI)/180);
panel.gapWidth = (12-(panel.memberWidth * panel.membersPerFoot)) / panel.membersPerFoot;
panel.members = {};
panel.crossmembers = {};
for(i=0; i<panel.crossmembersCount; ++i)
{
panel.crossmembers[i] = new SolidWood(1.25, 11.875, 0.5);
panel.crossmembers[i].properties.color = 0x000000;
panel.crossmembers[i].BuildAll();
panel.crossmembers[i].mesh.rotation.x = panel.degrees90;
panel.crossmembers[i].mesh.position.z = ((i*12)+5.5)-11.5;
panel.crossmembers[i].mesh.position.x = 0.0625;
panel.crossmembers[i].mesh.position.y = 0.25;
scene.add( panel.crossmembers[i].mesh );
}
for(i=0; i< panel.membersPerFoot; ++i)
{
panel.members[i] = new SolidWood(23.0, panel.memberWidth, 0.6875);
panel.members[i].properties.color = 0xccaa00;
panel.members[i].BuildAll();
panel.members[i].mesh.rotation.x = panel.degrees90;
panel.members[i].mesh.position.z = 0;
panel.members[i].mesh.position.x = panel.memberWidthHalf-6.125+((panel.memberWidth+panel.gapWidth)*i);
panel.members[i].mesh.position.y = (0.6875/2)*-1;
scene.add( panel.members[i].mesh );
}
renderer = (Detector.webgl ? new THREE.WebGLRenderer() : new THREE.CanvasRenderer());
renderer.setSize( WIDTH, HEIGHT );
renderer.setClearColor(0xD0D0D0, 1.0);
$container.append( renderer.domElement );
controls = new THREE.OrbitControls(camera, $container.get(0));
}
function animate() {
// note: three.js includes requestAnimationFrame shim
requestAnimationFrame( animate );
light.position = camera.position;
//var length = $('#speed').val() * 100;
renderer.render( scene, camera );
}
回答1:
The depth buffer (or Z-buffer) is used to resolve the hidden surface problem. If an incoming fragment has a greater depth value than the value in the buffer, it's discarded. If its value is less, it replaces the current value and the fragment colour is written.
The image looks to me like a classic case of Z-fighting. Your near/far plane is so far apart compared to the Z distance between the surfaces that their Z values collide.
The quick answer, change the projection line to something like this...
camera = new THREE.PerspectiveCamera(60, WIDTH / HEIGHT, 0.01, 100);
If you really need such large differences in near/far plane, it gets a bit more complicated.
A quick google turned up these:
- Depth Buffer Precision
- Maximizing Depth Buffer Range and Precision
来源:https://stackoverflow.com/questions/19695934/three-js-canvasrenderer-depth-sorting