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.
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();
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.
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:
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. :(
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.
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.
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());"?
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....)
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.
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'
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.
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....
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:
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?
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....
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.
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.
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()".)
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();
Comments
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.
An example of the problem... maybe if I use a script to clear the cache?
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. :(
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....
I can't figure out where to put this refresh (assuming I'm doing it correctly). The line I'm trying to add is:
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.
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:
(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.
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:
Now in the log I get:
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. :(
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:
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.
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.
I meant "riEndWorld" sorry. You also still need to call that refresh on the property map you were doing before.
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());"?
I did it this way, right before the Beauty Pass riWorldBegin():
I still don't get the right outline image, but I'm no longer getting errors about a missing prepared image....
(Is there anything I can do about the Min and Max errors? I'm not using those variables in my very simple camera shader....)
Using your code it should probably be the following:
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.
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.
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.
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.
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....
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.
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:
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?
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:
The list of available scripts works after this is run, but I still can't figure out how to set it....
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.
What do you mean by widget?
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.
A DzProperty derivative has a getLabel() function and a name member - both strings.
Ok, I'll see if I can iterate through the children of the parent property and find it that way-- thanks for the reminder.
DzProperties don't have children, so I'm wondering if we are talking about different things.
Probably not. I have a terrible time knowing what to call things in this scripting language.
I have set these variables:
and then I want to use them here:
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()".)
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 );
}
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: