.@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.
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.
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.
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
.@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).