Sunday, 21 April 2013

3d: Render higher resolution images with "Render_autosave", using VRay or mental ray



Hi All,

While today’s fast computers may ensure rendering crashes are less and less frequent, there are still instances when processing high resolution photorealistic renders will cause computers to freeze and ultimately crash!

I have certainly experienced in numerous occasions having renders freeze and crash when there were only few “render buckets” left to complete the entire image!

Such inconveniences may cause major setbacks with the final deadline and user’s workflow, especially when the renders are taking a considerable amount of time to process.

For example, the above panoramic image was rendered at 22.000 x 11.000 pixels,while at GMJ design ltd. As one can imagine, it was a huge challenge to create and render the above image due to its unusual output pixel size, and the manner in which it was captured (panoramic).

And yes, it crashed several times while the render was being processed!!
We had decided to render the space in a panoramic style to save the client time and money by NOT having to create and render countless camera angles to capture the entire proposed space.
The end product was a full panoramic image rasterized as a JPEG, which the client was then able to view and navigate through, by using a free software called “ iMove Viewer” .  

Very recently, a prolific script writer/ Senior Visualiser and Photographer called  David Venables has created an ingenious and simple script that allows users to set 3Ds max to automatically save the render periodically while still being processed in the frame buffer.

Users can also set the location and the frequency of the renders being saved.

Below is the simple script created by David Venables:


(

                Global AutosaveImg

               

                fn dntTick =

                (

                                Local Autosavedir = (getdir #autoback) + "\\" + "Rend_autosave.tif"

                                TIF.setType #color16

                                TIF.setAlpha #true

                                ::AutosaveImg = getLastRenderedImage copy:off

                                AutosaveImg.gamma = 2.2

                                AutosaveImg.filename = Autosavedir

                                Save AutosaveImg

                )


                Global dnetTimer = dotnetobject "system.timers.timer" (2*60*1000)

                dotnet.addEventHandler dnetTimer "Elapsed" dntTick


                callbacks.removeScripts id:#RenderAutoSave

                callbacks.addScript #preRender "dnetTimer.start()" id:#RenderAutoSave

                callbacks.addScript #postRender "dnetTimer.stop()" id:#RenderAutoSave

)





To save this script, simply open 3Ds Max, followed by clicking on the MAXScript button from the main toolbar, and choosing the MAXScript Editor option from the dropdown list.





Its dialog should open. Next, copy and paste the above mentioned script onto the dialog’s text field.   

By default, the script automatically finds the autosave path with the (getdir #autoback) string of code; and saves the file under the name of  "Rend_autosave.tif"  as a TIF file format.  




This can be changed manually. For instance, the default path could be saved in the following location: C:\Users\Public\Pictures

The relevant line of code would be replaced with the following: “Local Autosavedir = C:\\Users\\Public\\Pictures + "Rend_autosave.tif" .




In addition, the script automatically sets the saving frequency to every 2 minutes: (2*60*1000).




This default timer can also be changed by simply typing in a different number you may find more adequate (i.e. replace nr 2)!

Once satisfied with everything, simply save the script by pressing Ctrl+S.

The Save file dialog should appear. In order for this script to automatically start as a callback everytime 3Ds Max is lauched, it must be saved as an ms file in the following location:
C:\Program Files\Autodesk\3ds Max 2012\Scripts\Startup.   




Note: If using a different version of Max, simply save the script in the adequate 3ds Max folder (i.e. 3ds Max 2013; etc). 

Next, close and restart 3Ds Max. Render anything that would take longer than 2 minutes to test whether the script works or Not.

Finally, go to the designated folder/location to see the saved image/file; or simply type in the following in the bottom left part of 3ds Max: display (getLastRenderedImage()) ; followed by pressing Enter.
The OK text in blue should appear below, along with the last saved render in the frame buffer.  







The beauty of this script is that it will give the user the reassurance/peace of mind that when/if the render crashes it will be saved. This will also enable the user to continue from where the render was last saved; as opposed to starting from scratch again! 

Currently the script works mainly with the 3Ds Max frame buffer, regardless of the rendering engine being deployed.

The panoramic image below was rendered using the Render_autosave script!

If there are any specific features you would like to see implemented in this script, please contact David Venables through his LinkedIn page HERE or via email HERE.

I hope you have found this article useful!!

Ta




.

15 comments:

  1. Excellent! I would love to see a tutorial about panoramic images!

    ReplyDelete
  2. Hi Banko,

    Thank you very much for your feedback here. It's much appreciated!!
    Yes, I will definitely consider a tutorial on creating a panoramic render for Vray and mental ray.

    Thanks again!!

    J

    ReplyDelete
  3. Excuse me if I missed the part on resuming the render, but how is that done?

    ReplyDelete
  4. Hi Tom,

    Thank you very much for your feedback here!

    I don't suppose one is likely to be able resume the frame buffer render if/when it crashes?!
    However, users can safely retrieve any of the renders periodically saved automatically, from any location/folder set by the user...as explained earlier!

    I hope this answers your query!

    Ta

    ReplyDelete
  5. Hi Tom,

    I have just read your query again..and think I now understand what you meant: One would have had to restart Max and region render what's left to render.

    In fact, David Venables is actually trying to work out on a way to have the script to automatically restart Max and continue the render as region from where in the from buffer it was last saved.

    Finally, please feel free to make any sensible :0) requests you may find useful to implement in this script!

    Ta

    ReplyDelete
  6. Great idea

    I change some code here for my personal use I want to share with you because learn many thing from you every time checked this website ! thanks my man

    newfeatures
    1: Save bitmap that include (max file name + max current viewport ) in name
    2: adding ability for using vray frame buffer if you want I can add it to a macro to control every thing from an UI



    (

    Global AutosaveImg



    Fn imagefile =
    (
    if viewport.gettype() == #view_Camera then --check the user view for addinf the camera name(if exsit to filename else type UserView)
    (
    cname = viewport.getcamera()

    camname =cname.name
    )
    else
    (
    camname = "UserView"
    )

    Filepath = (getfilenamepath maxfilepath ) --Get Current file path

    makedir (Filepath + "\\R_Autosave2\\") -- Make Directory in filepath , rename R_Autosave if you want!

    mfilepath = (filepath + "\\R_Autosave2\\")

    fname = (mfilepath + getfilenamefile maxfilename ) --adding max file name before render name

    (Fname+"_" + (camname) + "_R_Autosave.tif") -- final file name
    )


    fn dntTick =

    (



    Local Autosavedir = mfilepath

    TIF.setType #color16

    TIF.setAlpha #true

    ::AutosaveImg = getLastRenderedImage copy:off -- for use max fame buffer

    --::AutosaveImg = vrayVFBGetChannelBitmap 1 copy:off --for using vray frame buffer you can also add an array for this to save all channel!!!

    AutosaveImg.gamma = 2.2

    AutosaveImg.filename = imagefile()

    Save AutosaveImg

    )


    Global dnetTimer = dotnetobject "system.timers.timer" (2*60*1000)

    dotnet.addEventHandler dnetTimer "Elapsed" dntTick


    callbacks.removeScripts id:#RenderAutoSave

    callbacks.addScript #preRender "dnetTimer.start()" id:#RenderAutoSave

    callbacks.addScript #postRender "dnetTimer.stop()" id:#RenderAutoSave
    )


    ReplyDelete
  7. Hi Amir,

    Thank you sooooo much for your great input here!!!

    It seems that, now it even works with Vray frame buffer and takes camera names into consideration when saving: the TIF name: Wow !!! :0)

    I have just had a look at it and ran it pass David Venables!

    David just added few tweaks "here and there" in addition to the great work you have already done!!

    The following is what it looks like now:



    (

    Global AutosaveImg



    Fn imagefile =
    (
    if viewport.gettype() == #view_Camera then --check the user view for addinf the camera name(if exsit to filename else type UserView)
    (
    cname = viewport.getcamera()

    camname =cname.name
    )
    else
    (
    camname = "UserView"
    )

    Filepath = (getfilenamepath maxfilepath ) --Get Current file path

    makedir (Filepath + "\\R_Autosave2\\") -- Make Directory in filepath , rename R_Autosave if you want!

    mfilepath = (filepath + "\\R_Autosave2\\")

    fname = (mfilepath + getfilenamefile maxfilename ) --adding max file name before render name

    (Fname+"_" + (camname) + "_R_Autosave.tif") -- final file name
    )


    fn dntTick =

    (



    Local Autosavedir = mfilepath

    TIF.setType #color16

    TIF.setAlpha #true

    if matchpattern (renderers.current as string) pattern:"v_ray*" == true or matchpattern (renderers.current as string) pattern:"vray*" == true then
    (
    ::AutosaveImg = vrayVFBGetChannelBitmap 1 copy:off --for using vray frame buffer you can also add an array for this to save all channel!!!
    )
    else
    (
    ::AutosaveImg = getLastRenderedImage copy:off -- for use max fame buffer
    )



    AutosaveImg.gamma = 2.2

    AutosaveImg.filename = imagefile()

    Save AutosaveImg

    )


    Global dnetTimer = dotnetobject "system.timers.timer" (2*60*1000)

    dotnet.addEventHandler dnetTimer "Elapsed" dntTick


    callbacks.removeScripts id:#RenderAutoSave

    callbacks.addScript #preRender "dnetTimer.start()" id:#RenderAutoSave

    callbacks.addScript #postRender "dnetTimer.stop()" id:#RenderAutoSave
    )

    ReplyDelete
    Replies
    1. thanks Jamie and David !!!
      Again I learned here :)

      so lets completely fix that :

      if matchpattern (renderers.current as string) pattern:"v_ray*" == true or matchpattern (renderers.current as string) pattern:"vray*" == true then
      (
      Renderers.current.output_on=true--enabel vrayframe buffer
      ::AutosaveImg = vrayVFBGetChannelBitmap 1 copy:off --for using vray frame buffer you can also add an array for this to save all channel!!!
      )
      else
      (
      ::AutosaveImg = getLastRenderedImage copy:off -- for use max frame buffer
      )

      For next step lets add ability to resume render if crashed last time!
      I think the idea must be as simple as
      1: check the Max file folder for last tif saved
      2: get the bucket size from Renderer
      3: slice the image to bucket size pieces then resize them to one pixel and get the mid color of that pixel if BLACK then continue from there :) (the main problem here is that we must use top-bottom or left- right in sequence method )

      what do you think?

      Delete
    2. Hi Amir,

      Thank you very much for your continuous input here!!!

      Your ideas are great indeed...and we are looking into this closely!!!!

      Thank again Amir!!!

      Ta

      Delete
  8. It's a nice idea.... however I think it's likely to crash your render just as much as save it. If a render crashes it's normally because it runs out of RAM more than a software failure, Vray especially rarely crashes max completely.

    Using this script you're creating a new image object to save your render which is going to eat into RAM especially with a large render, and there's no Garbage collection so you might be incrementally eating ram (I'd need to check this).

    Otherwise there are many ways to render large images, strip rendering with Backburner, or Tile Rendering with Deadline which you can use for free with 2 workstations, and thus even with one machine you can set up your own local render farm and render huge images in tiles and not risk running out of RAM and crashing your render and if it does randomly crash the rendering system will automatically attempt it again.

    I've rendered images of 60,000 pixels before and push the memory limit of max to the limit on a daily basis, Tile rendering is the way forward.

    ReplyDelete
  9. Hi Dave,

    Your input here is much appreciated!!!!

    You have some valid points. However, auto-saving the renders in the frame buffer periodically NOt only will give you that much needed piece of mind, but also help the user determine where in the frame buffer the "crash" took place.
    Yes, one can use strip render, tile render, etc...But it still doesn't mean the render will not crash due to lack of Ram, server failure, a rogue object in the scene, etc!
    I too use Vray extensively...and I tell you: It crashed several times for all the above mentioned...and other reasons.

    In fact, very recently this script helped patched up a big shot...when the deadline was due the following morning: literally the render crashed when there were only eight buckets left to complete the full frame.
    The auto-saved frame buffer also helped me pin poit that, the problem was a rougue object that I had merged in my scene!

    Perhaps the way forward is to use this script with backburner for strip renders or tile rendering?!

    Again, thank you very much for your input here David!

    Ta

    ReplyDelete
  10. this function is already on vray frame buffer, just UNCKED RENDER TO MEMORY FRAME BUFFER option, and enable "RENDER TO VRAY RAW IMAGE FILE", this way, every image cluster will be saved directly to your VRIMG file, and if your pc crashes while rendering, you will be able to use the VIEW IMAGE FILE menu and open the image containing last rendered clusters. Recomend to use the AUTOSAVE LIGHTCACHE and IRRADICANCE MAPS options, as well render from TOP to BUTTON.

    ReplyDelete
  11. Hi Benjamin,

    Thank you very much for your great input here!!!
    I have used this feature before,but not to the extent you have described earlier!!!
    I will definitely look into this later on!

    Thanks again Benjamin!

    Ta

    ReplyDelete
  12. _O)(..

    Feel happy to c u guys busy to implementation over Max render crash, Good job Keep it up :)

    ReplyDelete
  13. hi all, may i know every time i open 3ds max it appears a dialog box stating script load error?

    ReplyDelete