![]() |
Home | ![]() |
About Me | ![]() |
Notes | ![]() |
Galleries | ![]() |
Files | ![]() |
Links | ![]() |
![]() |
Programming | ![]() |
Maths | ![]() |
Odd Bits | ![]() |
![]() |
3D Graphics | ![]() |
Sometime soon, I'll be putting an OpenGL cookbook here. Stuff about how to set up an OpenGL camera and a neat transparency effect using lighting.
Update: I'm been busy more than a year, so I'll just describe the neat transparency effect quickly:
As usual, you should render transparent objects last. When you render the transparent objects, you should test the depth buffer but not set it.
First, make sure you have a procedure for drawing the glass object, since you'll have to draw it twice, once for the oblique surface darkening effect and once for the specular highlights. The procedure should not set any materials. You may want to disable glColorMaterials to keep things simple.
The first pass of the rendering tints the scene behind the glass. Tinting is acheived by the multiplicative blending mode (GL_ZERO, GL_SRC_COLOR). The glass is not lit by the world's lighting but by a non-attenuating 'headlight' from the camera. This light causes the edges of a sphere, say to be darker than the middle. Make sure the global ambience is turned off (set to black) and the headlight has no specular component (also set to black), Think of some appropriate colours for the headlight and/or the material.
Set the blend mode to (GL_ZERO, GL_SRC_COLOR), disable the face culling, and render the glass object. The scene behind the glass is now tinted, possibly more than once by the glass if it is a complicated shape.
Restore the lights to the way it was before the last step. You're about to render the specular highlights. Set the blending mode to be additive (GL_ONE, GL_ONE). Set the current material to be black with a strong specular reflection for the front and back surfaces. The front specular should be white and the back specular should be tinted somewhat to the colour of the glass. Render the glass object again.
Restore anything else you need to.
Here is a code fragment that sets up the lighting for a typical scene, including the 'headlight' that is used to vary the opacity of glass objects:
// SetUpLighting(CameraDirection, SunDir) // // Sets up the lighting for rendering the terrain and the objects. // The camera's direction, a unit vector, is needed to orient the // special 'lights' that vary the opacity of glass objects across // their surfaces. The sun direction is a unit vector that describes // the direction of the sun from from the world (ie the vector // points towards the sun. void SetUpLighting(const Vector3f CameraDirection, SunDir) { glEnable(GL_LIGHTING); // Enable the lights used to render most of the world. // Theese are the sun, the sky and the ground. The greenish // light of the ground is actually mixed in the ambient part // of the sky's bluish light. glEnable(GL_LIGHT0); // sun glEnable(GL_LIGHT1); // Sky and ground // Disable the special light that is not used to illuminate // the world but to darken the obliquely viewed surfaces of // glass objects. glDisable(GL_LIGHT2); // Headlight // Zero the global ambience const GLfloat GlobalAmbience[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GLfloat SunAmb[4] = (0.00f, 0.00f, 0.00f, 0.00f); GLfloat SunDif[4] = {1.50f, 1.55f, 0.98f, 0.00f}; GLfloat SunSpc[4] = {1.50f, 1.50f, 1.55f, 0.00f}; GLfloat SkyAmb[4] = {0.50f, 0.54f, 0.52f, 1.00f}; GLfloat SkyDif[4] = {0.15f, 0.19f, 0.28f, 0.00f}; GLfloat SkySpc[4] = {0.00f, 0.00f, 0.00f, 0.00f}; // It's best to leave the headlight colour a diffuse white. // Glass objects whose opacities will be varied by this light // will have their own colours defined by their material // properties. GLfloat HeadlightAmb[4] = {0.0f, 0.0f, 0.0f, 1.0f}; GLfloat HeadlightDif[4] = {1.0f, 1.0f, 1.0f, 0.0f}; GLfloat HeadlightSpc[4] = {0.0f, 0.0f, 0.0f, 0.0f}; GLfloat SkyDir4[4] = {0.0f, 0.0f, 1.0f, 0.0f}; // From straight up GLfloat SunDir4[4] = {SunDir.x, SunDir.y, SunDir.z, 0.0f}; GLfloat HeadlightDir4[4] = { -CameraDirection.x, -CameraDirection.y, -CameraDirection.z, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, SunAmb); glLightfv(GL_LIGHT0, GL_DIFFUSE, SunDif); glLightfv(GL_LIGHT0, GL_SPECULAR, SunSpc); glLightfv(GL_LIGHT0, GL_POSITION, SunDir4); glLightfv(GL_LIGHT1, GL_AMBIENT, SkyAmb); glLightfv(GL_LIGHT1, GL_DIFFUSE, SkyDif); glLightfv(GL_LIGHT1, GL_SPECULAR, SkySpc); glLightfv(GL_LIGHT1, GL_POSITION, SkyDir4); glLightfv(GL_LIGHT2, GL_AMBIENT, HeadlightAmb); glLightfv(GL_LIGHT2, GL_DIFFUSE, HeadlightDif); glLightfv(GL_LIGHT2, GL_SPECULAR, HeadlightSpc); glLightfv(GL_LIGHT2, GL_POSITION, HeadlightDir4); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, GlobalAmbience); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); } // End of SetUpLighting(CameraDirection, SunDir)
The following code fragment shows how the rendering of the glass effect is done. This example renders gold tinted glass of the sort used in F16 canopies.
// These settings can usually be issued just once if all the // glass objects to be rendered are rendered together. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glDisable(GL_CULL_FACE); glDepthMask(0); glEnable(GL_BLEND); glDisable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); GLfloat Black[4] = {0.0f, 0.0f, 0.0f, 1.0f}; GLfloat Ambient[4] = {0.65f, 0.55f, 0.30f, 1.0f}; GLfloat Diffuse[4] = {0.35f, 0.40f, 0.40f, 1.0f}; GLfloat Specular[4] = {1.00f, 1.00f, 1.00f, 1.0f}; GLfloat BackSpecular[4] = {0.80f, 0.70f, 0.10f, 1.0f}; GLfloat Shine[] = {50.0f}; glBlendFunc(GL_ZERO, GL_SRC_COLOR); // Multiplicative blending glDisable(GL_LIGHT0); // Off: Yellow sun glDisable(GL_LIGHT1); // Off: Blue sky (and olive ground ambience) glEnable(GL_LIGHT2); // On : Gold canopy headlight glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Black); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, Shine); *** Draw canopy *** glBlendFunc(GL_ONE, GL_ONE); // Additive blending glEnable(GL_LIGHT0); // On : Yellow sun glEnable(GL_LIGHT1); // On : Blue sky (and olive ground ambience) glDisable(GL_LIGHT2); // Off: Gold canopy headlight glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Black); glMaterialfv(GL_FRONT, GL_SPECULAR, Specular); glMaterialfv(GL_BACK, GL_SPECULAR, BackSpecular); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, Shine); *** Draw canopy again *** *** Restore lighting if necessary ***