Rendering animation speedups - LOD, etc.


(LukeW) #1

Hi,
I’m looking for scripts that can speed up the rendering process since it means that I would be able to have more complex scenes in my animations…

An example script is like this level of detail (LOD) one:
http://ftp.stenstad.net/mirrors/ftp.blender.nl/demos/demo212.zip

Here’s the script the LOD example contains:

import GameLogic
cont = GameLogic.getCurrentController()
sensorlist = cont.getSensors()
#print len(sensorlist)
camera = cont.getOwner()
position = camera.getPosition()
#print position
actuatorlist = cont.getActuators()
#print len(actuatorlist)

for act in actuatorlist:
  sphereobj = act.getOwner()
  spherePos = sphereobj.getPosition()
  dx = spherePos[0] - position[0]
  dy = spherePos[1] - position[1]
  dz = spherePos[2] - position[2]
  distanceSq = (dx*dx)+(dy*dy)+dz*dz)

  if (distanceSq < 50):
    act.setMesh("Sphere.005")
  else:
    act.setMesh("Sphere")

GameLogic.addActiveActuator(act,1)

I know how to program in lots of different languages but I haven’t tried to learn python scripts yet.

This code looks pretty straight-forward to me… I guess #print isn’t really necessary - it could just be for debugging-type purposes. I typed out that code manually - I couldn’t figure out how to copy and paste it or save it as a file. So there might be typos. There were a few different levels of detail and sphere meshes in the actual code but I simplified it to reduce typing.

Anyway, I don’t want to use any of Blender’s game features - I just want to render animations. So I guess many parts of that code like “GameLogic” shouldn’t be in there.

I was wondering how to make some code that is “called” with each frame of an animation… it would also be called for each subframe for motion-blurring, and fields rendering, etc.

Basically I want to make scenes that have lots of trees, etc, that are detailed up close while not taking long to render when in the distance (due to LOD).

BTW, I’ve tried rendering that demo but the objects show up in their original form - as cylinders… though when in game mode, the LOD works properly.


(theeth) #2

To make a script run each time the frame change, you have to do to the Script buttons window (next to the Display buttons window)
Press new (the one at the right side of the screen if you hae more than one)
Type the name of the script in the field that just appeared
You will nottice that the button next to the text field reads “FrameChange” which determines when the script is called.

For a LOD script that when when rendering, you could try something like this:


import Blender

ObjectList = ["Tree.002", "Tree.001", "Tree"]
DistanceList = [150, 100, 50]
InvisibleLayer = 10
VisibleLayer = 1

ob = Blender.Object.Get("Empty")
cam = Blender.Object.Get("Camera")

dx = ob.matrix[3][0] - cam.matrix[3][0]
dy = ob.matrix[3][1] - cam.matrix[3][1]
dz = ob.matrix[3][2] - cam.matrix[3][2]

dist = (dx*dx)+(dy*dy)+(dz*dz)

for obName in ObjectList:
        Blender.Object.Get(obName).Layer = 1 << (InvisibleLayer - 1)

for Index in range(3):
        if dist > DistanceList[Index]:
                Blender.Object.Get(ObjectList[Index]).Layer = 1 << (VisibleLayer - 1)
                break

ObjectList is the list of the names of the object with the LOD, in reverse order, from the least detailed to the most
DistanceList is the minimum distance that correspond to each LOD object
“Empty” is the name of the object to which all the LOD object are parented
“Camera” is the name of the camera
VisibleLayer is the layer where the object will go when visible
InvisibleLayer is the layer where objects will go when invisible

I hope that’s clear.

Martin
PS: that code wasn’t tested, but it should work.


(SHABA1) #3

Luke.

I do not know how you did it but whenever I try to run on of these blend files I just get the game/animation. I would acutually like one of thise to open up in blender so that I can study the meshes and setting e.t.c

How do you do that ?


(theeth) #4

SHABA1: open up Blender and then open the blend file from there.
If you open the blend file from the command line (or by double clicking on it, it’s the same difference), the games will automaticly starts when they have autostart on.

Martin


(SHABA1) #5

Thanks teeth.

Autostart
Nice feature.
I suppose that when you make a runtime with publisher this also works.?

and where do you set “autostart”?


(theeth) #6

Autostart is located in the Game menu at the top of the screen

runtime files always starts when you open them

Martin


(LukeW) #7

Hi theeth,
Thanks for that code…
I can’t get it to work properly though… basically the third object “tree.002” always moves to layer number 1 and the rest of the “tree” objects always move to layer 10. This also happens when I reload the file. None of the objects I parented to the Empty change in the view or when rendered no matter how far or close I move them from the camera. What I was expecting was for the objects that are parented to the empty to change meshes depending on their distance from the camera…
Here is my blend file:
http://members.ozemail.com.au/~wenke/blender/lod.blend
Maybe I got the naming of the “trees” and parenting objects to empties mixed up…


(theeth) #8

It works, the problem was that it didn’t work like you expected.

The Empty is where the Objects are suppose to be located, so for each different object, you’d need to have an empty and the different mesh parented to it. Also, another thing is that the distance in DistanceList are squared distance, so you have to put higher number than that to really see a difference.
Other than that, the script works correctly, so if you animate the camera moving towards or away from the Empty, you’ll see that the different meshes switch layers back and forth when needed.

I hope that’s more clear.

Martin


(LukeW) #9

theeth:

…The Empty is where the Objects are suppose to be located, so for each different object, you’d need to have an empty and the different mesh parented to it.

It seems that it parenting an object to the Empty has no effect at all. I’ve tried parenting only one of the plane/cylinder objects and moving it near the Empty, where the Camera is looking, and I’ve also tried parenting all the “Tree” objects to the Empty - it has no effect… the “Tree” objects change still, but they remain in their old position…

Also, another thing is that the distance in DistanceList are squared distance, so you have to put higher number than that to really see a difference.

Yes, I’ve seen them change and I realized the distance meant the distance squared. And you only had the cases where the object is >50, >100 and >150… you didn’t include the case where the distance squared <=50… so if the camera is to close to Empty, no mesh appears there.

Other than that, the script works correctly, so if you animate the camera moving towards or away from the Empty, you’ll see that the different meshes switch layers back and forth when needed.

Yes, but the different meshes don’t go to the position of where the Empty is…

I was looking for a script that worked like that example script I gave… in that example, there were many cylinders, and for each one of them, it calculated the distance squared and put an appropriate mesh in place of the cylinder… so there are in fact about a dozen cylinders and the LOD objects are reused many times - rather than just having one Empty and one distance calculation - some of the cylinders would be closer to the camera and some would be further away and so they’d use different LOD meshes…

I can just about code in the changes… it looks like Empty.getChildren() may be able to be use to get the list of Children that are parented to an object…

BTW, is there a way to copy and paste or save text that is in Blender to the Windows clipboard…? Thanks.


(LukeW) #10

theeth:

http://members.ozemail.com.au/~wenke/blender/lod19.blend

import Blender
import Blender210

tree1 = Blender210.getMesh("Tree")
tree2 = Blender210.getMesh("Tree.001")
tree3 = Blender210.getMesh("Tree.002")

cam = Blender.Object.Get("Camera")

objectList = ["Cylinder", "Plane", "Empty", 
"Empty.001", "Empty.002", "Empty.003",
"Empty.004", "Empty.005"]

for obName in objectList:
  ob2 = Blender210.getObject(obName)

  dx = ob2.LocX - cam.LocX
  dy = ob2.LocY - cam.LocY
  dy = ob2.LocZ - cam.LocZ
  distSq = (dx*dx)+(dy*dy)+(dz*dz)

  if distSq &lt; 200:
    Blender210.connect(ob2, tree1)

  elif distSq &lt; 500:
    Blender210.connect(ob2, tree2)

  else:
    Blender210.connect(ob2, tree3)

Now I’ve got 8 objects that switch between 3 different LOD meshes depending on their distance from the camera. I had to manually type in the names of the 8 objects though…

Is there a way of parenting the objects to an empty then accessing a list of the empty’s children?

I can’t get “getChildren()” to work. I used the Blender210 module… I couldn’t figure out how to do it any other way. My eventual goal would be to have hundreds of trees and it would be good if I could avoid typing in their names.


(theeth) #11

BTW, is there a way to copy and paste or save text that is in Blender to the Windows clipboard…?

not that I know of

for the rest, I don’t know the blender210 api too well, so I can’t really help you there.

Martin