Assigning Volume shader at render time

djigneodjigneo 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

  • Mustakettu85Mustakettu85 Posts: 2,933

    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.

     

  • mjc1016mjc1016 Posts: 15,001

    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() );

  • djigneodjigneo Posts: 283
    edited October 2015

    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 the Camera 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.

    aTokens = [];aParams = [];Renderer.riAtmosphere("c:/daz3d/shaders/daz/uber/volume/omUberVolume.sdl", aTokens, aParams);

    It's definitely not pretty, but it gives me a clue that Renderer.riAtmosphere() wants a compiled shader (either *.SL or *.SDL).

    Post edited by djigneo on
  • 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.

  • djigneodjigneo Posts: 283

    I think I may have figured it out.

    Renderer.riAtmosphere(Camera.getBrickSet(0).getFullShaderPath(), aTokens, aParams);

    I'll keep playing, but this seems to be on the right track.

  • Mustakettu85Mustakettu85 Posts: 2,933

    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).

     

  • djigneodjigneo Posts: 283
    edited October 2015

    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, and aParams 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.

    Post edited by djigneo on
  • Mustakettu85Mustakettu85 Posts: 2,933

    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.

  • djigneodjigneo Posts: 283
    edited November 2015

    Here's what I've got so far. This seems to apply the shader in the case of a DzBrickCamera. I haven't tested the DzShaderCamera yet, but I am trying to handle the basics at least. I'm not sure about the shader parameters yet.

    // functions areafunction setCameraShader(iShaderType, sShaderFile) {	var bIsVolumeShader;		switch(iShaderType) {		case DzRSLShader.VolumeAtmosphere:		case DzRSLShader.VolumeInterior:		case DzRSLShader.VolumeExterior:					bIsVolumeShader = true;			break;		default:			bIsVolumeShader = false;	}				var bIsImagerShader;	switch(iShaderType) {		case DzRSLShader.Imager:			bIsImagerShader = true;			break;		default:			bIsImagerShader = false;			break;	}	if (bIsVolumeShader == true) {		aTokens = [];		aParams = [];		Renderer.riAtmosphere(sShaderFile, aTokens, aParams);	}	if (bIsImagerShader == true) {		aTokens = [];		aParams = [];		Renderer.riImager(sShaderFile, aTokens, aParams);	}}

     

    // right after this line...Renderer.cameraProject( Camera, sizeRender.width, sizeRender.height );if (Camera.inherits(DzBrickCamera.className())) {		for (var i = 0; i < Camera.getNumBrickSets(); i++) {		var oBrickSet = Camera.getBrickSet(i);				setCameraShader(oBrickSet.getShaderType(), oBrickSet.getFullShaderPath());			}}if (Camera.inherits(DzShaderCamera.className())) {	for (var i = 0; i < Camera.getNumShaders(); i++) {		var oRslShader = Camera.getShader(i);				setCameraShader(oRslShader.getShaderType(), oRslShader.getShaderFile());			}}

     

     

    Post edited by djigneo on
  • Mustakettu85Mustakettu85 Posts: 2,933
    edited November 2015

    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.

     

    Post edited by Mustakettu85 on
  • djigneodjigneo Posts: 283
    edited November 2015

    Updated above code to more correctly use QObject.inherits() instead of comparing directly to expected instanced class.

    Essentially:

    if (Camera.className() == DzShaderCamera.className()) {

    was changed to:

    if (Camera.inherits(DzShaderCamera.className())) {

     

    Post edited by djigneo on
  • 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.

  • djigneodjigneo Posts: 283

    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?

    I wonder if the properties are named consistently with the properties on the DzBrickCamera, though theoretically there could be many DzRSLShader to one DzBrickCamera. 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.

Sign In or Register to comment.