Welcome

This blog represents a common area where we can share ideas, thoughts and other verbose information with others - While giving a little more insight into the inner workings/minds of our team.

Though there might be overlap in places, the content here differs from that of the main Aqsis website and is intended to be complimentary while still acting as a useful resource for those interested in the world of 3D graphics and rendering.

So... sit back, relax, and have fun... we will !!! ;-)

Friday, 30 October 2009

Moving on from Io

After the excitement of my last post I've had to abandon Io as my language of choice. While it has a beautifully succinct syntax, it proved to be a bit slow for my plans.

I spent some time looking for alternatives that could provide the same, or similar, level of flexibility and control, without the speed implications. My research led me eventually to Lua. I'd already looked at Lua some time ago, in fact I've already written a Lua binding once in the past (but forgot to back it up, so couldn't find it this time round).

I've spent some time working on it this time before posting, so much that I have a workable animation framework well and truly underway. There is a lot of 'legwork' to get all the necessary features in, but each part of the framework has be at least partially tested and proven, and what's more Lua is proving to be incredibly fast.

The framework I'm working on bears not a passing resemblance to Steve May's AL, intentionally, as this has been a goal of mine almost as long as I've been working on Aqsis. I was drawn to AL at around the same time as I was drawn to RenderMan, but the RenderMan side took precedence.

As it stands, the framework is able to run relatively simple scripts to produce RIB (and OpenGL to a degree) animation output. Much like AL, the system has a number of key technologies/advantages that make it more usable than a naive RenderMan binding.


  1. Support for time dependent variables called avars. These look like any other variable when used in the script, except their value changes depending on the current time. This is the key concept to animation in the framework, by using these avars judiciously in the scene script, animation happens automatically.

  2. Automatic motion blur. There is no need in the scene script to specify anything related to motion blur, unlike in a naive binding. The framework automatically determines which parts of the scene are changing over time, validates that this change is within the constraints of RenderMan, i.e. it's not legal to have the number of points in a mesh change over time, and wraps the relevant parts in motion blocks.



As a quick example, here is a simple script that produces a procedural animation of a "scissor mechanism". The key points to note, over a traditional animation system, are how easy it is to adjust any part of the model, from the number of segments, to the width and thickness of the parts. Simply changing numbers results in the whole thing being recalculated next update.


function createBlade(length, width, thickness)
blade = Model("blade")
function blade:body(time)
local left = - width / 2
local right = width / 2
local top = - thickness / 2
local bottom = thickness / 2
TransformBegin()
Translate(0, 0, -length/2)
TransformBegin()
Rotate(90, 1, 0, 0)
Rotate(180, 0, 0, 1)
Cylinder(width/2, top, bottom, 180)
Disk(top, width/2, 180)
Disk(bottom, width/2, 180)
TransformEnd()
Polygon({ P = {left, top, 0, left, top, length, right, top, length, right, top, 0}})
Polygon({ P = {right, top, 0, right, top, length, right, bottom, length, right, bottom, 0}})
Polygon({ P = {right, bottom, 0, right, bottom, length, left, bottom, length, left, bottom, 0}})
Polygon({ P = {left, bottom, 0, left, bottom, length, left, top, length, left, top, 0}})
TransformBegin()
Translate(0,0,length)
Rotate(90, 1, 0, 0)
Cylinder(width/2, top, bottom, 180)
Disk(top, width/2, 180)
Disk(bottom, width/2, 180)
TransformEnd()
TransformEnd()
end
return blade
end

scissor = Model("scissor")
scissor.extension = scissor:avar("extension", {{0.0, 0.0}, {30.0, 1.0}})
scissor.segments = 5
scissor.bladelength = 2
scissor.bladewidth = 0.3
scissor.bladethickness = 0.1

function scissor:body(time)
local minangle = (self.bladewidth / self.bladelength) * (180/math.pi)
local maxangle = 90 - minangle
local blade = createBlade(self.bladelength, self.bladewidth, self.bladethickness)
for segment = 0, self.segments do
local angle = 90 - math.min(math.max((90 * self.extension(time)), minangle), maxangle)
local offset = self.bladelength * math.sin(math.rad(90 - angle))
TransformBegin()
Rotate(-angle, 0, 1, 0)
blade()
Rotate(2 * angle, 0, 1, 0)
Translate(0, self.bladethickness, 0)
blade()
TransformEnd()
Translate(0, 0, offset)
end
end

theWorld = World()
function theWorld:body(time)
scissor()
end

theCamera = Camera("main")
theCamera.pan = theCamera:avar("pan", {{0.0, 180.0}, {30.0, 270.0}})
theCamera.dolly = theCamera:avar("dolly", {{0.0, 4.0}, {30.0, 8.0}})
function theCamera:body(time)
Projection("perspective", {fov = 50})
Translate(0,0,self.dolly(time))
Rotate(-50, 1,1,0)
Rotate(self.pan(time),0,1,0)
Translate(0,0,-7)
end


theRenderer = RenderMan:create("aqsis")

theRenderer:renderIt{world=theWorld, camera=theCamera,
start=0, stop=30, incr=1,-- motion_blur=0.5,
ribfile="scissor.rib",
display_name="scissor_~s.tif",
display_type="framebuffer",
display_mode="rgb",
xres = 320,
yres = 240}




The script produces the following animation when rendered with Aqsis. Note: this version doesn't have motion blur, because it has uncovered a bug with Aqsis relating to camera motion blur.

video

I'm currently working on a GUI for this system that will allow the user to focus on just writing the code for the model/world/camera bodies, and leaving the boilerplate stuff to the system. It also includes an OpenGL renderer that renders from the same internal representation, so it's possible to have realtime preview of the animation, but that's the subject of another post.

If anyone is interested in this framework, and wants to play with it, or get involved, please respond to this post and I'll get in touch.

Paul