mirror of
https://github.com/minetest/irrlicht.git
synced 2025-04-02 02:30:27 +02:00
Add more transparent node sorting algorithms
Adding 2 algorithms to sort by distance to camera plane instead of camera position. This is better in quite a few situations and extra cost is just one vector subtraction per node and an additional function parameter per call, I think that's worth it. So made the camera-plane to object-center now the new default. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6573 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
3c4ac201ce
commit
3752bd9bd4
@ -1,7 +1,7 @@
|
|||||||
--------------------------
|
--------------------------
|
||||||
Changes in 1.9 (not yet released)
|
Changes in 1.9 (not yet released)
|
||||||
|
|
||||||
- Add options for transparency node sorting algorithm
|
- Add options for transparency node sorting algorithm.
|
||||||
- CImageWriterPNG now also supports the writeImageToFile param to allow setting compressing level. 0 stays default, 1-10 for range increasing compression level.
|
- CImageWriterPNG now also supports the writeImageToFile param to allow setting compressing level. 0 stays default, 1-10 for range increasing compression level.
|
||||||
- Add io::IUserData which can be set in SMaterial to make it easer passing additional material values to shaders
|
- Add io::IUserData which can be set in SMaterial to make it easer passing additional material values to shaders
|
||||||
- Add lens shift support for the camera and the perspective projection functions
|
- Add lens shift support for the camera and the perspective projection functions
|
||||||
|
@ -111,18 +111,24 @@ namespace scene
|
|||||||
//! Which can be used to do some custom sorting via scene-graph (mainly useful if you only have to that once)
|
//! Which can be used to do some custom sorting via scene-graph (mainly useful if you only have to that once)
|
||||||
ETNS_NONE,
|
ETNS_NONE,
|
||||||
|
|
||||||
//! Distance from node origin to camera
|
//! Distance from node origin to camera position
|
||||||
ETNS_ORIGIN,
|
ETNS_ORIGIN,
|
||||||
|
|
||||||
//! Distance from node center to camera
|
//! Distance from node center to camera position
|
||||||
ETNS_CENTER,
|
ETNS_CENTER,
|
||||||
|
|
||||||
//! Distance from the nearest of the 2 transformed bounding-box extend corners to camera
|
//! Distance from the nearest of the 2 transformed bounding-box extend corners to camera
|
||||||
ETNS_BBOX_EXTENTS,
|
ETNS_BBOX_EXTENTS,
|
||||||
|
|
||||||
|
//! Distance from node origin to camera plane
|
||||||
|
ETNS_PLANE_ORIGIN,
|
||||||
|
|
||||||
|
//! Distance from node center to camera plane
|
||||||
|
ETNS_PLANE_CENTER,
|
||||||
|
|
||||||
//! Default sorting Irrlicht uses currently
|
//! Default sorting Irrlicht uses currently
|
||||||
//! This may change in the future
|
//! This may change in the future
|
||||||
ETNS_DEFAULT = ETNS_CENTER
|
ETNS_DEFAULT = ETNS_PLANE_CENTER
|
||||||
};
|
};
|
||||||
|
|
||||||
class IAnimatedMesh;
|
class IAnimatedMesh;
|
||||||
|
@ -1364,14 +1364,14 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE
|
|||||||
case ESNRP_TRANSPARENT:
|
case ESNRP_TRANSPARENT:
|
||||||
if (!isCulled(node))
|
if (!isCulled(node))
|
||||||
{
|
{
|
||||||
TransparentNodeList.push_back(TransparentNodeEntry(node, funcTransparentNodeDistance(node, camWorldPos)));
|
TransparentNodeList.push_back(TransparentNodeEntry(node, funcTransparentNodeDistance(node, CamWorldPos, CamWorldViewNormalized)));
|
||||||
taken = 1;
|
taken = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ESNRP_TRANSPARENT_EFFECT:
|
case ESNRP_TRANSPARENT_EFFECT:
|
||||||
if (!isCulled(node))
|
if (!isCulled(node))
|
||||||
{
|
{
|
||||||
TransparentEffectNodeList.push_back(TransparentNodeEntry(node, funcTransparentNodeDistance(node, camWorldPos)));
|
TransparentEffectNodeList.push_back(TransparentNodeEntry(node, funcTransparentNodeDistance(node, CamWorldPos, CamWorldViewNormalized)));
|
||||||
taken = 1;
|
taken = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1386,7 +1386,7 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE
|
|||||||
if (Driver->needsTransparentRenderPass(node->getMaterial(i)))
|
if (Driver->needsTransparentRenderPass(node->getMaterial(i)))
|
||||||
{
|
{
|
||||||
// register as transparent node
|
// register as transparent node
|
||||||
TransparentNodeEntry e(node, funcTransparentNodeDistance(node, camWorldPos));
|
TransparentNodeEntry e(node, funcTransparentNodeDistance(node, CamWorldPos, CamWorldViewNormalized));
|
||||||
TransparentNodeList.push_back(e);
|
TransparentNodeList.push_back(e);
|
||||||
taken = 1;
|
taken = 1;
|
||||||
break;
|
break;
|
||||||
@ -1486,11 +1486,17 @@ void CSceneManager::drawAll()
|
|||||||
consistent Camera is needed for culling
|
consistent Camera is needed for culling
|
||||||
*/
|
*/
|
||||||
IRR_PROFILE(getProfiler().start(EPID_SM_RENDER_CAMERAS));
|
IRR_PROFILE(getProfiler().start(EPID_SM_RENDER_CAMERAS));
|
||||||
camWorldPos.set(0,0,0);
|
|
||||||
if (ActiveCamera)
|
if (ActiveCamera)
|
||||||
{
|
{
|
||||||
ActiveCamera->render();
|
ActiveCamera->render();
|
||||||
camWorldPos = ActiveCamera->getAbsolutePosition();
|
CamWorldPos = ActiveCamera->getAbsolutePosition();
|
||||||
|
CamWorldViewNormalized = ActiveCamera->getTarget() - ActiveCamera->getAbsolutePosition();
|
||||||
|
CamWorldViewNormalized.normalize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CamWorldPos.set(0,0,0);
|
||||||
|
CamWorldViewNormalized.set(0,0,1);
|
||||||
}
|
}
|
||||||
IRR_PROFILE(getProfiler().stop(EPID_SM_RENDER_CAMERAS));
|
IRR_PROFILE(getProfiler().stop(EPID_SM_RENDER_CAMERAS));
|
||||||
|
|
||||||
@ -2196,44 +2202,59 @@ E_SCENE_NODE_RENDER_PASS CSceneManager::getSceneNodeRenderPass() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not sorting this later
|
// Not sorting this later
|
||||||
static f32 transparentSortingNone(const ISceneNode* node, const core::vector3df& camera)
|
static f32 transparentSortingNone(const ISceneNode*, const core::vector3df&, const core::vector3df&)
|
||||||
{
|
{
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance from node origin to camera
|
// Distance from node origin to camera pos
|
||||||
static f32 transparentSortingByOrigin(const ISceneNode* node, const core::vector3df& camera)
|
static f32 transparentSortingByOrigin(const ISceneNode* node, const core::vector3df& cameraPos, const core::vector3df&)
|
||||||
{
|
{
|
||||||
return node->getAbsolutePosition().getDistanceFromSQ(camera);
|
return node->getAbsolutePosition().getDistanceFromSQ(cameraPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance from node center to camera
|
// Distance from node center to camera pos
|
||||||
static f32 transparentSortingByCenter(const ISceneNode* node, const core::vector3df& camera)
|
static f32 transparentSortingByCenter(const ISceneNode* node, const core::vector3df& cameraPos, const core::vector3df&)
|
||||||
{
|
{
|
||||||
core::vector3df center = node->getBoundingBox().getCenter();
|
core::vector3df center = node->getBoundingBox().getCenter();
|
||||||
const core::matrix4& absMat = node->getAbsoluteTransformation();
|
const core::matrix4& absMat = node->getAbsoluteTransformation();
|
||||||
absMat.rotateVect(center);
|
absMat.rotateVect(center);
|
||||||
return (absMat.getTranslation()+center).getDistanceFromSQ(camera);
|
return (absMat.getTranslation()+center).getDistanceFromSQ(cameraPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distance from node origin to camera plane
|
||||||
|
static f32 transparentSortingByPlaneOrigin(const ISceneNode* node, const core::vector3df& cameraPos, const core::vector3df& cameraViewN)
|
||||||
|
{
|
||||||
|
return cameraViewN.dotProduct(node->getAbsolutePosition()-cameraPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distance from node center to camera plane
|
||||||
|
static f32 transparentSortingByPlaneCenter(const ISceneNode* node, const core::vector3df& cameraPos, const core::vector3df& cameraViewN)
|
||||||
|
{
|
||||||
|
core::vector3df center = node->getBoundingBox().getCenter();
|
||||||
|
const core::matrix4& absMat = node->getAbsoluteTransformation();
|
||||||
|
absMat.rotateVect(center);
|
||||||
|
return cameraViewN.dotProduct(absMat.getTranslation()+center-cameraPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const core::aabbox3d<f32> box = Node->getTransformedBoundingBox();
|
const core::aabbox3d<f32> box = Node->getTransformedBoundingBox();
|
||||||
Distance = core::min_(camera.getDistanceFromSQ(box.MinEdge), camera.getDistanceFromSQ(box.MaxEdge));
|
Distance = core::min_(camera.getDistanceFromSQ(box.MinEdge), camera.getDistanceFromSQ(box.MaxEdge));
|
||||||
*/
|
*/
|
||||||
static f32 transparentSortingBBoxExtents(const ISceneNode* node, const core::vector3df& camera)
|
static f32 transparentSortingBBoxExtents(const ISceneNode* node, const core::vector3df& cameraPos, const core::vector3df&)
|
||||||
{
|
{
|
||||||
const core::aabbox3d<f32>& box = node->getBoundingBox();
|
const core::aabbox3d<f32>& box = node->getBoundingBox();
|
||||||
const f32* m = node->getAbsoluteTransformation().pointer();
|
const f32* m = node->getAbsoluteTransformation().pointer();
|
||||||
|
|
||||||
f32 p[4];
|
f32 p[4];
|
||||||
p[0] = camera.X - (box.MinEdge.X * m[0] + box.MinEdge.Y * m[4] + box.MinEdge.Z * m[8] + m[12]);
|
p[0] = cameraPos.X - (box.MinEdge.X * m[0] + box.MinEdge.Y * m[4] + box.MinEdge.Z * m[8] + m[12]);
|
||||||
p[1] = camera.Y - (box.MinEdge.X * m[1] + box.MinEdge.Y * m[5] + box.MinEdge.Z * m[9] + m[13]);
|
p[1] = cameraPos.Y - (box.MinEdge.X * m[1] + box.MinEdge.Y * m[5] + box.MinEdge.Z * m[9] + m[13]);
|
||||||
p[2] = camera.Z - (box.MinEdge.X * m[2] + box.MinEdge.Y * m[6] + box.MinEdge.Z * m[10] + m[14]);
|
p[2] = cameraPos.Z - (box.MinEdge.X * m[2] + box.MinEdge.Y * m[6] + box.MinEdge.Z * m[10] + m[14]);
|
||||||
f32 l0 = (p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]);
|
f32 l0 = (p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]);
|
||||||
|
|
||||||
p[0] = camera.X - (box.MaxEdge.X * m[0] + box.MaxEdge.Y * m[4] + box.MaxEdge.Z * m[8] + m[12]);
|
p[0] = cameraPos.X - (box.MaxEdge.X * m[0] + box.MaxEdge.Y * m[4] + box.MaxEdge.Z * m[8] + m[12]);
|
||||||
p[1] = camera.Y - (box.MaxEdge.X * m[1] + box.MaxEdge.Y * m[5] + box.MaxEdge.Z * m[9] + m[13]);
|
p[1] = cameraPos.Y - (box.MaxEdge.X * m[1] + box.MaxEdge.Y * m[5] + box.MaxEdge.Z * m[9] + m[13]);
|
||||||
p[2] = camera.Z - (box.MaxEdge.X * m[2] + box.MaxEdge.Y * m[6] + box.MaxEdge.Z * m[10] + m[14]);
|
p[2] = cameraPos.Z - (box.MaxEdge.X * m[2] + box.MaxEdge.Y * m[6] + box.MaxEdge.Z * m[10] + m[14]);
|
||||||
f32 l1 = (p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]);
|
f32 l1 = (p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]);
|
||||||
return core::min_(l0, l1);
|
return core::min_(l0, l1);
|
||||||
}
|
}
|
||||||
@ -2244,16 +2265,22 @@ void CSceneManager::setTransparentNodeSorting(E_TRANSPARENT_NODE_SORTING sorting
|
|||||||
switch ( TransparentNodeSorting )
|
switch ( TransparentNodeSorting )
|
||||||
{
|
{
|
||||||
case ETNS_NONE:
|
case ETNS_NONE:
|
||||||
funcTransparentNodeDistance = transparentSortingNone;
|
funcTransparentNodeDistance = transparentSortingNone;
|
||||||
break;
|
break;
|
||||||
case ETNS_ORIGIN:
|
case ETNS_ORIGIN:
|
||||||
funcTransparentNodeDistance = transparentSortingByOrigin;
|
funcTransparentNodeDistance = transparentSortingByOrigin;
|
||||||
break;
|
break;
|
||||||
case ETNS_CENTER:
|
case ETNS_CENTER:
|
||||||
funcTransparentNodeDistance = transparentSortingByCenter;
|
funcTransparentNodeDistance = transparentSortingByCenter;
|
||||||
break;
|
break;
|
||||||
case ETNS_BBOX_EXTENTS:
|
case ETNS_BBOX_EXTENTS:
|
||||||
funcTransparentNodeDistance = transparentSortingBBoxExtents;
|
funcTransparentNodeDistance = transparentSortingBBoxExtents;
|
||||||
|
break;
|
||||||
|
case ETNS_PLANE_ORIGIN:
|
||||||
|
funcTransparentNodeDistance = transparentSortingByPlaneOrigin;
|
||||||
|
break;
|
||||||
|
case ETNS_PLANE_CENTER:
|
||||||
|
funcTransparentNodeDistance = transparentSortingByPlaneCenter;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -654,7 +654,8 @@ namespace scene
|
|||||||
|
|
||||||
//! current active camera
|
//! current active camera
|
||||||
ICameraSceneNode* ActiveCamera;
|
ICameraSceneNode* ActiveCamera;
|
||||||
core::vector3df camWorldPos; // Position of camera for transparent nodes.
|
core::vector3df CamWorldPos; // Position of camera for transparent nodes.
|
||||||
|
core::vector3df CamWorldViewNormalized; // Normalized view direction of camera for transparent nodes.
|
||||||
|
|
||||||
video::SColor ShadowColor;
|
video::SColor ShadowColor;
|
||||||
video::SColorf AmbientLight;
|
video::SColorf AmbientLight;
|
||||||
@ -671,8 +672,7 @@ namespace scene
|
|||||||
//! Algorithm used to sort transparent nodes
|
//! Algorithm used to sort transparent nodes
|
||||||
E_TRANSPARENT_NODE_SORTING TransparentNodeSorting;
|
E_TRANSPARENT_NODE_SORTING TransparentNodeSorting;
|
||||||
//! Pointer to the actual algorithm to get the distance
|
//! Pointer to the actual algorithm to get the distance
|
||||||
// (Could be we have to pass more parameters for better results, like view normal)
|
f32 (*funcTransparentNodeDistance)(const ISceneNode* node, const core::vector3df& cameraPos, const core::vector3df& cameraViewNormalized);
|
||||||
f32 (*funcTransparentNodeDistance)(const ISceneNode* node, const core::vector3df& camera);
|
|
||||||
|
|
||||||
//! An optional callbacks manager to allow the user app finer control
|
//! An optional callbacks manager to allow the user app finer control
|
||||||
//! over the scene lighting and rendering.
|
//! over the scene lighting and rendering.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user