Properly invert the tangent space matrix instead of transposing it (after all, model tangent space isn't guaranteed to be orthogonal) and do so offline. This removes a little strain from the GPU.

git-svn-id: https://svn.eduke32.com/eduke32@1591 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
plagman 2010-01-21 05:52:19 +00:00
parent 11c9195317
commit f3802b7897
2 changed files with 59 additions and 60 deletions

View file

@ -209,9 +209,7 @@ typedef struct s_prplane {
int32_t vertcount; int32_t vertcount;
GLuint vbo; GLuint vbo;
// attributes // attributes
GLfloat t[3]; GLfloat tbn[9];
GLfloat b[3];
GLfloat n[3];
GLfloat plane[4]; GLfloat plane[4];
_prmaterial material; _prmaterial material;
// elements // elements
@ -330,6 +328,8 @@ static void polymer_drawwall(int16_t sectnum, int16_t wallnum);
static void polymer_computeplane(_prplane* p); static void polymer_computeplane(_prplane* p);
static inline void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out); static inline void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out);
static inline void polymer_transformpoint(float* inpos, float* pos, float* matrix); static inline void polymer_transformpoint(float* inpos, float* pos, float* matrix);
static inline void polymer_invertmatrix(float* m, float* out);
static inline void polymer_normalize(float* vec);
static inline void polymer_pokesector(int16_t sectnum); static inline void polymer_pokesector(int16_t sectnum);
static void polymer_extractfrustum(GLfloat* modelview, GLfloat* projection, float* frustum); static void polymer_extractfrustum(GLfloat* modelview, GLfloat* projection, float* frustum);
static inline int32_t polymer_planeinfrustum(_prplane *plane, float* frustum); static inline int32_t polymer_planeinfrustum(_prplane *plane, float* frustum);

View file

@ -216,7 +216,7 @@ _prprogrambit prprogrambits[PR_BIT_COUNT] = {
"varying vec3 tangentSpaceEyeVec;\n" "varying vec3 tangentSpaceEyeVec;\n"
"\n", "\n",
// vert_prog // vert_prog
" TBN = transpose(mat3(T, B, N));\n" " TBN = mat3(T, B, N);\n"
" tangentSpaceEyeVec = eyePosition - vec3(curVertex);\n" " tangentSpaceEyeVec = eyePosition - vec3(curVertex);\n"
" tangentSpaceEyeVec = TBN * tangentSpaceEyeVec;\n" " tangentSpaceEyeVec = TBN * tangentSpaceEyeVec;\n"
"\n" "\n"
@ -1706,9 +1706,9 @@ static void polymer_drawplane(_prplane* plane)
if (materialbits & prprogrambits[PR_BIT_NORMAL_MAP].bit) if (materialbits & prprogrambits[PR_BIT_NORMAL_MAP].bit)
{ {
bglVertexAttrib3fvARB(prprograms[materialbits].attrib_T, plane->t); bglVertexAttrib3fvARB(prprograms[materialbits].attrib_T, &plane->tbn[0]);
bglVertexAttrib3fvARB(prprograms[materialbits].attrib_B, plane->b); bglVertexAttrib3fvARB(prprograms[materialbits].attrib_B, &plane->tbn[3]);
bglVertexAttrib3fvARB(prprograms[materialbits].attrib_N, plane->plane); bglVertexAttrib3fvARB(prprograms[materialbits].attrib_N, &plane->tbn[6]);
} }
if (plane->indices) if (plane->indices)
@ -2875,18 +2875,12 @@ static void polymer_computeplane(_prplane* p)
GLfloat vec1[5], vec2[5], norm, r;// BxN[3], NxT[3], TxB[3]; GLfloat vec1[5], vec2[5], norm, r;// BxN[3], NxT[3], TxB[3];
int32_t i; int32_t i;
GLfloat* buffer; GLfloat* buffer;
GLfloat* t;
GLfloat* b;
GLfloat* n;
GLfloat* plane; GLfloat* plane;
if (p->indices && (p->indicescount < 3)) if (p->indices && (p->indicescount < 3))
return; // corrupt sector (E3L4, I'm looking at you) return; // corrupt sector (E3L4, I'm looking at you)
buffer = p->buffer; buffer = p->buffer;
t = p->t;
b = p->b;
n = p->n;
plane = p->plane; plane = p->plane;
i = 0; i = 0;
@ -2911,6 +2905,8 @@ static void polymer_computeplane(_prplane* p)
// hack to work around a precision issue with slopes // hack to work around a precision issue with slopes
if (norm >= 15000) if (norm >= 15000)
{ {
float tangent[9];
// normalize the normal/plane equation and calculate its plane norm // normalize the normal/plane equation and calculate its plane norm
norm = -sqrt(norm); norm = -sqrt(norm);
norm = 1.0 / norm; norm = 1.0 / norm;
@ -2923,58 +2919,25 @@ static void polymer_computeplane(_prplane* p)
r = 1.0 / (vec1[3] * vec2[4] - vec2[3] * vec1[4]); r = 1.0 / (vec1[3] * vec2[4] - vec2[3] * vec1[4]);
// tangent // tangent
t[0] = (vec2[4] * vec1[0] - vec1[4] * vec2[0]) * r; tangent[0] = (vec2[4] * vec1[0] - vec1[4] * vec2[0]) * r;
t[1] = (vec2[4] * vec1[1] - vec1[4] * vec2[1]) * r; tangent[1] = (vec2[4] * vec1[1] - vec1[4] * vec2[1]) * r;
t[2] = (vec2[4] * vec1[2] - vec1[4] * vec2[2]) * r; tangent[2] = (vec2[4] * vec1[2] - vec1[4] * vec2[2]) * r;
polymer_normalize(&tangent[0]);
// bitangent // bitangent
b[0] = (vec1[3] * vec2[0] - vec2[3] * vec1[0]) * r; tangent[3] = (vec1[3] * vec2[0] - vec2[3] * vec1[0]) * r;
b[1] = (vec1[3] * vec2[1] - vec2[3] * vec1[1]) * r; tangent[4] = (vec1[3] * vec2[1] - vec2[3] * vec1[1]) * r;
b[2] = (vec1[3] * vec2[2] - vec2[3] * vec1[2]) * r; tangent[5] = (vec1[3] * vec2[2] - vec2[3] * vec1[2]) * r;
// // invert T, B and N polymer_normalize(&tangent[3]);
// r = 1.0f / ((t[0] * b[1] * plane[2] - t[2] * b[1] * plane[0]) +
// (b[0] * plane[1] * t[2] - b[2] * plane[1] * t[0]) +
// (plane[0] * t[1] * b[2] - plane[2] * t[1] * b[0]));
//
// polymer_crossproduct(b, plane, BxN);
// polymer_crossproduct(plane, t, NxT);
// polymer_crossproduct(t, b, TxB);
//
// // GLSL matrix constructors are in column-major order
// t[0] = BxN[0] * r;
// t[1] = -NxT[0] * r;
// t[2] = TxB[0] * r;
//
// b[0] = -BxN[1] * r;
// b[1] = NxT[1] * r;
// b[2] = -TxB[1] * r;
//
// n[0] = BxN[2] * r;
// n[1] = -NxT[2] * r;
// n[2] = TxB[2] * r;
// normalize T, B and N // normal
norm = t[0] * t[0] + t[1] * t[1] + t[2] * t[2]; tangent[6] = plane[0];
norm = sqrt(norm); tangent[7] = plane[1];
norm = 1.0 / norm; tangent[8] = plane[2];
t[0] *= norm;
t[1] *= norm;
t[2] *= norm;
norm = b[0] * b[0] + b[1] * b[1] + b[2] * b[2]; polymer_invertmatrix(tangent, p->tbn);
norm = sqrt(norm);
norm = 1.0 / norm;
b[0] *= norm;
b[1] *= norm;
b[2] *= norm;
norm = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
norm = sqrt(norm);
norm = 1.0 / norm;
n[0] *= norm;
n[1] *= norm;
n[2] *= norm;
break; break;
} }
@ -3007,6 +2970,42 @@ static inline void polymer_transformpoint(float* inpos, float* pos, float* matr
+ matrix[14]; + matrix[14];
} }
static inline void polymer_invertmatrix(float* m, float* out)
{
float det;
det = m[0] * (m[4]*m[8] - m[5] * m[7]);
det -= m[1] * (m[3]*m[8] - m[5] * m[6]);
det += m[2] * (m[3]*m[7] - m[4] * m[6]);
det = 1.0f / det;
out[0] = det * (m[4] * m[8] - m[5] * m[7]);
out[3] = det * (m[5] * m[6] - m[3] * m[8]);
out[6] = det * (m[3] * m[7] - m[1] * m[6]);
out[1] = det * (m[2] * m[7] - m[1] * m[8]);
out[4] = det * (m[0] * m[8] - m[2] * m[6]);
out[7] = det * (m[1] * m[6] - m[0] * m[7]);
out[2] = det * (m[1] * m[5] - m[2] * m[4]);
out[5] = det * (m[2] * m[3] - m[0] * m[5]);
out[8] = det * (m[0] * m[4] - m[1] * m[3]);
}
static inline void polymer_normalize(float* vec)
{
double norm;
norm = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2];
norm = sqrt(norm);
norm = 1.0 / norm;
vec[0] *= norm;
vec[1] *= norm;
vec[2] *= norm;
}
static inline void polymer_pokesector(int16_t sectnum) static inline void polymer_pokesector(int16_t sectnum)
{ {
sectortype *sec = &sector[sectnum]; sectortype *sec = &sector[sectnum];