away3d / away3d-core-fp11

Away3D engine for Flash Player 11
http://www.away3d.com
Other
640 stars 273 forks source link

Sorting of blended object is incorrect in the latest dev branch #605

Closed daiwei1999 closed 11 years ago

daiwei1999 commented 11 years ago

I found EntityCollector._entryPoint and _cameraForward attribute is not updated every frame, this will cause the calculation of zIndex of RenderableListItem incorrectly which used to sort blended object.

daiwei1999 commented 11 years ago

It's simple to produce this bug:

var cube:Mesh = new Mesh(new CubeGeometry(), new ColorMaterial(0xFF0000, 0.7)); cube.x = -100; scene.addChild(cube);

var sphere:Mesh = new Mesh(new SphereGeometry(), new ColorMaterial(0x00FF00, 0.7)); sphere.x = 100; scene.addChild(sphere);

If you move and rotate the camera, you can easily discover the sorting order is not always correct.

rob-bateman commented 11 years ago

your example does not use blending - can you post an exact test class exhibiting the problem that we can review?

profelis commented 11 years ago

daiwei1999 talk about transparent meshes and its sorting.

iY0Yi commented 11 years ago

Hey, if this issue is correct, that will be nice.

@rob-bateman Here is the code for reproducing. https://gist.github.com/GoroMatsumoto/5948112 Red ball always present in front of green. Both alpha property is 1.0. Just set alphaBlending = true;

iY0Yi commented 11 years ago

@daiwei1999 Can you post the code for fixing this issue? If you have. Cheers.

daiwei1999 commented 11 years ago

I fix the issue by only add two lines to the beginning of EntityCollector.clear method: public function clear():void { _entryPoint = _camera.scenePosition; _cameraForward = _camera.forwardVector; _cullPlanes = _customCullPlanes ? _customCullPlanes : _camera.frustumPlanes; .... } This modification will update _entryPoint and _cameraForward every frame which used to calculate zIndex, and correct zIndex will be used to sort blended object correctly.

iY0Yi commented 11 years ago

@daiwei1999 Thank you! Your code works with my above code. Great.

But I tested with more many meshes, and I found a little artifact of z-sorting.

for(var i:int = 0; i<500; i++)
{
    var material:ColorMaterial = new ColorMaterial(0xFFFFFF*Math.random());
    material.lightPicker = lightPicker;
    material.specular = .01;
    material.gloss = 5;
    material.alphaBlending = true;  

    var sp:Mesh = new Mesh(new SphereGeometry(400,32,32), material);
    sp.x = (Math.random()*2-1)*5000;
    sp.y = (Math.random()*2-1)*5000;
    sp.z = (Math.random()*2-1)*5000;
    view.scene.addChild(sp);
}

If faces of a mesh are intersected with other mesh's faces, an artifact occurs there. If you have a time for this, please confirm it with this code.

Anyway, your code improves Away3D's z-sorting problem comparatively.

Cheers.

rob-bateman commented 11 years ago

looks like the suggested fix works great! thanks guys

@GoroMatsumoto the artifacts you describe are a limitation of the blending system. when rendering objects this way, individual materials are rendered in a fixed order depending on their blend mode and object depth. as a result, intersecting objects are to be avoided if possible

mariommoreno commented 11 years ago

I've downloaded last dev, and issue still persist for me. I'm using different meshes with TextureBitmaps.alphaBlending = true; Character one is a plane with an animated sprite sheet, dust particles are sprite3D.

Meshes are included in ObjectContainer3D and then added to scene in order to group them, if it helps. Maybe "entity.x y z" are not in global coordinates?

Any idea how to solve it?

mariommoreno commented 11 years ago

Yes... the relative coordinates of entities are not valid for z-ordering. I've changed this lines in EntityCollector.applyRenderable() and now it works:

var dx:Number = _entryPoint.x - entity.x;
var dy:Number = _entryPoint.y - entity.y;
var dz:Number = _entryPoint.z - entity.z;               
var dx:Number = _entryPoint.x - entity.scenePosition.x;
var dy:Number = _entryPoint.y - entity.scenePosition.y;
var dz:Number = _entryPoint.z - entity.scenePosition.z;             

Do you know if using scenePosition affects performance? If not, I think it must be added to dev version.

shishenkov commented 11 years ago

Oh man - thank you Mario :+1: the entity.scenePosition check is still not in the dev branch of aw3d but finding your post got me a solution i was trying to figure out all day yesterday - i have a complex sphere-like object constructed out of hexagonal "tiles" that are using transparent png textures and the wrong sorting order totally messed it up - i was about to call the designer to request an interface revamp to accommodate non-transparent tiles anyway .. i compiled the latest dev version of the away 3d 4.1.4 with that fix applied here's a link if anyone out there needs the bin only: https://dl.dropboxusercontent.com/u/65764384/Away3d-CustomBuilds/Away3d-4.1.4-dev-20130924.swc