## Applying scorch decals

Well, it's actually *less* effective. There's a lot of "overhang" where a quad is larger than the triangle beneath it and hangs off the edge, or goes under an adjacent triangle. When it looks good, it looks pretty good.

You can see pretty good looking sortching on the ground here

But here, close up, you can see overhang

So, what I'm wondering is how you guys would do this.

Right now, I'm investigating an approach where I get all the triangles that intersect a small spherical volume ( the damage radius ) and then I'll tessellate a bunch of triangles to map directly to the terrain or other object. That ought not be too hard, though I suspect robust texture coordinate generation will be non-trivial ( unless I limit myself to doing this on heightmapped terrain, in which case it will be dirt-simple )

It occurs to me that projected texturing might be the answer. But, I know *nothing* of projected texturing. For example, do you need a free texture unit for *each* projected texture? I would need hundreds then, since I've got a lot of scorch damage in my game, as you can see from the first ( "Death from above" ) screenshot.

Basically, how would you guys approach this?

But then, I still know nothing of projected texturing. I find plenty of source code, but essentially nothing that describes it from a 10,000 foot perspective in pseudocode.

The 3D Game Programming book by Eric Lengyel shows how to do this. Basically the quad is split into triangles along the edges of the underlying mesh and each triangle is placed in the same plane as the mesh triangle below it. Works good. Was not too difficult to implement.

Looking at the stuff in the book now and it actually doesn't give too much info about it. I found some example code somewhere when I implemented my decal class but now I have no idea where I got it from. I did this a few years ago.

KenD

Looking at the stuff in the book now and it actually doesn't give too much info about it. I found some example code somewhere when I implemented my decal class but now I have no idea where I got it from. I did this a few years ago.

KenD

CodeBlender Software - http://www.codeblender.com

One more note. It's possible I found the code in one of Game Programming Gems books but I don't have them here right now so I can't take a look.

KenD

KenD

CodeBlender Software - http://www.codeblender.com

TomorrowPlusX Wrote:Right now, I'm investigating an approach where I get all the triangles that intersect a small spherical volume ( the damage radius ) and then I'll tessellate a bunch of triangles to map directly to the terrain or other object. That ought not be too hard, though I suspect robust texture coordinate generation will be non-trivial ( unless I limit myself to doing this on heightmapped terrain, in which case it will be dirt-simple )

This basic idea is probably the best way to go. If you try to do this in one pass you will be limited by the number of texture units, so you might as well draw each decal separately. I assume you're trying to simulate a mark from sort of spherical explosion, so maybe you could just find what triangles the sphere intersects, and then for the texture coordinate at each vertex of the triangles you could assign based on how deeply the vertex penetrates the sphere. You could even use a 3d texture, though I doubt it would look much better.

If you doing those sort of decals on more than terrain you could potentially do the exact same thing except draw every triangle- you could even use a vertex shader or some more simple texcoord generation so you don't have to send a texcoord array to the video card. That might help with the terrain case as well if you break the terrain into chunks.

Also, it occurred to me that with texture clamping set I can use phydeaux's premise of just setting texture coordinates as distance from the damage origin. Then I don't need to do anything hairy like subdivision of the scene triangles to get optimal texture coordinate assignment.

I'll keep you all posted, probably with stupid questions. Right now I'm hacking up a test state for my game where I can quickly prototype the code.

The implementation for the decal stuff is in the "Game Programming Gems 2" book. The chapter is written by Lengyel so it's basically the same as in his book and the CD contains an implementation of it.

KenD

KenD

CodeBlender Software - http://www.codeblender.com

Code:

`glEnable(GL_TEXTURE_GEN_S);`

glEnable(GL_TEXTURE_GEN_T);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );

glTexGenfv( GL_S, GL_OBJECT_PLANE, vec4( 1, 0, 0, -_position.x ).v );

glTexGenfv( GL_T, GL_OBJECT_PLANE, vec4( 0, 1, 0, -_position.y ).v );

glMatrixMode( GL_TEXTURE );

{

glLoadIdentity();

glScalef( 1.0 / scale, 1.0f / scale, 1.0f );

glTranslatef( scale * 0.5f, scale * 0.5f, 0.0f );

}

glMatrixMode( GL_MODELVIEW );

Where scale is the size of the texture in world units ( calculated as distance from the center of the damage sphere ) and _position is the location in world units of the damage sphere.

This works *great* so long as I'm only concerned with top-down projection.

What I've been trying to figure out, however, is how to get an arbitrary projection to work correctly. By arbitrary projection, I mean projection against an arbitrary plane, as in something other than ( 0,0,1,0 ).

So far, I have tex gen's axes for S and T working for an arbitrary plane. The trouble is figuring out an offset so the texture is centered around the vector along which I'm projecting.

This is what I'm doing, and basically what's failing is the fourth component of the GL_OBJECT_PLANE parameter, the offset of the plane from the origin. I'm drawing a blank as to how to calculate this value.

For reference, _position is the center of the damage sphere, & closestProjection is an "optimal" center for the texture map in world space.

Code:

`//make a normalized vector from texture center to damage origin`

vec3 projectionDirection( closestProjection - _position );

projectionDirection.normalize();

vec3 posY( 0, 1, 0 );

vec3 sAxis, tAxis;

//make perpendicular s & t axes

sAxis.cross( projectionDirection, posY );

sAxis.normalize();

tAxis.cross( sAxis, projectionDirection );

tAxis.normalize();

glDisable( GL_LIGHTING );

glDisable( GL_CULL_FACE );

glDisable( GL_DEPTH_TEST );

glPolygonMode( GL_FRONT, GL_FILL );

glEnable( GL_TEXTURE_2D );

glBindTexture( GL_TEXTURE_2D, _texID );

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

glEnable(GL_TEXTURE_GEN_S);

glEnable(GL_TEXTURE_GEN_T);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );

glMatrixMode( GL_TEXTURE );

{

glLoadIdentity();

glScalef( 1.0 / scale, 1.0f / scale, 1.0f );

glTranslatef( scale * 0.5f, scale * 0.5f, 0.0f );

}

glMatrixMode( GL_MODELVIEW );

/*

THIS CODE IS FOOBAR...

I'm trying to come up with plane offset to center the texture around closestProjection.

*/

float sOffset = sAxis.x * closestProjection.x + sAxis.y * closestProjection.x + sAxis.z * closestProjection.x;

float tOffset = tAxis.x * closestProjection.y + tAxis.y * closestProjection.y + tAxis.z * closestProjection.y;

glTexGenfv( GL_S, GL_OBJECT_PLANE, vec4( sAxis.x, sAxis.y, sAxis.z, -sOffset ).v );

glTexGenfv( GL_T, GL_OBJECT_PLANE, vec4( tAxis.x, tAxis.y, tAxis.z, -tOffset ).v );

As far as I can tell the *axes* are correct, e.g., a circle texture projected against a nearly vertical surface is correctly applied, as in it looks circular when the camera is along the normal vector of the surface. But, the trouble here is offsetting the translation in the texture matrix, or as I'm trying here offsetting along the fourth component of the plane equation, so the texture is centered around the chosen point in world space.

I may just have to buy "Game Programming Gems 2"... but any help from you guys would be appreciated.

Also, one more thing, this code is written to prototype the idea, not to be an example of efficiency! I'll make it fast *after* I get it working

I think the math is a little harder to work out if you want to scale the 2d texture coordinates directly.

(edit)

It also occured to me you could do this without using any GL_TEXTURE matrix operations at all since you essentially have an offset with the w coefficient in the plane equation. It may be easier to compute without involving any texture transformations.

That said, I'm still examining how exactly I am to calculate the w component.

So far, the best thing I can come up with is this. To get w, I need to know the position of the point "closestProjection" on the plane, in the plane's 2d coordinate system. That's the offset I need to get the texture to center correctly.

So, to calculate this, what I need to do is to figure out how to pack a matrix to un-transform an arbitrary plane ( a,b,c,d ) to, for example, the z plane ( 0,0,1,0 ). Then, I'd multiply "closestProjection" by that matrix, thereby putting it on z = 0. I could then use its x & y values as the w parameters for the GL_OBJECT_PLANE.

The issue then is how to come up with a matrix to untransform a plane. Does anybody here know how to do this? Or where I can find out how? I did some googling, but it turned up very little, except for a post on flipcode's forums but it was a little too ivory-tower and I couldn't wrap my soft, squishy brain around it.

TomorrowPlusX Wrote:So far, the best thing I can come up with is this. To get w, I need to know the position of the point "closestProjection" on the plane, in the plane's 2d coordinate system. That's the offset I need to get the texture to center correctly.

That's correct, but I think it's a lot easier than having to do anything particularly complicated with matrices. You just want to find the projection on the s-t plane, so you would just take the dot product of closestProjection and s-axis to find the offset for s, and the same for the t-axis.

Now, you still want to scale it and translate it, but I think the easiest way to do that is still work in the s/t coordinate frame. To scale, you'd simply scale the x,y,z coefficients of GL_OBJECT_PLANE, and then to translate to center, you'd just add -0.5 to the w coefficient. This should work because you should be subtracting half a unit in the s or t direction.

It works! Now, I've just got to clean it up, and add some special code to handle the exceptional circumstance that the origin is 0,0,0 ( everywhere else it works, correctly ). And then I'll pull out the texture matrix code, since it's overkill.

Then, of course I've got to make it generic... but that's easy.

Congrats- by the way, your game looks great so far.