Dark Bit Factory & Gravity
GENERAL => Projects => Topic started by: taj on July 10, 2007
-
Hi all,
heres a quick demo that will run on almost any opengl card with decent numbers of polygons.
Its a test to see if real time, dynamic, smooth, ambient occlusion can be done with just spheres.
The code is uncompressed so maybe it would fit in 1k but who cares - its cool anyway.
When I'm done I'll post some code.
-
very cool i really like that! :goodpost:
-
More pastel colours in demos please!
How many samples are you taking for the occlusion on each pixel?
Jim
-
Nino, I'm really happy you like it, I've tuned it a little and created what I think are better looking , though actually, not as physically correct shadows. I will upload the newer version in a minute after this post.
Jim, pastel is cool :-) The ambient occlusion is calculated per vertex not per pixel (no shaders here). Of course I have a hell of a lot of vertices in there. Once I'm happy with the code and effect, I'll post it - I guarantee you will be stunned.
Thanks for feedback guys, its really appreciated.
-
Guys,
Here is a newer version which also has a ground plane with ambient occlusion from the spheres.
I haven't worked out yet how to get the ground plane to occlude the spheres using this technique.
This is quite cool now I think. I added another pastel color for Jim :-)
-
Those look really nice :) Reminds me of fruit bonbons.
The first version ran a little too quickly for me, the second one with the ground plane ran also a little bit quick to be able to see the effect properly, however the soft shadows are a hit. This can be really beautiful. It's already more interesting than Farbrausches latest 4kb.
-
Yep, nice one.
wonders how many tris the floor's made of.
-
Wow! very amazing! Even version 2 with the shadows runs very smooth and looks awesome! :goodpost:
-
Hi again,
shockie, I actually rather likes FRs latest 4k, the colours were sweet :-). Speaking of sweets, yep its bonbons everywhere. Ambient occlusion always seems to give that sort of look but when I add the pastel colours .. damn its just like a bon bon. (shockie Ill add a timer for you in final version).
Stonemonkey, the floor is composed of 7200 triangles but I think I could use less...
Anyway, solved the problem of getting the ground plane to shade the spheres. So new version of the demo. I need to tidy code now and explain it a bit so I'll publish soon. Getting late and got a trip tomorrow so may be weekend, we'll see.
I should say how its done though now as I know it works. Heres the killer, I use opengl lighting model with 8 opengl lights to do the ambient occlusion. Basically there is a light in each sphere. The lights are "darklights" that is, they have negative colour values! Then I draw all the objects with maximum ambient lighting (so they would come out looking completely flat) but then the darklights SUBTRACT light from the scene.
I had to setup the attenuation of the light correctly for the equation for ambient occlusion of a sphere on any other object (this was the big trick).
The plane is more difficult but in the end I realised that I could use one point light source and move it around. Each time I draw a sphere I move the point light directly under the sphere on the plane then set attenuation which is correct for a plane. OpenGL lighting does the rest!
So thats it, one darklight inside each sphere and one darklight that moves around under each sphere on the plane.
I'll post code when its not so embarressing.
Real time, dynamic ambient occlusion of spheres and planes using OpenGL 1.1 (no shaders or extensions required).
With some work it might even fit in 1k.
-
That's such a clever trick with the lights :) Thanks for the explanation, hopefully you'll include a few versions in the end? It must be doing at least 200fps here!
-
Shock I added a timer just for you, download again and it should run nice and smooth for you.
Chris
-
Totally smooth :) Perfect!
-
Aha, a use for gl lights :p or is it just me that doesn't like them.
Nicely done btw.
-
Smoothly here :) , another great idea :clap:
-
You impressed me another time, Chris. Runs absolutely smooth and gentle here.
The pastel colors are extremely cool. And I agree with Jim that there should be
more pastel colors in intros/demos. Looks very arty.
Very well done!!!
-
Thanks for all the kind comments guys I really appreciate the feedback. Only good feedback though ;-)
Seriously thanks- very encouraging.
I think I've come to an end of this little one so Ill post code tomorrow (too late tonight). However I've thought of several other really bizarre uses for opengl lights so I'll try coding them and see.
Stonemonkey: yeah opengl lights are a pain and suck in many ways. I think that why I started down this path of - ok they suck as lights, wonder how we could use them for something else?
Chris
-
Heres the code...
#include <windows.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#if defined(__cplusplus)
extern "C" {
#endif
int _fltused;
#if defined(__cplusplus)
};
#endif
//max number is 7, we must reserve one light for plane
// opengl supports 8 lights
#define NLIGHTS 7
static const GLfloat white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //doubles as position of lights
static const GLfloat darklight[] = { -2.0f, -2.0f, -2.0f, 2.0f };
static GLUquadricObj *q;
long startTime;
float time;
void setup(){
int i;
q = gluNewQuadric ();
gluQuadricNormals (q,GLU_SMOOTH);
glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
// everything in the scene will receive white ambient light
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, white);
//setup all opengl lights to be "ambient occlusion" lights.
for (i=0;i<8; i++) {
glLightfv(GL_LIGHT0+i,GL_AMBIENT,black);
glLightfv(GL_LIGHT0+i,GL_SPECULAR,black);
// yo the secret sauce...
// lights are set with NEGATIVE colour!
glLightfv(GL_LIGHT0+i,GL_DIFFUSE,darklight);
// a quadratic falloff of light power is used
// attenuation is 1/(constant + linear*dist + quadratic*dist)
glLightf(GL_LIGHT0+i, GL_CONSTANT_ATTENUATION, 1.0f);//so intersecting spheres look right
glLightf(GL_LIGHT0+i, GL_LINEAR_ATTENUATION, 0.0f);
glLightf(GL_LIGHT0+i, GL_QUADRATIC_ATTENUATION, 2.0f); //physically correct would be 1.0, but it looks bad :-)
}
// enable all sphere lights
for (i=0;i<NLIGHTS;i++) glEnable (GL_LIGHT0+i);
// now the plane light needs differnt attenuation factors...
glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 0.0f);//touch the plane and its black
glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 1.0f);
glLightf(GL_LIGHT7, GL_QUADRATIC_ATTENUATION, 0.0f);
// enable plane light
glEnable (GL_LIGHT7);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f,1.0f,0.1f,100.0f);
gluLookAt(0,0,-10.0f, 0,0,0, 0,1,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
time =0;
}
void moveSpheres(int val){
glRotatef(time*0.4f,1,1,1);
glRotatef(val*time,val,5,3);
glTranslatef(sinf(val+time*0.1f)*4.0f,0,0);
}
void moveGroundLight(int val){
glTranslatef(0,-6.0f,0);
glScalef(1.0f,0.0f,1.0f);
moveSpheres(val);
}
void drawGround(){
// draw GROUND plane
glLoadIdentity();
glTranslatef(0.0f,-5.0f,0.0f);
glRotatef (-90,1,0,0);
glColor4f (1.0f,1.0f,0.9f,1.0f);
// disable the ground light as it should not occlude itself
glDisable (GL_LIGHT7);
gluDisk(q,0.0f,20.0f,60,60);
glEnable (GL_LIGHT7);
}
void drawAOSpheres(){
int i;
// set the lights in position
for (i=0; i<NLIGHTS; i++) {
glLoadIdentity();
moveSpheres(i);
// black is 0,0,0,1, which are the values we need for
// a point light at the origin.
glLightfv (GL_LIGHT0+i, GL_POSITION, black);
}
// draw the spheres being careful not to draw a sphere occluding itself
for (i=0;i<NLIGHTS; i++) {
// simulate a plane by always placing a light under the sphere on the plane
glLoadIdentity();
moveGroundLight(i);
glLightfv (GL_LIGHT7, GL_POSITION, black);
// a sphere should not occlude itself so switch off its own light
glDisable (GL_LIGHT0+i);
glColor4f (1.0f-(i/20.0f),0.7f+(i/20.0f),1.0f,1.0f);
glLoadIdentity();
moveSpheres(i);
gluSphere (q,1,30,30);
glEnable (GL_LIGHT0+i);
}
}
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
PIXELFORMATDESCRIPTOR pfd;
HDC hDC;
pfd.cColorBits = pfd.cDepthBits = 32;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
hDC = GetDC ( CreateWindow("edit", 0,
WS_POPUP|WS_VISIBLE,
100, 100, 640 , 480, 0, 0, 0, 0) );
SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, &pfd) , &pfd );
wglMakeCurrent ( hDC, wglCreateContext(hDC) );
ShowCursor(FALSE);
glClearColor(1.0f,1.0f,1.0f,1.0f);
setup();
startTime = timeGetTime();
do {
glClear ( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
time = (timeGetTime() - startTime) *0.006f;
drawAOSpheres();
drawGround();
SwapBuffers ( hDC );
} while ( !GetAsyncKeyState(VK_ESCAPE) );
ExitProcess(0);
}
-
Someone should pay this guy for posting so much valuable sources and information.
Unfortunately I am low on money (as always). So, there is nothing I can do except
to say :
THANKS YOU A THOUSAND TIMES :goodpost:
and of course credit your work with some KARMA.
Chris rocks!
-
Thanks for all the kind comments guys I really appreciate the feedback. Only good feedback though ;-)
Seriously thanks- very encouraging.
You are posting your things amongst friends who appreciate the effort that has gone into getting even the framework together for this, let alone the final piece of art. :)
-
looks very fine and run smooth on my laptop :)
nice work! :D
-
Someone should pay this guy for posting so much valuable sources and information.
:-)
Use and abuse as fit Benny.
Dont give up on OGL lights, I know iq from rgba has a few tricks with ogl lights to avoid shaders.
I reckon metaballs can be done with lights and other effects.
-
@chris: Can you use this algorithm for more detailed 3D object (like 3d Marylin Monroe in a 4k :P), or only for spheres ?
-
@chris: Can you use this algorithm for more detailed 3D object (like 3d Marylin Monroe in a 4k :P), or only for spheres ?
Well yes and no. The spheres can ambiently occlude any geometry - even Marylin :-) lol. The technique wont work for Marylin occluding herself-which will look very odd indeed. However, going back to the older swept surface code and tutorial I posted here. I think that could be extended to calculate an approximate ambient occlusion for say, chess pieces, and these combined with the balls.
Chris