Planet simulation (video teaser: height and shadows)

.@Bortels i am happy you looked at this post! This is your discussion of this spring and the apparent dead end you ran into that triggered me into writing this planet simulation. That would be great if you restarted your project, you had generated so much enthousiasm and hope among this community.

Concerning opacity it is quite easy to modify. If you dowloaded the code you can replace the sphere init and shadows function by these ones. I have added a shadowDepth parameter, equal to 0.2 (20%) by default.

Note that when there are several spheres with textures, the fps start to decrease. It should be possible to recover the fps by coloring the vertices from the texture image, instead of stetting it as a texture. The drawback would be a less accurate surface, but i would be ok when one is far from the planet, and one could switch to the texture mode when the spaceship comes close to the planet. Is it a feature you want me to implement?

function Sphere:init(input)
    -- spatial position of sphere
    self.cx = input.cx or 0
    self.cy = input.cy or 0
    self.cz = input.cz or 0
    -- angular position of sphere, defined by angles around x,y,z axis
    self.ax = 0
    self.ay = 0
    self.az = 0
    -- sphere radius and rotation
    self.radius = input.r
    self.tRot = input.rotTime1
    -- sphere rotation 2
    self.tRot2 = input.rotTime2
    self.cx2 = input.cx2 or 0   -- center of rotation 2
    self.cy2 = input.cy2 or 0
    self.cz2 = input.cz2 or 0
    self.ax2 = input.ax2 or 0   -- axis of rotation 2
    self.ay2 = input.ay2 or 1
    self.az2 = input.az2 or 0
    -- mesh definition
    self.nx = input.nx    -- number of triangles in x
    self.ny = input.ny    -- and in y
    self.c1 = input.c1    -- 2 color() objects, to see the triangles
    self.c2 = input.c2
    self.optimized = input.meshOptimize    -- boolean
    -- sphere decoration
    self.url = input.url    -- texture as a url (text)
    self.hflip = input.hflip    -- to flip image horizontally
    if input.lightDir then
        self.lightDir = input.lightDir:normalize()   -- a vec3 pointing to the sun
    end
    self.shadowRatio = input.shadowRatio or 1.05   -- close to 1.05
    self.shadowDepth = input.shadowDepth or 0.2    -- an number between 0 and 1, close to 0
    
    -- create mesh and colors
    local vertices,colors,tc = {},{},{}
    if self.optimized then
        vertices,colors,tc = self:optimMesh({ nx=self.nx, ny=self.ny, c1=self.c1, c2=self.c2 })
    else
        vertices,colors,tc = self:simpleMesh({ nx=self.nx, ny=self.ny, c1=self.c1, c2=self.c2 })
    end

    -- if a radius is given, warp to a sphere
    if self.radius then 
    vertices = self:warpVertices({
            verts=vertices, 
            xangle=180, 
            yangle=180 
        }) end

    -- create the mesh itself
    self.ms = mesh()
    self.ms.vertices = vertices
    self.ms.colors = colors
    
    -- add the texture from internet
    if self.url then 
        self:load( self.url ) -- this will not be instantaneous!
    end
    self.ms.texCoords = tc
    
    -- add some shadows
    if self.lightDir then self:shadows() end

end

function Sphere:shadows()
        self.ms2 = mesh()
        local dir = self.lightDir
        local vertices2,colors2 = {},{}
        local d = 0
        local dmax = 255*(1-self.shadowDepth)
        for i,v in ipairs(self.ms.vertices) do
            vertices2[i] = v
            d = v:dot(dir)
            d = 128 - 4*(d-0.1)*128 
            if d<0 then d=0 end
            if d>dmax then d=dmax end
            colors2[i] = color(0,0,0,d)
        end
        self.ms2.vertices = vertices2
        self.ms2.colors = colors2
end

Ah, I wish I had more time (My work tends to be not-so-busy, then very busy - and I’m in a very busy phase) - I’d like to dig into this again, but for now I have to file your neat trick for shading for another day. Bravo, by the way - it seems so simple in hindsight, but I spent many hours trying to work out a cheaper way to light than recoloring everything each frame…

If we’re lucky, changes upcoming to Codea may let us do some “real” lighting; I’m keeping my fingers crossed.

I hope too that CODEA will include more built-in real-time way to do shadows, because this trick has some drawbacks, that can be managed, but with some efforts though.

i’ll maybe continue to work along the road to starwars, but it will be very slow, unless someone wants to join me pulling the load. My next step should be to integrate Nat controllers to the scene.

Some news: i’ve added height map management and night map management.
http://www.youtube.com/watch?v=61PDL6u10Yk

Hello everybody. As I went on in my 3d eperiments, if felt the need to gather everything in a signle software package, ‘3d workbench’ where i can try and mix, re-use, things. So i made the following package. It’s not really a tutorial, but there are many comments available when you touch ‘info’, so it is a little bit of a tuto. I have not integrated all my experiments yet (you’ll see many items in the menus are disabled), but it is already interesting enough to share (I think). I’ll post updates as I integrate things. The most interesting things in this code, from my point of view, are:

  • many menus, all real time.
  • total control of view (3 sets of real time contollers)
  • a ‘hand made’ multithreading: to be continuously real time from the player’s perspective, i have designed a ‘jobStack’ class which execute CPU intensive tasks by small slices, during each draw().
  • asynchronous loading of internet images is managed
  • the design is expandable (i can add operations without getting lost), and the operations can be combined.

    Here is what it looks like (as usual, the 22fps is due to recording, it is really 50-60fps)
    http://www.youtube.com/watch?v=ni4kyre0X7w
    You can have the code in a txt file (3000 lines) frm my dropbox:
    http://db.tt/YDOAoNJf
    As usual, i don’t know how to track the downloads, so if you download the code, please just leave a brief comment (even 1 word, like ‘thanks’ is enough), so i know how many people are interested.
    For the videos it is easier, because Youtube indicates the number of view.

Very impressive @jmv38 - I’m not at the 3D stage yet but when I get there I will certainly check out what you have done.

Very nice. Looking forward to checking it out.

Thanks for sharing.

Wow, gotta say this is impressive. What accounts for the slices in the transparent globe bit?

Thanks @all. @Fred: the slices is the transparent globle are un unwanted ‘bug’ in tranparency effect: transparent meshes seem to always have a partially opaque side: ‘partially’ because it is this side is transparent to other meshes drawn before, but opaque to some parts of the mesh itself. In general, transparent objects are transparent to objects drawn before, but opaque to objects drawn after. This is surprising because the bug is only for transparency, not for occlusion.

My assuption to explain this: the transparency is managed only once, when the triangle is drawn on the screen buffer. When the pixels of next triangles are drawn, the OS checks if they are visible (with an internal Zmap image i suppose), so he knows if they are visible or not (occlusion). So if the pixel is below the current Zmap level, it is not drawn (opacity), while we would like it to be drawn but mixed with the already present color (transparency). But to work as desired, the Zmap would have to be very complex: it should keep track not only of highest level, but also of the zlevels and colors of all successive drawing at each pixel location! This would be very memory consuming! It is probably why they don’t do it.

So it is (i think) a CODEA or IOS or GraphicProcessor bug. Can we take this as a fact and manage it? It would mean /1/ managing zlevels of objects ourself, by splitting them in sub-meshes of relatively flat regions, and drawing objects in the good order, depending on the viewer position… Too complex i think. For a game it is probably feasible to /2/ limit the object rotation wrt the viewer within limits where the transparency works correctly.

Your assumption is correct and it is OpenGL that is responsible, hence no likelihood of change, sadly.

First, this is really cool what you made here :slight_smile:

For the transparency, there is another option to make it look better, but I dont know if this can be used in Codea: When drawing transparency with OpenGL, you normally switch off the DepthBuffer writing (thats what you called zMap). Then all back faces are also drawn. This is not perfect, as the correct drawing order back to front is still needed to make it look correct when the colors are mixed. But at least it then renders all triangles. And it looks correct for transparency higher than about 70% (which is my experience). When drawing mixed transparent and opaque objects you first render the opaques with zBuffer writing enabled and then the transparent with zBuffer writing disabled.

While writing this I got another idea, which works for convex objects: To render back to front without sorting you would first render the back sides (inner side) of the sphere and then the front sides. In OpenGL this can be set with glCullFace, but I think also this is not available in Codea. You just need to define the triangles correct in counter clockwise vertex order.

Both options dont need any zsorting so it is still very fast.

But as Codea will have Shaders soon, this could get possible. I’m a standard OpenGL programmer, so I dont know much about shaders yet, but it should be possible to decide front and back face, maybe also depth writing… or if somebody from Codea reads this, it could maybe be taken into account to add it if it doesnt work with shaders :slight_smile:

Thank for the tips @KilamMalik. Any comment on this problem @Simeon?

.@Jmv38 that’s a really impressive demo you have there.

Good thoughts, @KilamMalik. I will think about providing interfaces to some of the lower-level OpenGL functions (depth function, enable depth testing, culling, and so on).

For more information about this issue, here is the OpenGL wiki about transparency sorting: http://www.opengl.org/wiki/Transparency_Sorting

As you can see from that article, even sorting polygons by Z-value is not enough to get error-free transparency.

Thank you @simeon.

Video teaser of my latest extensions: heights and shadows (static)
http://www.youtube.com/watch?v=ITgIY44TVoA

Hi @Jmv38, simply Amazing!

.@Jmv38 the exaggerated height map reminds me of the Spore planets. Looks great!

Thanks @yelnats & @Simeon

Want more?
http://www.youtube.com/watch?v=36LJ7Z8mcGw
I’ll be in family next days, so i’ll give you a break till monday… :wink:

I shall be going over your example code with a fine toothcomb, 3D is an area I’d like to get more knowledge on - many many thanks for sharing!