# Decals?

Hello! I am trying to create a “decal” (textured quad) onto a surface in my OpenGL program. I am using Bullet Physics to create a ray that intersects a triangle and returns two 3d float vectors: an intersect position, and the intersected triangle’s normal. I’ve spent several hours researching and trying to figure out how to correctly orient my quad to the triangle’s surface and as far as I know I need a tangent and binormal, but the formulas I have found require U V coordinates, which I do not have, since the only returned values are a normal and position. I am looking for a formula to orient my quad from just a position and normal vector, preferably into a quaternion, unless there is an easier way using multitexturing or something else. Thanks!

What you need is called “projective texturing”.
The pre-GL2 way of doing this is by using the texture matrix.
http://developer.nvidia.com/object/Projective_Texture_Mapping.html

It is the same concept with vertex shaders, but doing the matrix calculations in the shader, useful if this change each frame for example.

You have:
position
normal_vector

You also need:
up_vector
right_vector

You may do (Pseudocode):
up_vector = (0.0, 1.0, 0.0)
right_vector = crossproduct(normal_vector, up_vector)
up_vector = crossproduct(normal_vector, right_vector)

The last line seems strange at first, but is to correct the up-vector. Together they form the local coordinate system of the polygon you hit (a matrix so to speak). If you now transform the decal-quad with this coordinate system and the given position you get your decal on top of the surface. To reduce flickering (z-fighting) make a little offset in the direction of the normal (position += normal_vector*0.1).

Oh, and when the imaginary up-vector and the normal-vector match (or are very close) the cross-product is invalid, then simply use another up-vector, like (1.0,0.0,0.0).

Yeah, but it’s a good idea to frustum cull tris outside of the projective texture’s frustum before texturing them projectively. Maybe you can give some hints as to how to do this in my other thread.

thanks for the post…i got the same problems…