Shadows always add realism to our scene , here I explain
about how to do it and how to apply it to your scene casting a
character shadow , this technique is a good idea to apply for
directional light , you don't need know the mesh structure data , and
you can apply it in only one pas to you scene without project the
texture , you only need build a square and apply the texture to it.
I use OpenGL ,C++ under GNU/Linux to explain this technique , all
images are from my personal project at Black-Legacy.com
We can cast a fast flat shadow from a directiona light using our object
like a shadow stencil, but we can use the wrap object texture to cast a
realistic shadow
These images have a Object shadow, left image you can see the model
without texture and the right image have a texture using transparecy ,
but the shadow is a object shadow, We need Texture shadow to cast also
the transparency.
To do it , follow the next steps:
* Clear Framebuffer using glcolor (1110) ,because later we do White
color as tranparence.
* Place a camera on light position , camera are lookin to our object
* Draw your object.
* Get Framebuffer (using glCopyTexSubImage2D )like a texture and pace
it down our object.
* Every Frame.
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)wwwn/(GLfloat)whwn, 5.0f ,4000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( Light_posX,
Light_posY,Light_posZ, ObjectX,ObjectY,
ObjectZ, 0, 1, 0);
DRAW YOUR OBJECT(IMPORTAN DRAW YOUR OBJECT USING TEXTURES AND
TRANSPARENCES PROPERTIES IF REQUIERED)
glBindTexture(GL_TEXTURE_2D, ShadowMapTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,256,256, 0,GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
(ScreenResolutionWn/2)-128, (ScreenResolutionWh/2)-128, 256, 256);
---------------------------
DRAW YOUR SCENE AND PLACE A SQUARE DOWN OUR OBJECT.
|

We optain a similar image , but in these image shadow
is black , really we get a collored image.
Now We need apply glBlendFunc filters to convert white
color into transparent color, Just enable Blend and Alpha Test
after drow the square down our object. And draw the square White as
possible.
|
Note these function draw MY square ,
sure you need change it.
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.9);
glTranslatef(ObjectX,ObjectY, ObjectZ);
glBlendFunc(GL_DST_COLOR,
GL_ZERO);
glBindTexture(GL_TEXTURE_2D, ShadowMapTexture); //
shadowMapTexture is my texture name
glColor4f(1,1,1,0.003);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-7,0,-7);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-7,0,7);
glTexCoord2f(0.0f, 0.0f); glVertex3f(7,0,7);
glTexCoord2f(1.0f, 0.0f); glVertex3f(7,0,-7);
glEnd();
glPopMatrix();
|

Now white square is transparent and que can see our shadow, but this
shadows is a colored shadow, usefull for a mirror, sure , and for
a reflective water, sure. But not for a shadow, We need delete the
color or get only 2 colors , these is more easy option, Only need chane
one data on our code to get gray scale.
Look for this line:
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,256,256, 0,GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
Change Red data to 1 ,like
glTexImage2D(GL_TEXTURE_2D, 0,1,256,256,
0,GL_RGBA, GL_UNSIGNED_BYTE, NULL);
Now We get our image, but only grey color.
These are the new image, now shadow have grey scale
,this is good for glass objects ,sure, and for ice objects
sure , perhaps is good for a invisibility ,but not for a shadow , we
need a grey unifor shadow, and to do it
We need conver our texture to Black texture, How,
After you draw the object to get it, select drawing color to Black ,
and disable light.
|
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)wwwn/(GLfloat)whwn, 5.0f ,4000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( Light_posX,
Light_posY,Light_posZ, ObjectX,ObjectY,
ObjectZ, 0, 1, 0);
glDisable(GL_LIGHTING);
glColor4f(0,0,0,1)
DRAW YOUR OBJECT (IMPORTAN DRAW YOUR OBJECT USING TEXTURES AND
TRANSPARENCES PROPERTIES IF REQUIERED)
glBindTexture(GL_TEXTURE_2D, ShadowMapTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0,1,256,256, 0,GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
(ScreenResolutionWn/2)-128, (ScreenResolutionWh/2)-128, 256, 256);
---------------------------
DRAW YOUR SCENE AND PLACE A SQUARE DOWN OUR OBJECT. |

A unifor shadow, but very hard , this shadow is good for a very strong
light
near to our objects, but We don cant change our glcolor (0,0,0) to
other grey
scale color because we return to glass shadow, Then we can use stencil
buffer
to compare a our object and a grey square and only get the
portion of the .....
Yes we can do it , is a hard way and stencyl buffer is a slow buffer ,
and
need 32 colours bit.
More easy enable FOG , we can create a very hard gray fog, Shadow will
be smooth like
Fog as White. Now We can adjust our shadow smooth using the Fog
colour.
|
GLfloat fogColor[4]=
{0.65f, 0.65f, 0.65f, 1.0f};
glFogi(GL_FOG_MODE, GL_EXP);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35f);
glHint(GL_FOG_HINT,
GL_DONT_CARE);
glFogf(GL_FOG_START,
1.0f);
glFogf(GL_FOG_END,
5.0f);
glClearColor(1,1,1,0);
glEnable(GL_FOG);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)wwwn/(GLfloat)whwn, 5.0f ,4000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( Light_posX,
Light_posY,Light_posZ, ObjectX,ObjectY,
ObjectZ, 0, 1, 0);
glDisable(GL_LIGHTING);
glColor4f(0,0,0,1)
DRAW YOUR OBJECT (IMPORTAN DRAW YOUR OBJECT USING TEXTURES AND
TRANSPARENCES PROPERTIES IF REQUIERED)
glBindTexture(GL_TEXTURE_2D, ShadowMapTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0,1,256,256, 0,GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
(ScreenResolutionWn/2)-128, (ScreenResolutionWh/2)-128, 256, 256);
---------------------------
DRAW YOUR SCENE AND PLACE A SQUARE DOWN OUR OBJECT.
DON'T FORGET
RESTORE YOUR ALPHA ,BLEND , FOG and LIGHT PROPERTIES
|

And this is the final result , a Realistic Real-Time Fast Flat Shadow,
Flat shadow is a good way to apply shadow for a chjaracter, or other
objects , but flat shadow don't have relief properties, You need
Volumetric,Stencil or projective shadow to create relief shadow effect.
Luckyly this fog shadow have addidtion properties,and have really fast
to render it and look nice, I develop this shadow estyle to use it on
my personal project Black Legacy . feel free to test it!!
I develop the FOG SHADOW idea and To avoid every one get a fuck
copyright from this idea , I do IT GPL

Addition properties
|
|