SMesh shadows
SMesh shadows
Hi,
I'm new to Irrlicht.
Is there any extension to IMeshSceneNode which can draw shadows?
Essentially my scene doesn't have any animated nodes, it just has mesh nodes generated on the fly (using SMesh/SMeshBuffers). These nodes are not necessarily static and I need to render the scene with shadows.
Is it a matter of extending/rewriting the CMeshSceneNode() class to use a shadow volume node like the CAnimatedSceneNode class does?
Perhaps I'm not looking hard enough, I'm sure this must have been considered already.
I'm new to Irrlicht.
Is there any extension to IMeshSceneNode which can draw shadows?
Essentially my scene doesn't have any animated nodes, it just has mesh nodes generated on the fly (using SMesh/SMeshBuffers). These nodes are not necessarily static and I need to render the scene with shadows.
Is it a matter of extending/rewriting the CMeshSceneNode() class to use a shadow volume node like the CAnimatedSceneNode class does?
Perhaps I'm not looking hard enough, I'm sure this must have been considered already.
Thanks Travis. I need to cast the shadow onto everything in the scene though, not just a plane.
Isn't it a common thing to do? I'm quite surprised it's not already implemented, after all, not all dynamic entities are animated meshes, I would have expected the same behaviour in the IMeshSceneNode as is in the IAnimatedMeshSceneNode.
Isn't it a common thing to do? I'm quite surprised it's not already implemented, after all, not all dynamic entities are animated meshes, I would have expected the same behaviour in the IMeshSceneNode as is in the IAnimatedMeshSceneNode.
Ok.
For now I'm going to implement a new custom scene node derived from IMeshSceneNode (basically CMeshSceneNode with the same shadow volume support that CAnimatedMeshSceneNode has). It looks like all the mechanisms are there for it to work - it just seems like a glaring omission to me.
I guess most people aren't generating or using static meshes which require shadows.
If I get a working version I'll probably modify the engine's CMeshSceneNode to allow shadow volumes and post the changes.
For now I'm going to implement a new custom scene node derived from IMeshSceneNode (basically CMeshSceneNode with the same shadow volume support that CAnimatedMeshSceneNode has). It looks like all the mechanisms are there for it to work - it just seems like a glaring omission to me.
I guess most people aren't generating or using static meshes which require shadows.
If I get a working version I'll probably modify the engine's CMeshSceneNode to allow shadow volumes and post the changes.
Ok. If anyone is interested, I've modified IMeshSceneNode.h and the CMeshSceneNode class to allow to create and use a shadow volume node. No idea if there are other nodes derived from IMeshSceneNode that may need tweaking.
I've only just noticed that shadows only work with point lights... I'll need to investigate making them work with directional lights also.
I've only just noticed that shadows only work with point lights... I'll need to investigate making them work with directional lights also.
I'd be very interested in seeing how you did this. Many things in Irrlicht are extensible via interface classes but it doesn't sound like you did this. Are you going to post your code?bpe_xmind wrote:Ok. If anyone is interested, I've modified IMeshSceneNode.h and the CMeshSceneNode class to allow to create and use a shadow volume node. No idea if there are other nodes derived from IMeshSceneNode that may need tweaking.
I've only just noticed that shadows only work with point lights... I'll need to investigate making them work with directional lights also.
Sure. I'm not sure how the forum works (where/how to upload source files).
I chose to change the implementation of IMeshSceneNode because I believe it is inconsistent with IAnimatedMeshSceneNode and should allow the use of shadow volumes - I could have extended it or written a new custom node by basing it on the engine's version just the same.
How do I post the source/changes?
I chose to change the implementation of IMeshSceneNode because I believe it is inconsistent with IAnimatedMeshSceneNode and should allow the use of shadow volumes - I could have extended it or written a new custom node by basing it on the engine's version just the same.
How do I post the source/changes?
You could generate a patch file with your diff program - that's a commonly used technique.
Or if it's one major change, and a few minor changes, just post it here in [ code ] tags.
If it's very clean, and works properly, you may want to submit it to the patch tracker for the devs to have a look at, and consider for inclusion.
Or if it's one major change, and a few minor changes, just post it here in [ code ] tags.
If it's very clean, and works properly, you may want to submit it to the patch tracker for the devs to have a look at, and consider for inclusion.
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
#irrlicht on irc.freenode.net
Ok. Here are the changes in a text diff format output by examdiff pro (they are very minor changes). < means the lines were added. > are those which were removed. If there's a better way please let me know.
Changes to IMeshSceneNode.h :-
8d7
< #include "IShadowVolumeSceneNode.h"
35,51d33
<
< //! Creates shadow volume scene node as child of this node
< //! and returns a pointer to it. The shadow can be rendered using the ZPass
< //! or the zfail method. ZPass is a little bit faster because the shadow volume
< //! creation is easier, but with this method there occur ugly looking artifacs
< //! when the camera is inside the shadow volume. These error do not occur
< //! with the ZFail method.
< //! \param id: Id of the shadow scene node. This id can be used to identify
< //! the node later.
< //! \param zfailmethod: If set to true, the shadow will use the zfail method,
< //! if not, zpass is used.
< //! \param infinity: Value used by the shadow volume algorithm to scale the
< //! shadow volume.
< //! \return Returns pointer to the created shadow scene node.
< //! This pointer should not be dropped. See IUnknown::drop() for more information.
< virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id=-1,
< bool zfailmethod=true, f32 infinity=10000.0f) = 0;
Changes to CMeshSceneNode.h :-
9d8
< #include "IShadowVolumeSceneNode.h"
49,58d47
< //! Creates shadow volume scene node as child of this node
< //! and returns a pointer to it.
< virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id,
< bool zfailmethod=true, f32 infinity=10000.0f);
<
< //! Removes a child from this scene node.
< //! Implemented here, to be able to remove the shadow properly, if there is one,
< //! or to remove attached childs.
< virtual bool removeChild(ISceneNode* child);
<
91,92d79
<
< IShadowVolumeSceneNode* Shadow;
Changes to CMeshSceneNode.cpp :-
10,11d9
< #include "os.h"
< #include "CShadowVolumeSceneNode.h"
26c24
< : IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), PassCount(0), Shadow(0),
---
> : IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), PassCount(0),
43,45d40
<
< if (Shadow)
< Shadow->drop();
48,55d42
< //! Creates shadow volume scene node as child of this node
< //! and returns a pointer to it.
< IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode(s32 id,
< bool zfailmethod,
< f32 infinity)
< {
< if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))
< return 0;
57,80d43
< if (Shadow)
< {
< os::Printer::log("This node already has a shadow.", ELL_WARNING);
< return 0;
< }
<
< Shadow = new CShadowVolumeSceneNode(this, SceneManager, id, zfailmethod, infinity);
< return Shadow;
< }
<
< //! Removes a child from this scene node.
< //! Implemented here, to be able to remove the shadow properly, if there is one,
< //! or to remove attached childs.
< bool CMeshSceneNode::removeChild(ISceneNode* child)
< {
< if (child && Shadow == child)
< {
< Shadow->drop();
< Shadow = 0;
< return true;
< }
<
< return (ISceneNode::removeChild(child));
< }
211,213d173
<
< if (Shadow && PassCount==1)
< Shadow->setMeshToRenderFrom(Mesh);
Changes to IMeshSceneNode.h :-
8d7
< #include "IShadowVolumeSceneNode.h"
35,51d33
<
< //! Creates shadow volume scene node as child of this node
< //! and returns a pointer to it. The shadow can be rendered using the ZPass
< //! or the zfail method. ZPass is a little bit faster because the shadow volume
< //! creation is easier, but with this method there occur ugly looking artifacs
< //! when the camera is inside the shadow volume. These error do not occur
< //! with the ZFail method.
< //! \param id: Id of the shadow scene node. This id can be used to identify
< //! the node later.
< //! \param zfailmethod: If set to true, the shadow will use the zfail method,
< //! if not, zpass is used.
< //! \param infinity: Value used by the shadow volume algorithm to scale the
< //! shadow volume.
< //! \return Returns pointer to the created shadow scene node.
< //! This pointer should not be dropped. See IUnknown::drop() for more information.
< virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id=-1,
< bool zfailmethod=true, f32 infinity=10000.0f) = 0;
Changes to CMeshSceneNode.h :-
9d8
< #include "IShadowVolumeSceneNode.h"
49,58d47
< //! Creates shadow volume scene node as child of this node
< //! and returns a pointer to it.
< virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id,
< bool zfailmethod=true, f32 infinity=10000.0f);
<
< //! Removes a child from this scene node.
< //! Implemented here, to be able to remove the shadow properly, if there is one,
< //! or to remove attached childs.
< virtual bool removeChild(ISceneNode* child);
<
91,92d79
<
< IShadowVolumeSceneNode* Shadow;
Changes to CMeshSceneNode.cpp :-
10,11d9
< #include "os.h"
< #include "CShadowVolumeSceneNode.h"
26c24
< : IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), PassCount(0), Shadow(0),
---
> : IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), PassCount(0),
43,45d40
<
< if (Shadow)
< Shadow->drop();
48,55d42
< //! Creates shadow volume scene node as child of this node
< //! and returns a pointer to it.
< IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode(s32 id,
< bool zfailmethod,
< f32 infinity)
< {
< if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER))
< return 0;
57,80d43
< if (Shadow)
< {
< os::Printer::log("This node already has a shadow.", ELL_WARNING);
< return 0;
< }
<
< Shadow = new CShadowVolumeSceneNode(this, SceneManager, id, zfailmethod, infinity);
< return Shadow;
< }
<
< //! Removes a child from this scene node.
< //! Implemented here, to be able to remove the shadow properly, if there is one,
< //! or to remove attached childs.
< bool CMeshSceneNode::removeChild(ISceneNode* child)
< {
< if (child && Shadow == child)
< {
< Shadow->drop();
< Shadow = 0;
< return true;
< }
<
< return (ISceneNode::removeChild(child));
< }
211,213d173
<
< if (Shadow && PassCount==1)
< Shadow->setMeshToRenderFrom(Mesh);