3D API Overview - 1.3.2 Beta


I’ve opened this thread up to everyone so people can examine and comment on the new 3D stuff

There is no documentation for this stuff yet. So this thread will serve as the beta documentation for now.

You can grab a sample 3D scene here: http://twolivesleft.com/Codea/Projects/3D_Test.codea

Source code on pastebin: http://pastebin.com/gJ6CxXD2

Basic Matrix Control

multMatrix( m )

Multiplies matrix m against the current model matrix.

modelMatrix( m )

Called with no parameters, returns the current model matrix. When called with a matrix parameter modelMatrix sets the current model matrix to the specified matrix. Defaults to identity.

projectionMatrix( m )

Called with no parameters, returns the current projection matrix. When called with a matrix parameter projectionMatrix sets the current projection matrix to the specified matrix.

The default projection is an orthographic projection starting at the lower left of the screen and extending WIDTH, HEIGHT to the upper right corner of the screen.

viewMatrix( m )

Called with no parameters, returns the current view matrix. When called with a matrix parameter viewMatrix sets the current view matrix to the specified matrix. Defaults to identity.

Basic Types


Represents a 4x4 matrix (column major). Supports the following operations:

m1 = matrix() -- creates an identity matrix

m2 = matrix( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 )

m = m1 * m2 -- matrix multiplication

m = m1 * 5 -- scalar multiplication

m = m1 / 5 -- scalar division

m = m:rotate( angle, x, y, z )

m = m:translate( x, y, z )

m = m:scale( x, y, z )

print( m )


vec4 is new. vec3 now supports most common operations that vec2 supports.

View Control

perspective( fov, aspect, zNear, zFar )

This sets the projection matrix to the perspective projection defined by the given parameters. If called with no parameters it defaults to fov=45 degrees, aspect=WIDTH/HEIGHT, zNear=0.1, zFar=(HEIGHT/2) / tan( pi * 60 / 360 ) * 10.

ortho( left, right, bottom, top, near, far )

This sets the projection matrix to the orthographic projection defined by the given parameters. If called with no parameters it defaults to ortho( 0, WIDTH, 0, HEIGHT, -10, 10 )

camera( eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ )

This sets up the view matrix to emulate a camera positioned eye and pointing at center, with an up-vector defined by up. Called without parameters it defaults to camera( 0, 0, -10, 0, 0, 0, 0, 1, 0 )

Is this in testflight yet? I haven’t received a notification if it is (it keeps asking if I want to install Codea 1.3.1 (15))

It’s 4am and I still can’t get the build uploaded to TestFlight. It’s driving me crazy — Xcode 4.3 and iCloud entitlements are causing all sorts of issues.

In the worst case I’ll have to recompile it on my laptop tomorrow morning using the older version of Xcode. That shouldn’t have issues.

Also every attempt to upload the build is taking 15 minutes. The internet connection here is pretty poor.

Finally sorted it out. It should be available now.

Downloading as I type … Yippee!

Neat! Got the demo, pretty damn cool. Time to mess with things. :slight_smile:

Looks really cool, @Simeon! I’m just getting into learning OpenGLES, so this kind of ties in pretty nicely :slight_smile:

I’m not sure if the following questions are tangential to what you want to discuss here, but I figured this was likely to best place to ask.

I’ve just drawn a cube using a mesh with vec3 vertices, and it worked perfectly. Is there any way to texture the different faces of something like this at present? addRect / setRectTex / etc only support 2D meshes? This may well be beyond the scope of what you want the API to provide.

Also, is there any way (presumably by using a different shader) that you could provide the ability to add / position light sources? Again, might be outside the scope of what you’re going for, but of course the cube I created is just rendered in a flat colour. As I said, I’m just learning OpenGLES, so I’m not sure how difficult / possible this is, or if I’m even asking the wrong question entirely! :slight_smile:

You can texture them by setting the texture coordinates of each vertex (mesh.texCoords). The addRect API is 2D at the moment. I’m not sure if we’ll take that into 3D — maybe addQuad with vec3 arguments would be more suited.

We haven’t exposed GLSL shader functionality. But it’s something I’d like to do — definitely not this update though. At the moment you can simulate vertex lighting by computing the normals for each vertex and then computing the light intensity for each vertex given a particular light position. You’d use this to modulate the vertex colours to simulate light.

Thanks @Simeon - setting texCoords makes perfect sense! Your description of lighting lost me at ‘normals’ (I know of them, but not really what they are) - I’ll have to read up. :slight_smile:

Anyways, I made a little cube:

Hmm - exposing my ignorance here. I thought that GLSL let you program the lighting model (among other things) - but that the base normal lighting models (point sources, and ambient, and so on) were “cooked in” - ie. there was, for example, a GLSL chunk of code for “ambient” you would simply reference. (This may be my old-school-before-shader-pipelines ignorance showing).

Even if we can’t do our own GLSL, a basic lighting model would be very handy - I don’t know how far flat-shaded 3D will go…

Basic lighting models are no longer built-in to OpenGL ES2 (they were in OpenGL ES1). It’s very easy to emulate the standard fixed vertex lighting model, but in us doing so (and designing an API around it) I feel we would better spend that time implementing some really nice GLSL UI and API.

Expanded to a basic 3D tilemap:

Yay. This is awsome. Have your thought about just putong this in 1.4 and adding other features to? This is a giant feature in my opinion…
Thank you so much!

I presume backfaces are not drawn? I tried adding translucent water blocks, but you can only see through them from one direction.

We’ll have to add a flag to enable back face rendering.

@Simeon - Oh this is awesome guys :smiley:

Can’t wait for it to be released to try it out on my code !
If all goes well I should see a nice framerate boost :smiley:

If you could get back face culling as a switchable flag it would be nice :stuck_out_tongue:



Wholly s***! I just looked at the code, at BAM! even I can understand it. THANK YOU SO MUCH! And was thought out just the right way and also limits your work. If you could eventually add the ability to add a light source and turn light lighting on and off, that would be nice, but that also means add and object’s luster parameters. YIPEE! Life just got much more exciting now that I can really comprehend your method. And @frosty: Out of curiosity, I just want to see some of your code. Your stuff looks cool.

I want to see frosty’s code too because I don’t have this working yet. I’m trying to get my head round the matrices but when I print them I get weird stuff : some entries are even nans.

Are you able to share some code that generates NaNs?

function setup()
function draw()
    if not done then
        done = true

produces a 4x4 matrix with nans in the 4,1 and 4,2 slots (row,coloumn), a 1 in the 1,1 slot, and 0 everywhere else.