ShaderEffector: IsDirty(DIRTYFLAGS::DATA) always true?

  • Hello,

    I noticed that the Shader Effector always returns true for IsDirty(DIRTYFLAGS::DATA). Even if it doesn't do anything.
    This somehow destroys caching in our plugins that support Effectors.

    Test it by simply creating a scene with just a Shader Effector, attaching a Python Tag to the effector, and putting in this code:

    import c4d
    def main():
        effectorOp = doc.SearchObject("Shader")
        dirtyMatrix = effectorOp.IsDirty(c4d.DIRTYFLAGS_MATRIX)
        dirtyData = effectorOp.IsDirty(c4d.DIRTYFLAGS_DATA)
        dirtyCache = effectorOp.IsDirty(c4d.DIRTYFLAGS_CACHE)
        dirtyAll = effectorOp.IsDirty(c4d.DIRTYFLAGS_ALL)
        print("dirtyMatrix: " + str(dirtyMatrix) + ", " + "dirtyData: " + str(dirtyData) + ", " + "dirtyCache: " + str(dirtyCache) + ", " + "dirtyAll: " + str(dirtyAll))

    Any time the tag is executed (be it by playing back the animation, changing anything in the scene, or just by wildly waving the mouse around), DIRTYFLAGS_DATA returns true.

    Is there any way to know if the Effector is actually dirty?

    Thanks & greetings,

  • Hi,

    this is probably a safeguard against the uncertainty of shader dirty state evaluation. While a shader node can be evaluated for its dirty state like any other node, that does say very little about what the shader does in its sample function. The shader could be dependent on the craziest combination of scene graph attributes and unravelling that is not that easy / simply impossible. So the effector samples the shader every time it has a chance to do so.

    A very ugly solution to the problem would to be to coarsely sample the effector on a carefully chosen bounding box and and cache these samples. Upon evaluation you would resample the effector testing for it to match your cache. The obvious flaws would be that this is computationally expensive and also prone to False Negatives when your cache grid stride steps over some finer details in the shader.


  • What do you want to learn by checking dirty?

    A Shader Effector could use a "Noise" shader. In that Noise shader, you can enable "Animation Speed".

    So the Shader effector will create a different result for every frame, even no parameter values change.

  • Yeah, I know shaders can depend on basically anything in the scene.

    And I guess there is no way to know for sure (would be cool if shaders could return a flag the indicates if it actually is animating or changing without changes to the container).

    So, it really seems they are always dirty because of this. Damn :D I would prefer them to only be dirty if the shader node changes. That way it would be up to the develop if they rely on the dirty results or not.


  • Hi @fwilleke80, unfortunately, I confirm the shader effect is almost always dirty. I don't have any real workaround maybe you can retrieve all noises and compute their dirtiness, but this is indeed a very hard topic to handle all cases because you will also need to handle the actual parameter of the shader effector itself.