PDA

View Full Version : Render "preframe" and "post frame" option?



lordtangent
09-15-2008, 06:59 PM
I skimmed thought the script docs and looked though LW and I can't figure out how to trigger an lscript for each frame at render time. For what I want to do it has to be Screamer Net compatible also.

One more question: Is it possible to completely disable objects via lscript similar to the check box in Scene Editor? Lscript commander doesn't record it so I'm having a hard time figuring out what function would do that.

Thanks for any help!

faulknermano
09-16-2008, 12:03 AM
how to trigger an lscript for each frame at render time.

this can be quite tricky to do, especially since you mentioned that you need it to be LWSN-compatible. as far as i know you can use the event of RENDER_DONE (using master-class lscript) to know when a render has just finished. however, master-class lscripts have a reputation for crashing LWSN. depending on the functionality you want you may be able to get it to work in other ways. what exactly are you looking to accomplish?


is it possible to completely disable objects via lscript


ItemActive(0);



Lscript commander doesn't record it

if you do execute the Save Command List command in Layout you will get a list of commands that you can execute as a Command Sequence. have a look at the docs (release notes) for more info.

lordtangent
09-16-2008, 02:24 AM
What I want to do is run the gather cache and then disable all the lights. The goal is to get a gather only render pass. (No direct light. Only the results of the gather) I've tested the idea interactively and it works.

So now the trick is to automate things for a full sequence render so that it: resets the cache, (perhaps renames the cache with a frame number?), regenerates the cache, turns off the lights, renders, then turns back on the lights.

ItemActive(0); would work to disable the lights long enough to do the gather only pass.

I'm thinking I might also be able to use the pre-process buffer to get this out. But I haven't tested the idea yet. Plus I liked the idea of being able to do a full per-frame cache generating render pass. It's not exactly how the cache is meant to be used but I've done a similar trick in mentalray (being driven by Maya) and it worked pretty well.

faulknermano
09-16-2008, 02:52 AM
it's a neat idea (i've been mulling about a radiosity pass for janus for some time now). however, if i understand you correctly, i do not think it will be possible to make that work with LWSN. at least with lscript - there's no way to call any kind of command from within LWSN that is not part of a handler (e.g. channelfilter, motion modifiers, etc).

i believe the major problem is resetting the cache, which is just probably just renaming the file (as you already said). but since it is not tied to a handler or cannot be hooked to an expression, you cant change it once it has been loaded into LWSN.

unless somebody else comes up with a better idea, my only thought is a crude one: generate a single lws for every frame you wish to cache and load them all up in LWSN.

btw, what exactly are you referring to when you say 'pre-process buffer'?

Blochi
09-16-2008, 08:19 AM
I'd like to add that in the current version of LW your LScript doesn't have a way of knowing the current ItemActive state. And calling ItemActive(0) is a toggle, actually. Means, a light that has been disabled, will get enabled by this command.

If you want something to happen BEFORE render, you might be lucky with a Motion Script. Not sure how much access you get in a Motion Script, but you should be able to rename a file... Just make sure to set some flags, because these motion plugins are executed in every motion blur pass....

Blochi

faulknermano
09-16-2008, 08:35 AM
Not sure how much access you get in a Motion Script, but you should be able to rename a file

or possibly after the render using a imagefilter? hmmm... either way the timing must be examined, though, whether or not the cache file in question exists when the imagefilter / motion modifieres are called. of course, thinking about it, if this was submitted over the the farm you'd have to account for two or more nodes finishing the same cache at the same time.

Blochi
09-16-2008, 10:00 AM
Good point, actually.

Especially when this hack is based upon deleting the cachefile first, you might end up with a node war over cachefiles.... Just for kicks, you should also make them beeep or play a siren sound!

lordtangent
09-16-2008, 10:44 AM
I noticed in the docs that for LWSN the disk based cache is read only anyway. (it can still cache to memory though) So there is probably no danger of a race condition on the cache from multiple render nodes.

But the goal is still to get that cache generated and make the gather only pass.

I have another idea how to do it using a more complex scene. But the cache hack is really so simple. If it's do-able it would be my first approach.

as for the "pre-process buffer" I noticed it in one of the DP kit nodes. I haven't had time to play with it and see what it actually is.

lordtangent
09-21-2008, 10:54 PM
Well, I struggled today writing a prototype lscript to test my idea and had very little luck getting the automation working 100% correctly.

I'm uploading an attachment of one of my gather only renders so everyone can see that the idea actually works. I'm just trying to automate things.

Since I realized that I could not have LWSN actually WRITE to the cache, I figured there was no reason to try and make the BAKNING part LWSN compatible. But no matter what that means I would still need to pre-render the cache in LW. So I focused on working to automate that part of things in LW. I used a Custom Object type lscript, since it was the easiest considering it can fire off code when the frame changes.

I used my prototype script to semi-automatically generate some frames of uniquely named radiosity caches. Then I turned off the lights in the scene and did an F10 render.

My script tried to change the name of the cache for each frame, and the command history showed that it was firing off as LW advanced each frame. But LW didn't properly re-load the cache each frame and just kept rendering with the shame cache. (my test scene had object animation in it so I could spot problems easier. The problem was easy to spot)

So, now I'm thinking the only way to do this would be to actually re-start the render each frame (so that it reloads the cache correctly) or use LWSN -3 and have it reload the scene each frame, forcing it to also re-load the cache.

For baking I has a similar problem. I needed to bake the frames individually. (even though my script properly changed the cache name)

I'm thinking to make this work I would need to basically take over the LW scene render function and "bake scene" functions with lscripts. It's probably doable but a major hassle and right now a little outside my lscipting ability. Enough of a "sleep" or wait needs to be built-in so that LW has a chance to re-load the cache. It seems that in all it's built-in batch modes it blasts though things too fast or never even checks the cache name path again.

Here is what I got so far if anyone else wants to pick it up. No gui or anything yet. I just hard coded the cache path in there for testing. And for BAKING the cache I commented the last couple of lines and used the frame advance buttons in LW. I didn't attempt to script that since I couldn't figure out what class of script to use in LW that could do a for loop that advanced LW automatically for me. When I tried to use "Bake Radiosity Scene"


//-----------------------------------------
// Cacher... Changes radiosity cache name each frame
//
// Version 0.1

@version 2.3
@warnings
@script custom

// global values go here

fileName = "D:\\LW_Content\\RadiosityCache\\TeaPotFastAO\\TeaP otFastAO_";

newtime: frame, time
{
// called each time the current time index changes in the scene

currentFrame = frame;
currentTime = time;
cacheNameCommand = "RadiosityCacheFilePath " + fileName + currentFrame.asStr(4,true) + ".cache";

CommandInput( cacheNameCommand );
// sleep(500);
// CommandInput( "BakeRadiosityFrame" );
}

lordtangent
09-21-2008, 10:56 PM
as for the "pre-process buffer" I noticed it in one of the DP kit nodes. I haven't had time to play with it and see what it actually is.

Played with the nodes and aside from a lot of crashes I have no progress to report. I still have no idea at all what the "Pre-Effect" buffer is.

lordtangent
09-22-2008, 12:27 AM
else comes up with a better idea, my only thought is a crude one: generate a single lws for every frame you wish to cache and load them all up in LWSN.


Having a separate scene for every frame is pretty much how ever other high-end renderer on the market works anyway. I don't consider that TOO much of a hack and I would be perfectly comfortable doing that. The main trick would still be automating the cache generation on a local machine and the automated creation of all those scenes (and then maybe also how to submit to a render farm that is used to getting LW scenes as a single scene rather than a scene per-frame)

I'm not sure if the script I posed above works on LWSN. (I realize, Custom Objects aren't really applicable in LWSN...) The script could probably be made as an object replace instead, which would work similarly.

faulknermano
09-22-2008, 12:38 AM
i've modified your code and transplanted it as a master-class lscript. like you, i was unable to get an F10 render to properly switch the cache file to be conjunction with the render, it seems that LW itself does not want to write the cache file out. so this code is the brute-force BakeRadiosityFrame method, using the event RENDER_DONE to signal the advance to the next frame.

some notes: the st_abort is a special variable type, which is 'static', which means it remembers its value within the function it resides in. a variable is made 'static' by prefixing it with st_.

to use: just select this script from the popup menu. it will go from 1-20. unload it after finishing.


@warnings 0
@script master
currentFrame;startFrame;endFrame;
fileName = "D:\\PROJECTS\\TeaPotFastAO_";
create
{
currentFrame = 0;
fileName = "D:\\PROJECTS\\TeaPotFastAO_";
startFrame = 1;
endFrame = 20;
cacheNameCommand = "RadiosityCacheFilePath " + fileName + currentFrame.asStr(4,true) + ".cache";
CommandInput(cacheNameCommand);
RenderNext();
}
process: event, command
{
if(event == RENDER_DONE)
{
cacheNameCommand = "RadiosityCacheFilePath " + fileName + currentFrame.asStr(4,true) + ".cache";
CommandInput(cacheNameCommand);
if(st_abort == nil)
st_abort = RenderNext();


}
}

RenderNext
{
currentFrame++;
if(currentFrame > endFrame)
return(true);
GoToFrame(currentFrame);
CommandInput( "BakeRadiosityFrame" );
return(nil);

}

faulknermano
09-22-2008, 12:41 AM
I'm not sure if the script I posed above works on LWSN.


i guarantee you it will not. ;) i can also guarantee that the script i posted up will also not work because both scripts call commands which LWSN does not support. quite unfortunate though.

lordtangent
09-22-2008, 02:39 AM
Cool. Thanks faulknermano! This gives me a lot of ideas to work with. Now all I need to do is write a little interface code to ask for a bake start / stop and cache name.

I re-created my original script as an object-replace script. It has a little interface code to set up the path and store the path properly in the scene file. I haven't tested it with LWSN yet but the idea is to be able to use it in LWSN -3 mode. I figure if the chunk size is only one frame it should work ok? I'm not adverse to the idea of writing out millions of scene files as a last resort. But if there is a cleaner solution I'd like to do that first.



///-----------------------------------------
// CacheReplacer... Changes radiosity cache name each frame
//
// Version 0.2

@version 2.3
@warnings
@script replace
@name CacheReplacer
cachePath = "";
prog = "CacheReplacer v 0.2";

create
{
setdesc(prog);
}

process: ra
{
currentFrame = ra.newFrame;
cacheNameCommand = "RadiosityCacheFilePath " + cachePath + currentFrame.asStr(4,true) + ".cache";
CommandInput( cacheNameCommand );
}
load: what,io
{
if(what == SCENEMODE)
{
cachePath = io.read();
}
setdesc(prog);
}
save: what,io
{
if(what == SCENEMODE)
{
io.writeln(cachePath);
}
}
options
{
reqbegin(prog);
c1 = ctlfilename("Cache Name",cachePath,40,true);
return if !reqpost();
cachePath = getvalue(c1);
reqend();
}


I also wrote improved the Custom Object version, and while it wont work with LWSN as you state, it does seem to work better for interactive stuff ... scrubbing the time bar, F9 renders, etc. It has an optional "bake" feature which is a remnant of my earlier testing. I'm posting it in case it's useful for anyone who wants to test this stuff in LW. (Not LWSN)



@version 2.3
@warnings
@script custom
@name CacheNamer
prog = "CacheNamer v 0.2";
cachePath = "";
bakeYes = 1;


newtime: frame, time
{
// called each time the current time index changes in the scene

currentFrame = frame;
cacheNameCommand = "RadiosityCacheFilePath " + cachePath + currentFrame.asStr(4,true) + ".cache";
CommandInput( cacheNameCommand );

if( bakeYes == 2 )
{
sleep(200);
CommandInput( "BakeRadiosityFrame" );
}
}
load: what,io
{
if(what == SCENEMODE)
{
cachePath = io.read();
bakeYes = io.read();
}
setdesc(prog);
}
save: what,io
{
if(what == SCENEMODE)
{
io.writeln(cachePath);
io.writeln(bakeYes);
}
}
options
{
reqbegin(prog);
c1 = ctlfilename("Cache Name",cachePath,40,true);
// c2 = ctlchoice("Bake Cache",bakeYes,@"No","Yes"@);
c2 = ctlpopup("Bake Cache",bakeYes,@"No","Yes"@);

return if !reqpost();
cachePath = getvalue(c1);
bakeYes = getvalue(c2);
reqend();
}

faulknermano
09-22-2008, 02:48 AM
I haven't tested it with LWSN yet but the idea is to be able to use it in LWSN -3 mode. I figure if the chunk size is only one frame it should work ok?

(not quite sure what you mean by 'chunk size')

you may get lucky and find out that LWSN has actually changed in 9.5. but as far as i have been able to test it (9.3.1) the attempt to execute CommandInput() in a ScreamerNet situation fails because LWSN cannot handle it.

lordtangent
09-22-2008, 03:15 AM
Chunk size means how many frames per "chunk" or render job.

For example, with LWSN -3 you can set <first frame> <last frame> <frame step>

meaning you could have it render an entire scene (a big chunk), or just one frame (the smallest chunk)

Of course, a similar concept holds for a lot of render Queues as well. You can have a machine do a bunch frames instead of just one if it makes sense. I always though "chunk size" was a generic name for it. The phrase has been used at so many places I've worked I assumed everyone used it.

Well, if CommandInput() is no good in ScreamerNet I guess I will just have to write out a bunch of scene files with RadiosityCacheFilePath hard coded. It would not be too hard to just write out a batch script at the same time to render them all with ScreamerNet.