Scripted multipass render to add outlines?

2

Comments

  • zigraphixzigraphix Posts: 2,787
    edited November 2012

    Ok... partial success! The top image uses colorid, the bottom one uses normals.

    Now the problem I have is that the camera doesn't refresh the outline image before compositing. :-S Ever. Including between runs of DS. So once I've set the outline image, it stays set to the same copy of that image, even if the image itself on the hard drive changes. :( The only two ways I have to get around this are 1) change the image to a name I haven't used yet or 2) run the outline image through Layered Image Editor (which effectively does the same thing).

    Also, now I've lost the background, of course, but that's not a huge surprise. I might even be able to figure out how to get it back.

    good.png
    490 x 490 - 96K
    near_success.jpg
    490 x 490 - 64K
    Post edited by zigraphix on
  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    An example of the problem... maybe if I use a script to clear the cache?

    RenderEdit_Image.png
    490 x 490 - 138K
  • ketthroveketthrove Posts: 63
    edited December 1969

    You need to call refresh() on the DzTexture on the properties your are setting.

  • zigraphixzigraphix Posts: 2,787
    edited November 2012

    ketthrove said:
    You need to call refresh() on the DzTexture on the properties your are setting.

    I'm setting the image property in the Parameters tab of a Shader Mixer camera. I'm not sure how to get to that from within the render time script. I tried this, but it didn't seem to quite do the trick... I'm back to getting the "color id" render again. :(

    
    // Set up crop window
    Renderer.setCropWindow( oHandler );
    
    // refresh outline image
    oProperty = oOwner.findProperty( "0utlineImage" );
    oProperty.refresh();
    
    // Set up the display(s)
    Renderer.doDefaultDisplay();
    
    Post edited by zigraphix on
  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    BTW, if I can get this working in time, I'd like the toon cam with outline to be my freebie for Christmas this year....

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    I can't figure out where to put this refresh (assuming I'm doing it correctly). The line I'm trying to add is:

    Camera.outlineImage.refresh();

    Within the Beauty Pass, if I put it between Renderer.riWorldBegin() and the //Render each node comment, I get a solid black render. If I put it after rendering the nodes but before Renderer.riEndWorld() it renders, but composites the old (cached) outline image. If I put it after Renderer.riEndWorld() DS crashes on render.

    If I put it between Renderer.riBegin and Renderer.riWorldBegin(), I get a colorid render, rather than the camera render (see previous examples).

    All of the above (except the crashes) drop the render window behind the DS window, for some reason.

    After the Outline Pass, between Renderer.riEndWorld and Renderer.riBegin for the Beauty Pass, it crashes on render.

    Within the Outline Pass, between Renderer.riWorldBegin and Renderer.riEndWorld, a colorid render is generated, the outline files are correctly generated, and for whatever reason, the render window does not drop behind the main DS window.

    Where is this refresh supposed to go? Or have I got the syntax wrong? I would really prefer not to have to code the camera itself-- I want this to be a script that works with multiple cameras, so people who use Shader Mixer can use it.

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    This is frustrating.

    Here's where I am now. Through much trial and error (and abuse of the MessageBox class) I have determined that the property I need to aim the refresh at is this one:

    Camera.getProperty(35).getMapValue().refresh();

    (I can't for the life of me figure out how to access this by the name instead of the number, but whatever.)

    And, sure enough, in the log I see "Loaded image Outline_Frm0_Normal.jpg" between the first pass and second pass renders.

    
    Ran tdlmake on image C:/Users/zigraphix/Documents/daz content/Projects_content/Projects/sketch/nov1/Outline_Frm0_Normal.jpg
    Loaded image Outline_Frm0_Normal.jpg
    Loaded image Outline_Frm0_Normal.jpg
    Rendering image
    3Delight message #145 (Severity 1): S2073: 'Min' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'Max' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMin' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMax' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    Loaded image Outline_Frm0_Normal.jpg
    3Delight message #145 (Severity 1): S2073: 'Min' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'Max' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMin' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMax' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    Saved image: C:\Users\zigraphix\AppData\Roaming\DAZ 3D\Studio4\temp\render\r.png
    Finished Rendering
    Total Rendering Time: 4.54 seconds
    Loaded image r.png
    Saved image: C:\Users\zigraphix\AppData\Roaming\DAZ 3D\Studio4\temp\RenderAlbumTmp\Render 2.jpg
    
    

    Yay!

    Except... the image that is being composited is still the old image. Boo. The improvement is that every time I render, the outline image from the previous render gets used, which is better than before, when the outline image NEVER got updated... but still not good enough.

    I've tried putting the refresh call as early as possible. If I put it before riBegin, it renders black and throws an error. Right now I have it right before riWorldBegin. I also tried forcing tdlmake by adding this line right after the refresh:

    Renderer.prepareImage(Camera.getProperty(35).getMapValue(), Camera.getProperty(35).getMapValue().getFilename());
    

    Now in the log I get:

    
    Ran tdlmake on image C:/Users/zigraphix/Documents/daz content/Projects_content/Projects/sketch/nov1/Outline_Frm0_Normal.jpg
    WARNING: images\dzimagemgr.cpp(596): Image C:/Users/zigraphix/Documents/daz content/Projects_content/Projects/sketch/nov1/Outline_Frm0_Normal.jpg not found in the list in DzImageMgr::imagePrepared()
    
    

    It doesn't matter if I put the refresh call before or after the prepareImage call.

    Argh.

    I'm going to go have some chocolate and maybe I'll look at this again tomorrow. :(

  • ketthroveketthrove Posts: 63
    edited December 1969

    It looks like the prepare of images (tdlmake, that which takes an image and prepares it for 3Delight consumption) is only called at the beginning of the render, before the individual frames are rendered.

    You'll need to manually call the image prep:

    
    App.getImageMgr().prepareAllImages(Renderer);
    

    This should be done after the first call to riEnd, but before the second call to riEndWorld.

    To find a property by name you use findProperty(), or findPropertyByLabel(). Warning, however, shader mixer will rename properties as you connect/disconnect bricks to each other. So before you finish your camera set the name on the property to you're desired name before saving the preset for the camera. Make sure you check the return of findProperty is the one you though you were getting. You can all so use the methods on DzShaderBrick to find properties by their parameter name, parameter names do not change on the brick.

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    Thanks for the warning about property names changing as the shader is edited in Shader Mixer.

    Unfortunately, adding "App.getImageMgr().prepareAllImages(Renderer);" has not made any difference, though I've tried adding it in several places. However, I noticed that I have no instances of riEnd in either rendering pass-- they weren't in the original scripts I was working from.

    In the original OutlineRenderScript.dsa, I see Renderer.riBegin right after the sRIB section, then a bunch of setup stuff where parameters are set, then Renderer.riWorldBegin, rendering the nodes, then Renderer.riEndWorld.

    In StandardExampleRenderScript.dsa, again Renderer.riBegin comes right after the RIB Path calculation, the parameters are all set up, Renderer.riWorldBegin is called, the shadows are layered and nodes are rendered, and then Renderer.riEndWorld.

    Where should riEnd go? I don't see it listed in the docs at all.

  • ketthroveketthrove Posts: 63
    edited November 2012

    I meant "riEndWorld" sorry. You also still need to call that refresh on the property map you were doing before.

    Post edited by ketthrove on
  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    Ok, after the first riEndWorld(), before the second riEndWorld(). Got it. But I already tried that....

    Should "App.getImageMgr().prepareAllImages(Renderer);" go before or after "Camera.getProperty(35).getMapValue().refresh();"? Do I need to remove "Renderer.prepareImage(Camera.getProperty(35).getMapValue(), Camera.getProperty(35).getMapValue().getFilename());"?

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    I did it this way, right before the Beauty Pass riWorldBegin():

    
    // Set up the display(s)
    Renderer.doDefaultDisplay();
    
    // outline refresh here
    Camera.getProperty(35).getMapValue().refresh();
    App.getImageMgr().prepareAllImages(Renderer);
    
    // Begin describing the scene
    Renderer.riWorldBegin();
    

    I still don't get the right outline image, but I'm no longer getting errors about a missing prepared image....

    
    Saved image: C:\Users\zigraphix\AppData\Roaming\DAZ 3D\Studio4\temp\render\r.png
    Finished Rendering
    Total Rendering Time: 2.92 seconds
    Loaded image r.png
    Saved image: C:\Users\zigraphix\AppData\Roaming\DAZ 3D\Studio4\temp\RenderAlbumTmp\Render 6.jpg
    Rendering image
    3Delight message #145 (Severity 1): S2073: 'Min' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'Max' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMin' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMax' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    Loaded image Outline_Frm0_Normal.jpg
    Ran tdlmake on image C:/Users/zigraphix/Documents/daz content/Projects_content/Projects/sketch/nov1/Outline_Frm0_Normal.jpg
    3Delight message #145 (Severity 1): S2073: 'Min' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'Max' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMin' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMax' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    

    (Is there anything I can do about the Min and Max errors? I'm not using those variables in my very simple camera shader....)

  • ketthroveketthrove Posts: 63
    edited December 1969

    Using your code it should probably be the following:

    
    // Start rendering; the string argument is shown in the progress dialog
    Renderer.riEndWorld( "Rendering: Scripted Render Example..." );
    
    // outline refresh here
    Camera.getProperty(35).setMap(""); //clear the texture
    Camera.getProperty(35).setMap("path/to/generated/outline.png");
    Camera.getProperty(35).getMapValue().refresh();
    App.getImageMgr().prepareAllImages(Renderer);
    
    
    // Do the beauty pass
    

    The texture needs to not be set until its made the first time. Just as a warning index is just as likely to change as name for the property.

  • zigraphixzigraphix Posts: 2,787
    edited November 2012

    Yay! Thank you!!! :lol:

    Now I just need to put together some loader scripts to set up the camera and set the rendering script. (And incorporate a real background, but I think I have some hints about that.)

    Does anyone know how to get rid of these errors? They show during the render, and I'd like to avoid confusing users.

    
    3Delight message #145 (Severity 1): S2073: 'Min' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'Max' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMin' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    3Delight message #145 (Severity 1): S2073: 'SceneMax' is not a parameter of shader 'brickyard/{cba2c4ea-0574-4e3a-9407-f98b0707092e}/shader_Imager'
    
    success.jpg
    490 x 490 - 62K
    Post edited by zigraphix on
  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    I think I need another hint to figure out how to pick up the background when using a brick camera. There is a note in the sample script that says "TODO: Check for DzShaderCamera & DzBrickCamera with Imager" -- Camera.className() tells me "DzBrickCamera", but then what? I just want to use whatever the user has set as the backdrop color or image in the scene, but "Renderer.renderBackDrop( BackDrop, sizeRender.width, sizeRender.height );" before the Renderer.cameraProject line doesn't seem to do anything.

  • ReDaveReDave Posts: 815
    edited December 1969

    I think there was something about that in the example scripts Rob made: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/start (Render to backdrop and/or to Viewport, at the bottom of the linked page). *Sigh* too many fingers in too many pies, I can't think straight.

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    I got a backdrop specified in the camera to work, so I'm going with that for now. But I'll look at Rob's examples again-- I did read through them a couple of weeks ago, but I understand more about scripting now than I did then....

  • TugpsxTugpsx Posts: 738
    edited December 1969

    Curious did you ever finish this little project?

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    Tugpsx said:
    Curious did you ever finish this little project?

    Still working on it. The render works, but there are still too many manual steps to set it up. If you'd like to take a look, pm me.

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    When I use the "Save render settings" utility with my Scripted 3Delight settings, it doesn't capture the render engine information. The file that is created has this info:

    
     "scene" : {
      "extra" : [
       {
        "type" : "studio_render_settings",
        "render_options" : {
         "aspect_ratio" : [ 10, 13 ],
         "startTime" : 0,
         "endTime" : 1,
         "renderMovToId" : "ImageSeries",
         "renderViewport" : false,
         "isAspectConstrained" : true,
         "imageSize" : [ 500, 650 ],
         "renderType" : "Software",
         "renderStyle" : "Normal",
         "rayTraceDepth" : 1,
         "openGLPasses" : 1,
         "useGLSL" : false,
         "isCurrentFrameRender" : true,
         "useMotionBlur" : false,
         "motionBlurPct" : 100,
         "motionBlurSamples" : 2,
         "xPixelSamples" : 4,
         "yPixelSamples" : 4,
         "shadowSamples" : 10,
         "shadingRate" : 2,
         "doubleSided" : true,
         "gain" : 1,
         "gamma" : 1,
         "pixelFilter" : "Sinc",
         "xFilterWidth" : 6,
         "yFilterWidth" : 6
        }
       }
      ]
     }
    
    

    I think I need to change "renderType" to something other than "Software," but what? Then I'll also need to select the appropriate script, so I'll need to figure out what that option is called. There's no context help for either of these options. Does anyone know how to refer to them in a render preset script?

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    I found an old script someone shared with me two years ago, and was able to get the setting renderType to scripted renderer to work. However, I'm still having trouble setting the render script. The log doesn't show any errors, but if I try to include the variable that should have the path to the script in a messagebox, there's nothing there.

    This sets the path to my render script:

    var sRENDER_SCRIPT = "support/DAZ/ScriptedRenderer/Outline Compositor/OutlineCompositorRenderScript.dsa";
    

    The list of available scripts works after this is run, but I still can't figure out how to set it....

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    Does anyone know how I can determine the name of a widget from strings files or anything like that? I need to know how to refer to the script selector widget.

  • Richard HaseltineRichard Haseltine Posts: 100,888
    edited December 1969

    What do you mean by widget?

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    In scripting terms, I mean property. I have a variable set to the path to the script I want to use, but I don't know the name of the property to set to that variable.

  • Richard HaseltineRichard Haseltine Posts: 100,888
    edited December 1969

    A DzProperty derivative has a getLabel() function and a name member - both strings.

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    Ok, I'll see if I can iterate through the children of the parent property and find it that way-- thanks for the reminder.

  • Richard HaseltineRichard Haseltine Posts: 100,888
    edited December 1969

    DzProperties don't have children, so I'm wondering if we are talking about different things.

  • zigraphixzigraphix Posts: 2,787
    edited December 1969

    Probably not. I have a terrible time knowing what to call things in this scripting language.

    I have set these variables:

    
    var oRENDER_MANAGER = App.getRenderMgr();
    var oRENDERER = oRENDER_MANAGER.findRenderer("DzScriptedRenderer");
    var sRENDER_SCRIPT = "support/DAZ/ScriptedRenderer/Outline Compositor/OutlineCompositorRenderScript.dsa";
    

    and then I want to use them here:

    oRENDERER.setRenderScript( sRENDER_SCRIPT );

    but it doesn't work-- the value of the script referenced in the Render Settings panel doesn't change. I suspect the name of the thingy I'm trying to set has changed. ( Where "thingy" here refers to "oRENDERER.setRenderScript()".)

  • Richard HaseltineRichard Haseltine Posts: 100,888
    edited December 1969

    No error? I'm not sure what you need, but you can use Rob's trick to look for the functions in DzRenderer in DS4:

    for ( var o in oRENDERER ) {
    print ( o );
    }

  • RenpatsuRenpatsu Posts: 828
    edited December 1969

    zigraphix said:
    Probably not. I have a terrible time knowing what to call things in this scripting language.

    I have set these variables:

    
    var oRENDER_MANAGER = App.getRenderMgr();
    var oRENDERER = oRENDER_MANAGER.findRenderer("DzScriptedRenderer");
    var sRENDER_SCRIPT = "support/DAZ/ScriptedRenderer/Outline Compositor/OutlineCompositorRenderScript.dsa";
    

    and then I want to use them here:

    oRENDERER.setRenderScript( sRENDER_SCRIPT );

    but it doesn't work-- the value of the script referenced in the Render Settings panel doesn't change. I suspect the name of the thingy I'm trying to set has changed. ( Where "thingy" here refers to "oRENDERER.setRenderScript()".)

    Despite the UI of the render options not changing, it seems "internally" it is working. Via the following script I can invoke the "Point-based occlusion" render without having it selected beforehand:

    var oRenderMgr = App.getRenderMgr();
    var oRenderer = oRenderMgr.findRenderer("DzScriptedRenderer");
    oRenderMgr.setActiveRenderer( oRenderer );
    oRenderer.setRenderScript( "support/DAZ/ScriptedRenderer/Point-Based Occlusion/PointBasedOcclusionRenderScript.dsa" );
    oRenderMgr.doRender();
Sign In or Register to comment.