Assigning Volume shader at render time
djigneo
Posts: 283
I'm trying to modify the 'Standard Example' scripted 3Delight render script to tell 3delight to use the Volume shader from the camera.
When rendering with the standard (not scripted) 3Delight rendering, the volume shader takes effect. In the 'Standard Example' render script it does not. The camera is created via Shader mixer, its Root is a Volume brick.
I suspect the call that is required is Renderer.riAtmosphere()
, but I'm unclear what to pass for the parameters. Confusingly, the Camera
variable does not have a getShader()
method either, which leads me to believe at runtime it is not a dzShaderCamera
as I would expect.
Any hints?
Post edited by djigneo on
Comments
I wish I could help, but it's exactly where I got stuck myself. You're right about the RiAtmosphere call, but it's getting the shader from the camera that is a problem. Shader Mixer cameras doubly so - the class is likely to be called "DzBrickCamera", if we go by the line in the example render script... but there is no documentation.
Break out the crystal balls, candles, incense and other arcane trappings...because, this is one of the those where it seems to be an arcane art as opposed to anything modern.
Maybe one of the resident wizards will drop by to give some insight on this...
Getting the class name is easy - create a camera, select it and in the SctiptIDE window run
print( Scene.getPrimarySelection().className() );
Yes, as @Mustakettu85 said, it is indeed a
DzBrickCamera
.Richard (how do you link to users that have a space in their name?), I think it's important to print the
Camera.className()
out during render script execution (which I did). It's not safe to assume theCamera
variable is the exactly the same instance as the currently active camera.Using a hardcoded shader, I was able to convince 3Delight to use a volume shader.
It's definitely not pretty, but it gives me a clue that
Renderer.riAtmosphere()
wants a compiled shader (either *.SL or *.SDL).I just meant if you needed to know the class name of a particular camera type that technique would work - you should of course validate anything you use in the render script.
I think I may have figured it out.
I'll keep playing, but this seems to be on the right track.
Thanks for the tip, Richard!
djigneo - this is getting seriously awesome. Does the getBrickSet method populate the shader settings automagically, or do we need to make the script pick them up from the scene into aTokens/aParams?
Oh just in case, the .sdl is the compiled shader, and you can omit the extension (at least, in all other contexts you can omit it for sure, so there's no reason not to omit it here).
I haven't played a bunch with it yet, but the render looked reasonable, though I hadn't been doing a whole lot with the parameters yet. It should be easy to verify one way or the other by creating an obvious "everything is one color" volume shader and setting it to a non-default color. Worst case scenario is looping through the custom camera parameters and generating the
aTokens
, andaParams
arrays, I guess.Presumably, you would want to make the
riAtmosphere()
call for each BrickSet the camera has. I think there may be one for each root (Volume, Imager, etc), though that's entirely speculative. I"m guessing it would be wise to also to check that it's a Volume root.I was planning on working on a render script before too long, so we can compare notes a little later, if you like.
Imager shaders would be processed with RiImager.
I haven't yet had time to test if the "magic" is there or not, so yeah, a bit later.
Here's what I've got so far. This seems to apply the shader in the case of a
DzBrickCamera
. I haven't tested theDzShaderCamera
yet, but I am trying to handle the basics at least. I'm not sure about the shader parameters yet.Thanks for the code! Testing now... checking in the RIBs.
For a shader mixer imager shader (like the one doing colorise in AoA's Atmospherics) with a dzBrickCamera the parameters are passed automagically.
Not the case for an atmosphere shader (Ri_Fog from shader builder and a hacked-off version of AoA's fog cam) attached to either dzBrickCamera or dzShaderCamera. They will need querying.
Updated above code to more correctly use
QObject.inherits()
instead of comparing directly to expected instanced class.Essentially:
was changed to:
Will test later this week, thank you for the update!
...haven't forgotten about this thread, but haven't had much free time unfortunately.
I can't seem to figure out the way to iterate over shader properties efficiently. There is a getNumProperties () method, but there is no "getProperty(index)" method that could be used in a cycle. There is only a findProperty (string) one, but how exactly do we get these property names?
getProperty( number ) takes the index values from 0 up to getNumProerpties().
Wait, Richard, do you mean there _is_ a getProperty() method to dzRSLShader class, it's just not documented?
Sorry, I thought the discussion was materials - which ar derived from DzEleemnt and so have getProeprties. No, RSLShader doesn't have that method.
I wonder if the properties are named consistently with the properties on the
DzBrickCamera
, though theoretically there could be manyDzRSLShader
to oneDzBrickCamera
. Pure speculation from me at this point, but it would perhaps make sense. If that were the case, then the approach would be:For each property on DzBrickCamera, try to find an identically named property on one of the related DzRSLShaders. If found, set properties equal to each other.
I am starting to have a need for honoring the Camera shader parameters, so maybe I'll investigate before too long.
This seems feasible.
One thing to watch out for may be the fact that property names, property labels and actual shader parameter names can be all different. The latter are accessed via 'tokens', if I get it right.