Page 1 of 2

[feature requests] SceneNode parameter for shader.

Posted: Sun Aug 12, 2012 4:58 am
by clarks
I am quite sure that this has been asked for already. It would be nice to have a parameter, or some way of knowing which scenenode is being rendered when IShaderConstantSetCallback gets called. This is required if multiple objects use one shader with different parameters like color.

Re: [feature requests] SceneNode parameter for shader.

Posted: Sun Aug 12, 2012 7:09 pm
by devsh
I vote yes!!

Because the amount of times I had to code around that to achieve the feature

Personally I think irrlicht SMaterial should have a "void* userData" field

Re: [feature requests] SceneNode parameter for shader.

Posted: Sun Aug 12, 2012 10:36 pm
by hybrid
This request has absolutely nothing to do with the user data attribute (and this won't ever go into the engine). But yes, the information for shaders was requested already, but the necessary changes have not yet been discussed or defined.

Re: [feature requests] SceneNode parameter for shader.

Posted: Sun Aug 12, 2012 11:23 pm
by Mel
You may know which scene node is being rendered using a lighting manager, but a callback parameter would be a more convenient way.

How about having a ISceneNode pointer on the shader callbacks interface that is set to the current scene node being rendered which is using the current shader, prior to the onSetMaterial call? Then, the shader callback interface would have a method to get this pointer, and that would do it.

Re: [feature requests] SceneNode parameter for shader.

Posted: Sun Aug 12, 2012 11:48 pm
by clarks
Well I personally think that we should start this discussion already, unless there is some reason why we should not. This would give irrlicht more flexibility and thus make it more powerful when dealing with shaders. Since IShaderConstantSetCallback can only take one userData, there is no room for flexibility. A change that we need is something along the lines of setting a shader constant callback for a specific node with userdata for that node. It goes something like this:

Code: Select all

 
bool ISceneNode::setShaderConstantCallback( IShaderConstantSetCallback* callback, u32 userData );
 
where userData is data specific to the node and not the shader. Thus multiple different nodes can call this function with the same shader callback with different userData, which gives more flexibility. Another suggestion would be to do this:

Code: Select all

 
virtual void IShaderConstantSetCallback::OnSceneNode( const ISceneNode* node ) {}
 

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 4:44 am
by Granyte
I found an interestign way to work around by using a std map and the second material data

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 4:52 am
by clarks
I found an interestign way to work around by using a std map and the second material data
Can you elaborate on this please?

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 7:56 am
by CuteAlien
I guess he means abusing one of the material values he doesn't use otherwise (for example MaterialTypeParam2) and setting it to the key of std::map which contains further information. Basically just using any of the unused variables as userdata parameter.

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 10:14 am
by hendu
FWIW, I've had to code around this too. But having the scene node param there wouldn't help much, because I'd still need to match it to something else, knowing just the node is not useful to me. So the amount of code is close to the same even with the proposed param.

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 12:26 pm
by devsh
in the normal world of FFMPEG and other libraries

void* userData;

is the best way, as you can use it IN ANY WAY YOU LIKE

this way you only need one parameter for AN ARBITRARY NUMBER OF PARAMETERS that you may want to add to SMaterial simply by having a pointer to a struct object or class.

I.E.

struct HardwareTessellationAndPOMParameters
{
float height;
float levelDistances[8];
float mipMapOffset;
bool displaceInProjectionSpace;
};

obviously since there is ONE Material Type, this means shader wont get reset. But since there is ONE SMATERIAL PER MESH BUFFER OR NODE, this means that userData of the materials can point to nodes themselves.

Then we can also have a SAFECOPY() when we copy materials from mesh to mesh or node to node, so userData gets set to NULL

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 1:16 pm
by CuteAlien
Might be better to hava a IUserData interface that also has a serialize and deserialize function. Maybe also some copy-functions (copy pointer, clone).

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 8:52 pm
by Mel
I think this isn't about serializing custom user data, but about having access to the current scene node being rendered from the constants set interface. In fact, the constants set interface is already bound to the SMaterial, whenever a material is set, it uses the proper interface to set the constants of any shader. Thus, it is simpler to modify the constants set interface to have the proper scene node. Setting something similar to a lighting manager that executed an "onNodePreRender" to set the current node would help.

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 10:05 pm
by clarks
But having the scene node param there wouldn't help much, because I'd still need to match it to something else, knowing just the node is not useful to me. So the amount of code is close to the same even with the proposed param.
What do you think about this?

Code: Select all

class SPaintParams
{
public:
    SColor3f mColor;
};
 
class PaintShader: public IShaderConstantSetCallBack
{
    std::map<ISceneNode*,SPaintParams*> mNodePair; // hmmm!
    std::map<ISceneNode*,SPaintParams*>::iterator mActivePair;
public:
  PaintShader() {}
  ~PaintShader() {}
 
    void AddParam( const ISceneNode* node, const SPaintParams& param )
    {
        // add the node and param to the pair
    }
    
    void OnSetNode( const ISceneNode* node ) 
    {
        mActivePair = mNodePair.find(node); /// compiler might complain about this
    }
    
    void OnSetConstants(IMaterialRendererServices* services, s32 userData)
    {
        SPaintParams& param = mActivePair.second; /// blah blah blah
    }
};
 
If this does the trick then finding a way to generalize it is the answer.

Re: [feature requests] SceneNode parameter for shader.

Posted: Mon Aug 13, 2012 11:54 pm
by Mel
It is faster to have a lighting manager telling the current node being rendered than searching for it.

Code: Select all

 
class customLightManager : public scene::ILightingManager
{
public:
scene::ISceneNode* currentNode;
...
void OnNodePreRender (ISceneNode *node)
{
currentNode = node;
}
...
};
 
class customShaderCallback : public video::IConstantsSetCallback
{
customLightManager* clm;
...
}
 
That way, you need to tell the constants set callback which is the custom light manager you are using, and that is all. You, later, can access the node via clm->currentNode. It is safe to use it because the OnNodePreRender is called only once per node each pass before the shader is actually used, and so, you can set your constants also on a per node basis, besides and independently of the material data.

Re: [feature requests] SceneNode parameter for shader.

Posted: Tue Aug 14, 2012 7:04 am
by Granyte
CuteAlien wrote:I guess he means abusing one of the material values he doesn't use otherwise (for example MaterialTypeParam2) and setting it to the key of std::map which contains further information. Basically just using any of the unused variables as userdata parameter.
That's exactly what i ment.