Kub*_*lik 1 3d html5 canvas three.js
我正在尝试使用THREE.js创建一个简单的地图,其中的平面纸状树木在WebGL中伸出.我无法理解库如何处理z缓冲.我已尝试使用renderer.sortObjects参数以及material.depthWrite和object.renderDepth,但似乎没有组合工作 - 我要么让库以正确的顺序显示树(来自摄像机的那些被阻挡那些靠近相机的人,但是有着奇怪的透明度故障,或者我设法使透明度正确,但是离屏幕越远的树就会出现在靠近的地方.经过几个小时的尝试,这是我最终得到的:

如您所见,右侧更多的树在左侧的树上呈现.
在我完全疯了之前请帮助我:)
这是我的代码:http://jsfiddle.net/UgZxc/
var map_size = 80;
var MapModel = {};
var types_amount = 2;
var floorMap = [];
for(var i=1; i<=map_size; i++){
floorMap[i]=[];
for(var j=1; j<=map_size; j++){
var ran = Math.ceil(Math.random()*types_amount);
switch(ran){
case 1:
floorMap[i][j]='grass';
break;
case 2:
floorMap[i][j]='water';
break;
}
}
}
MapModel.floorMap = floorMap;
var objectMap = [];
for(var i = map_size; i>=1; i--){
objectMap[i] = [];
for(var j=1; j<=map_size; j++){
objectMap[i][j] = [];
var rand = Math.ceil(Math.random()*2);
switch(rand){
case 1:
objectMap[i][j].push('tree');
break;
}
}
}
MapModel.objectMap = objectMap;
block_size=100;
// Constructor
MapApp = function()
{
Sim.App.call(this);
}
// Subclass Sim.App
MapApp.prototype = new Sim.App();
// Our custom initializer
MapApp.prototype.init = function(param)
{
Sim.App.prototype.init.call(this, param);
// Create the Earth and add it to our sim
for(var i=1; i<=map_size; i++){
for(var j=map_size; j>=1; j--){
var square = new Square();
square.init(i, j);
this.addObject(square);
var arr = MapModel.objectMap[i][j];
for(var k in arr){
var obj = new MapObject();
obj.init(i, j, arr[k]);
this.addObject(obj);
}
}
}
// Let there be light!
var sun = new Sun();
sun.init();
this.addObject(sun);
this.camera.position.x = 3*block_size;
this.camera.position.y = 3*block_size;
this.camera.position.z=5*block_size;
this.camera.rotation.x = Math.round(45* 100* Math.PI/180)/100;
this.selfUpdate = function(){
this.camera.position.x += 0.125 * block_size/10;
this.camera.position.x += 0.050 * block_size/10;
}
}
Square = function()
{
Sim.Object.call(this);
this.size = block_size;
}
Square.prototype = new Sim.Object();
wrote2 = false;
Square.prototype.init = function(x, y){
var type=MapModel.floorMap[x][y];
var reflectivity = 0;
switch(type){
case "grass":
var earthmap = "http://dl.dropboxusercontent.com/u/1142760/static/html/webgl/tiles/samatrawa.png";
break;
case "water":
var earthmap = "http://dl.dropboxusercontent.com/u/1142760/static/html/webgl/tiles/samawoda.png";
reflectivity = 1;
break;
}
//console.log(earthmap);
var geometry = new THREE.CubeGeometry(this.size, this.size, this.size );
var texture = THREE.ImageUtils.loadTexture(earthmap);
var material = new THREE.MeshPhongMaterial( { map: texture, color: 0xffffff, reflectivity: reflectivity } );
material.depthWrite = true;
var mesh = new THREE.Mesh( geometry, material );
mesh.translateX(x*this.size);
mesh.translateY(y*this.size);
mesh.renderDepth = y*block_size;
if(!wrote2){
wrote2=true;
console.log('square renderDepth:', mesh.renderDepth, 'square mesh.position.y:', mesh.position.y);
console.log('square material.depthWrite', material.depthWrite);
}
this.setObject3D(mesh);
}
Square.prototype.update = function()
{
// "I feel the Earth move..."
//this.object3D.rotation.y += 0.1;
//Sim.Object.prototype.update.call(this);
}
// Custom Sun class
Sun = function()
{
Sim.Object.call(this);
}
Sun.prototype = new Sim.Object();
Sun.prototype.init = function()
{
// Create a point light to show off the earth - set the light out back and to left a bit
var light = new THREE.DirectionalLight( 0xC5BC98, 2);
light.position.set(-10, 0, 20);
// Tell the framework about our object
this.setObject3D(light);
}
MapObject = function(){
Sim.Object.call(this);
}
MapObject.prototype = new Sim.Object();
wrote=false
MapObject.prototype.init = function(x, y, type){
switch(type){
case "tree":
var textureURL = "http://dl.dropboxusercontent.com/u/1142760/static/html/webgl/tiles/samodrzewo.png";
break;
case "water":
var textureURL = "http://dl.dropboxusercontent.com/u/1142760/static/html/webgl/tiles/samawoda.png";
break;
}
//console.log(textureURL);
var geometry = new THREE.PlaneGeometry(1*block_size, 2*block_size);
var texture = THREE.ImageUtils.loadTexture(textureURL);
var material = new THREE.MeshPhongMaterial( { map: texture, transparent:true } );
material.depthWrite = false;
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x=x*block_size;
mesh.position.y=y*block_size;
mesh.translateZ(2*block_size);
mesh.rotation.x = Math.round(45 * 100 * Math.PI /180)/100;
//mesh.renderDepth = y*block_size;
mesh.renderDepth = -y*1000 ;
if(!wrote){
console.log('object renderDepth:', mesh.renderDepth, 'object mesh.position.y:', mesh.position.y);
console.log('object material.depthWrite', material.depthWrite);
wrote = true;
}
//console.log(mesh.rotation.x);
this.setObject3D(mesh);
}
var renderer = null;
var scene = null;
var camera = null;
var mesh = null;
$(document).ready(
function() {
var container = document.getElementById("container");
var app = new MapApp();
app.init({ container: container });
app.run();
}
);
Run Code Online (Sandbox Code Playgroud)
通常,通过打开/关闭深度测试/写入不能解决该问题.这个答案很好地解释了:WebGL中的透明纹理行为
因此,只能通过以正确的顺序绘制透明对象来解决.解决方案是(主要是默认的three.js行为!):
app.renderer.sortObjects = true;虽然我没有看到代码中的哪个位置被禁用.但是,在你的情况下,事实证明你的three.js版本在重新排序时做得不好(可能是一些不稳定的排序,我不会深入研究),所以你会得到看似随机的文物.更新到最新的构建修复.
工作小提琴:http://jsfiddle.net/UgZxc/12/
作为旁注:尝试下次减少代码示例/小提琴,以及依赖项的数量.那里有很多不相关的代码.
| 归档时间: |
|
| 查看次数: |
3920 次 |
| 最近记录: |