From: havoc Date: Thu, 18 Aug 2005 18:48:30 +0000 (+0000) Subject: added r_smoothnormals_areaweighting cvar (default 1, suggested by Black as a better... X-Git-Tag: xonotic-v0.1.0preview~4640 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=44e0afe0554386593f659f4043f5d0b2ed2f9579;hp=760ae8779d3f4a93510bcad762fce16728631936 added r_smoothnormals_areaweighting cvar (default 1, suggested by Black as a better method, faster and shading looks a little more distinct on nexuiz player models) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5596 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_rmain.c b/gl_rmain.c index 276a6455..05dc0da6 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -105,6 +105,8 @@ cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "8"}; cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320"}; cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "4"}; +cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1"}; + cvar_t developer_texturelogging = {0, "developer_texturelogging", "0"}; cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"}; @@ -513,6 +515,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_bloom_blur); Cvar_RegisterVariable(&r_bloom_resolution); Cvar_RegisterVariable(&r_bloom_power); + Cvar_RegisterVariable(&r_smoothnormals_areaweighting); Cvar_RegisterVariable(&developer_texturelogging); Cvar_RegisterVariable(&gl_lightmaps); if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE) @@ -1527,7 +1530,7 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture rsurface_svector3f = varray_svector3f; rsurface_tvector3f = varray_tvector3f; rsurface_normal3f = varray_normal3f; - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f); + Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer); } // a single autosprite surface can contain multiple sprites... VectorClear(forward); @@ -1564,7 +1567,7 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture rsurface_svector3f = varray_svector3f; rsurface_tvector3f = varray_tvector3f; rsurface_normal3f = varray_normal3f; - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f); + Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer); } Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward); Matrix4x4_Transform(&ent->inversematrix, r_viewright, right); @@ -1609,7 +1612,7 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface if (rsurface_normal3f == NULL) { rsurface_normal3f = varray_normal3f; - Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f); + Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f, r_smoothnormals_areaweighting.integer); } R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, surface->groupmesh->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, rsurface_lightmapcolor4f + 4 * surface->num_firstvertex); r = 1; diff --git a/gl_rsurf.c b/gl_rsurf.c index 27f6d6db..898da1fb 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -785,7 +785,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, rsurface_svector3f = varray_svector3f; rsurface_tvector3f = varray_tvector3f; rsurface_normal3f = varray_normal3f; - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f); + Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer); } if (ent->colormap >= 0) { diff --git a/model_alias.c b/model_alias.c index e0b3fa34..ca95999c 100644 --- a/model_alias.c +++ b/model_alias.c @@ -177,7 +177,7 @@ static void Mod_Alias_Mesh_CompileFrameZero(surfmesh_t *mesh) mesh->data_tvector3f = mesh->data_vertex3f + mesh->num_vertices * 6; mesh->data_normal3f = mesh->data_vertex3f + mesh->num_vertices * 9; Mod_Alias_GetMesh_Vertex3f(loadmodel, frameblend, mesh, mesh->data_vertex3f); - Mod_BuildTextureVectorsAndNormals(0, mesh->num_vertices, mesh->num_triangles, mesh->data_vertex3f, mesh->data_texcoordtexture2f, mesh->data_element3i, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f); + Mod_BuildTextureVectorsAndNormals(0, mesh->num_vertices, mesh->num_triangles, mesh->data_vertex3f, mesh->data_texcoordtexture2f, mesh->data_element3i, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f, true); } static void Mod_MDLMD2MD3_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask) diff --git a/model_brush.c b/model_brush.c index a19020c1..0be4c0df 100644 --- a/model_brush.c +++ b/model_brush.c @@ -1895,7 +1895,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l) } // compile additional data about the surface geometry - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, surface->groupmesh->data_vertex3f, surface->groupmesh->data_texcoordtexture2f, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f); + Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, surface->groupmesh->data_vertex3f, surface->groupmesh->data_texcoordtexture2f, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f, true); BoxFromPoints(surface->mins, surface->maxs, surface->num_vertices, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex)); // generate surface extents information @@ -4427,7 +4427,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) Con_Print("\n"); } // for per pixel lighting - Mod_BuildTextureVectorsAndNormals(out->num_firstvertex, out->num_vertices, out->num_triangles, out->groupmesh->data_vertex3f, out->groupmesh->data_texcoordtexture2f, (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), out->groupmesh->data_svector3f, out->groupmesh->data_tvector3f, out->groupmesh->data_normal3f); + Mod_BuildTextureVectorsAndNormals(out->num_firstvertex, out->num_vertices, out->num_triangles, out->groupmesh->data_vertex3f, out->groupmesh->data_texcoordtexture2f, (out->groupmesh->data_element3i + 3 * out->num_firsttriangle), out->groupmesh->data_svector3f, out->groupmesh->data_tvector3f, out->groupmesh->data_normal3f, true); // calculate a bounding box VectorClear(out->mins); VectorClear(out->maxs); diff --git a/model_shared.c b/model_shared.c index fe81e7ff..4e77c52b 100644 --- a/model_shared.c +++ b/model_shared.c @@ -486,60 +486,51 @@ void Mod_ValidateElements(const int *elements, int numtriangles, int numverts, c } // warning: this is an expensive function! -void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f) +void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qboolean areaweighting) { - int i; + int i, j; const int *element; float *vectorNormal; + float areaNormal[3]; // clear the vectors memset(normal3f + 3 * firstvertex, 0, numvertices * sizeof(float[3])); // process each vertex of each triangle and accumulate the results // use area-averaging, to make triangles with a big area have a bigger // weighting on the vertex normal than triangles with a small area // to do so, just add the 'normals' together (the bigger the area - // the greater the length of the normal is + // the greater the length of the normal is element = elements; - for (i = 0; i < numtriangles; i++) + for (i = 0; i < numtriangles; i++, element += 3) { - float areaNormal[3]; - TriangleNormal( - vertex3f + element[0] * 3, - vertex3f + element[1] * 3, - vertex3f + element[2] * 3, + vertex3f + element[0] * 3, + vertex3f + element[1] * 3, + vertex3f + element[2] * 3, areaNormal ); - - vectorNormal = normal3f + element[0] * 3; - vectorNormal[0] += areaNormal[0]; - vectorNormal[1] += areaNormal[1]; - vectorNormal[2] += areaNormal[2]; - - vectorNormal = normal3f + element[1] * 3; - vectorNormal[0] += areaNormal[0]; - vectorNormal[1] += areaNormal[1]; - vectorNormal[2] += areaNormal[2]; - - vectorNormal = normal3f + element[2] * 3; - vectorNormal[0] += areaNormal[0]; - vectorNormal[1] += areaNormal[1]; - vectorNormal[2] += areaNormal[2]; - - element += 3; + + if (!areaweighting) + VectorNormalize(areaNormal); + + for (j = 0;j < 3;j++) + { + vectorNormal = normal3f + element[j] * 3; + vectorNormal[0] += areaNormal[0]; + vectorNormal[1] += areaNormal[1]; + vectorNormal[2] += areaNormal[2]; + } } // and just normalize the accumulated vertex normal in the end vectorNormal = normal3f + 3 * firstvertex; - for (i = 0; i < numvertices; i++) { + for (i = 0; i < numvertices; i++, vectorNormal += 3) VectorNormalize(vectorNormal); - vectorNormal += 3; - } } void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f) { float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2]; - // 103 add/sub/negate/multiply (1 cycle), 3 divide (20 cycle), 3 sqrt (22 cycle), 4 compare (3 cycle?), total cycles not counting load/store/exchange roughly 241 cycles - // 12 add, 28 subtract, 57 multiply, 3 divide, 3 sqrt, 4 compare, 50% chance of 6 negates + // 79 add/sub/negate/multiply (1 cycle), 1 compare (3 cycle?), total cycles not counting load/store/exchange roughly 82 cycles + // 6 add, 28 subtract, 39 multiply, 1 compare, 50% chance of 6 negates // 6 multiply, 9 subtract VectorSubtract(v1, v0, v10); @@ -547,8 +538,6 @@ void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, con normal3f[0] = v10[1] * v20[2] - v10[2] * v20[1]; normal3f[1] = v10[2] * v20[0] - v10[0] * v20[2]; normal3f[2] = v10[0] * v20[1] - v10[1] * v20[0]; - // 1 sqrt, 1 divide, 6 multiply, 2 add, 1 compare - VectorNormalize(normal3f); // 12 multiply, 10 subtract tc10[1] = tc1[1] - tc0[1]; tc20[1] = tc2[1] - tc0[1]; @@ -569,9 +558,6 @@ void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, con tvector3f[0] -= f * normal3f[0]; tvector3f[1] -= f * normal3f[1]; tvector3f[2] -= f * normal3f[2]; - // 2 sqrt, 2 divide, 12 multiply, 4 add, 2 compare - VectorNormalize(svector3f); - VectorNormalize(tvector3f); // if texture is mapped the wrong way (counterclockwise), the tangents // have to be flipped, this is detected by calculating a normal from the // two tangents, and seeing if it is opposite the surface normal @@ -585,7 +571,7 @@ void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, con } // warning: this is a very expensive function! -void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const int *elements, float *svector3f, float *tvector3f, float *normal3f) +void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const int *elements, float *svector3f, float *tvector3f, float *normal3f, qboolean areaweighting) { int i, tnum; float sdir[3], tdir[3], normal[3], *v; @@ -601,33 +587,21 @@ void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int num for (tnum = 0, e = elements;tnum < numtriangles;tnum++, e += 3) { Mod_BuildBumpVectors(vertex3f + e[0] * 3, vertex3f + e[1] * 3, vertex3f + e[2] * 3, texcoord2f + e[0] * 2, texcoord2f + e[1] * 2, texcoord2f + e[2] * 2, sdir, tdir, normal); - if (svector3f) + if (!areaweighting) { - for (i = 0;i < 3;i++) - { - svector3f[e[i]*3 ] += sdir[0]; - svector3f[e[i]*3+1] += sdir[1]; - svector3f[e[i]*3+2] += sdir[2]; - } + VectorNormalize(sdir); + VectorNormalize(tdir); + VectorNormalize(normal); } + if (svector3f) + for (i = 0;i < 3;i++) + VectorAdd(svector3f + e[i]*3, sdir, svector3f + e[i]*3); if (tvector3f) - { for (i = 0;i < 3;i++) - { - tvector3f[e[i]*3 ] += tdir[0]; - tvector3f[e[i]*3+1] += tdir[1]; - tvector3f[e[i]*3+2] += tdir[2]; - } - } + VectorAdd(tvector3f + e[i]*3, tdir, tvector3f + e[i]*3); if (normal3f) - { for (i = 0;i < 3;i++) - { - normal3f[e[i]*3 ] += normal[0]; - normal3f[e[i]*3+1] += normal[1]; - normal3f[e[i]*3+2] += normal[2]; - } - } + VectorAdd(normal3f + e[i]*3, normal, normal3f + e[i]*3); } // now we could divide the vectors by the number of averaged values on // each vertex... but instead normalize them diff --git a/model_shared.h b/model_shared.h index 0bc49935..eaed415f 100644 --- a/model_shared.h +++ b/model_shared.h @@ -560,8 +560,8 @@ extern char loadname[32]; // for hunk tags int Mod_BuildVertexRemapTableFromElements(int numelements, const int *elements, int numvertices, int *remapvertices); void Mod_BuildTriangleNeighbors(int *neighbors, const int *elements, int numtriangles); void Mod_ValidateElements(const int *elements, int numtriangles, int numverts, const char *filename, int fileline); -void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f); -void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex, const float *texcoord, const int *elements, float *svectors, float *tvectors, float *normals); +void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qboolean areaweighting); +void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex, const float *texcoord, const int *elements, float *svectors, float *tvectors, float *normals, qboolean areaweighting); surfmesh_t *Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean detailtexcoords, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors); diff --git a/render.h b/render.h index 0973f84d..689ba438 100644 --- a/render.h +++ b/render.h @@ -196,6 +196,8 @@ extern cvar_t r_textureunits; extern cvar_t gl_polyblend; extern cvar_t gl_dither; +extern cvar_t r_smoothnormals_areaweighting; + #include "gl_backend.h" #include "r_light.h"