renders: use dot product of shadevector and normal directly

This commit is contained in:
Denis Pauk 2024-06-04 18:58:45 +03:00
parent a9219192e0
commit 88bb466f1e
4 changed files with 70 additions and 81 deletions

View file

@ -27,20 +27,15 @@
#include "header/local.h"
#define NUMVERTEXNORMALS 162
#define SHADEDOT_QUANT 16
/* precalculated dot products for quantized angles */
static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
#include "../constants/anormtab.h"
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
vec3_t shadevector;
float shadelight[3];
float *shadedots = r_avertexnormal_dots[0];
static void
R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *order_end,
float alpha, dxtrivertx_t *verts, vec4_t *s_lerped)
float alpha, dxtrivertx_t *verts, vec4_t *s_lerped, const float *shadelight,
const float *shadevector)
{
#ifdef _MSC_VER // workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops)
int maxCount = 0;
@ -129,6 +124,7 @@ R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *or
do
{
int index_xyz;
const float *norm;
float l;
/* texture coordinates come from the draw list */
@ -139,7 +135,9 @@ R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *or
order += 3;
/* normals and vertexes come from the frame list */
l = shadedots[verts[index_xyz].lightnormalindex];
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
clr[index_clr++] = l * shadelight[0];
clr[index_clr++] = l * shadelight[1];
@ -177,7 +175,7 @@ R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *or
*/
static void
R_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp,
vec4_t *s_lerped)
vec4_t *s_lerped, const float *shadelight, const float *shadevector)
{
daliasxframe_t *frame, *oldframe;
const dxtrivertx_t *ov;
@ -241,7 +239,8 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp,
lerp = s_lerped[0];
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, move, frontv, backv);
R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp,
move, frontv, backv);
num_mesh_nodes = paliashdr->num_meshes;
mesh_nodes = (dmdxmesh_t *)((char*)paliashdr + paliashdr->ofs_meshes);
@ -252,7 +251,7 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp,
order + mesh_nodes[i].ofs_glcmds,
order + Q_min(paliashdr->num_glcmds,
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
alpha, verts, s_lerped);
alpha, verts, s_lerped, shadelight, shadevector);
}
if (colorOnly)
@ -263,7 +262,7 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp,
static void
R_DrawAliasShadowCommand(const entity_t *currententity, int *order, const int *order_end,
float height, float lheight, vec4_t *s_lerped)
float height, float lheight, vec4_t *s_lerped, const float *shadevector)
{
unsigned short total;
vec3_t point;
@ -346,7 +345,7 @@ R_DrawAliasShadowCommand(const entity_t *currententity, int *order, const int *o
static void
R_DrawAliasShadow(entity_t *currententity, dmdx_t *paliashdr, int posenum,
vec4_t *s_lerped)
vec4_t *s_lerped, vec3_t shadevector)
{
int *order, i, num_mesh_nodes;
float height = 0, lheight;
@ -373,7 +372,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdx_t *paliashdr, int posenum,
order + mesh_nodes[i].ofs_glcmds,
order + Q_min(paliashdr->num_glcmds,
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
height, lheight, s_lerped);
height, lheight, s_lerped, shadevector);
}
/* stencilbuffer shadows */
@ -418,10 +417,11 @@ void
R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
{
int i;
dmdx_t *paliashdr;
float an;
vec3_t bbox[8];
const image_t *skin = NULL;
vec3_t bbox[8];
vec3_t shadevector, shadelight;
dmdx_t *paliashdr;
vec4_t *s_lerped;
if (!(currententity->flags & RF_WEAPONMODEL))
@ -585,9 +585,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
shadelight[2] = 0.0;
}
shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] *
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
an = currententity->angles[1] / 180 * M_PI;
shadevector[0] = cos(-an);
shadevector[1] = sin(-an);
@ -703,7 +700,7 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
s_lerped = R_VertBufferRealloc(paliashdr->num_xyz);
R_DrawAliasFrameLerp(currententity, paliashdr, currententity->backlerp,
s_lerped);
s_lerped, shadelight, shadevector);
R_TexEnv(GL_REPLACE);
glShadeModel(GL_FLAT);
@ -760,7 +757,7 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
glEnable(GL_BLEND);
glColor4f(0, 0, 0, 0.5f);
R_DrawAliasShadow(currententity, paliashdr, currententity->frame,
s_lerped);
s_lerped, shadevector);
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glPopMatrix();

View file

@ -30,11 +30,9 @@
#include "../files/DG_dynarr.h"
#define NUMVERTEXNORMALS 162
#define SHADEDOT_QUANT 16
/* precalculated dot products for quantized angles */
static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
#include "../constants/anormtab.h"
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
typedef struct gl3_shadowinfo_s {
@ -66,8 +64,8 @@ GL3_ShutdownMeshes(void)
static void
DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
int *order, int *order_end, float* shadedots, float alpha, qboolean colorOnly,
dxtrivertx_t *verts, vec4_t *s_lerped)
int *order, int *order_end, float alpha, qboolean colorOnly,
dxtrivertx_t *verts, vec4_t *s_lerped, const float *shadevector)
{
// all the triangle fans and triangle strips of this model will be converted to
// just triangles: the vertices stay the same and are batched in vtxBuf,
@ -132,6 +130,7 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
for(i=0; i<count; ++i)
{
gl3_alias_vtx_t* cur = &buf[i];
const float *norm;
int index_xyz;
int j = 0;
float l;
@ -145,9 +144,9 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
order += 3;
/* normals and vertexes come from the frame list */
// shadedots is set above according to rotation (around Z axis I think)
// to one of 16 (SHADEDOT_QUANT) presets in r_avertexnormal_dots
l = shadedots[verts[index_xyz].lightnormalindex];
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
for(j=0; j<3; ++j)
{
@ -213,7 +212,8 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
* Interpolates between two frames and origins
*/
static void
DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight)
DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
const float *shadevector)
{
daliasxframe_t *frame, *oldframe;
dxtrivertx_t *ov, *verts;
@ -234,10 +234,6 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight)
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE |
RF_SHELL_HALF_DAM));
// TODO: maybe we could somehow store the non-rotated normal and do the dot in shader?
float* shadedots = r_avertexnormal_dots[((int)(entity->angles[1] *
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
frame = (daliasxframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
+ entity->frame * paliashdr->framesize);
verts = frame->verts;
@ -308,12 +304,12 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight)
order + mesh_nodes[i].ofs_glcmds,
order + Q_min(paliashdr->num_glcmds,
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
shadedots, alpha, colorOnly, verts, s_lerped);
alpha, colorOnly, verts, s_lerped, shadevector);
}
}
static void
DrawAliasShadowCommands(int *order, int *order_end, vec3_t shadevector,
DrawAliasShadowCommands(int *order, int *order_end, const float *shadevector,
float height, float lheight, vec4_t *s_lerped)
{
// GL1 uses alpha 0.5, but in GL3 0.3 looks better
@ -606,8 +602,8 @@ GL3_DrawAliasModel(entity_t *entity)
else
{
R_LightPoint(gl3_worldmodel->grid, entity, &gl3_newrefdef,
gl3_worldmodel->surfaces, gl3_worldmodel->nodes, entity->origin,
shadelight, r_modulate->value, lightspot);
gl3_worldmodel->surfaces, gl3_worldmodel->nodes,
entity->origin, shadelight, r_modulate->value, lightspot);
}
/* player lighting hack for communication back to server */
@ -796,7 +792,7 @@ GL3_DrawAliasModel(entity_t *entity)
entity->oldframe = 0;
}
DrawAliasFrameLerp(paliashdr, entity, shadelight);
DrawAliasFrameLerp(paliashdr, entity, shadelight, shadevector);
//glPopMatrix();
gl3state.uni3DData.transModelMat4 = origModelMat;

View file

@ -30,11 +30,9 @@
#include "../files/DG_dynarr.h"
#define NUMVERTEXNORMALS 162
#define SHADEDOT_QUANT 16
/* precalculated dot products for quantized angles */
static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
#include "../constants/anormtab.h"
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
typedef struct gl4_shadowinfo_s {
@ -66,8 +64,8 @@ GL4_ShutdownMeshes(void)
static void
DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
int *order, int *order_end, float* shadedots, float alpha, qboolean colorOnly,
dxtrivertx_t *verts, vec4_t *s_lerped)
int *order, int *order_end, float alpha, qboolean colorOnly,
dxtrivertx_t *verts, vec4_t *s_lerped, const float *shadevector)
{
// all the triangle fans and triangle strips of this model will be converted to
// just triangles: the vertices stay the same and are batched in vtxBuf,
@ -132,6 +130,7 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
for(i=0; i<count; ++i)
{
gl4_alias_vtx_t* cur = &buf[i];
const float *norm;
int index_xyz;
int j = 0;
float l;
@ -145,9 +144,9 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
order += 3;
/* normals and vertexes come from the frame list */
// shadedots is set above according to rotation (around Z axis I think)
// to one of 16 (SHADEDOT_QUANT) presets in r_avertexnormal_dots
l = shadedots[verts[index_xyz].lightnormalindex];
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
for(j=0; j<3; ++j)
{
@ -213,7 +212,8 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
* Interpolates between two frames and origins
*/
static void
DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight)
DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight,
const float *shadevector)
{
daliasxframe_t *frame, *oldframe;
dxtrivertx_t *ov, *verts;
@ -234,10 +234,6 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight)
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE |
RF_SHELL_HALF_DAM));
// TODO: maybe we could somehow store the non-rotated normal and do the dot in shader?
float* shadedots = r_avertexnormal_dots[((int)(entity->angles[1] *
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
frame = (daliasxframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
+ entity->frame * paliashdr->framesize);
verts = frame->verts;
@ -308,12 +304,12 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight)
order + mesh_nodes[i].ofs_glcmds,
order + Q_min(paliashdr->num_glcmds,
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
shadedots, alpha, colorOnly, verts, s_lerped);
alpha, colorOnly, verts, s_lerped, shadevector);
}
}
static void
DrawAliasShadowCommands(int *order, int *order_end, vec3_t shadevector,
DrawAliasShadowCommands(int *order, int *order_end, const float *shadevector,
float height, float lheight, vec4_t *s_lerped)
{
// GL1 uses alpha 0.5, but in GL4 0.6 looks better and more true to vanilla
@ -796,7 +792,7 @@ GL4_DrawAliasModel(entity_t *entity)
entity->oldframe = 0;
}
DrawAliasFrameLerp(paliashdr, entity, shadelight);
DrawAliasFrameLerp(paliashdr, entity, shadelight, shadevector);
//glPopMatrix();
gl4state.uni3DData.transModelMat4 = origModelMat;
@ -832,12 +828,14 @@ GL4_DrawAliasModel(entity_t *entity)
}
}
void GL4_ResetShadowAliasModels(void)
void
GL4_ResetShadowAliasModels(void)
{
da_clear(shadowModels);
}
void GL4_DrawAliasShadows(void)
void
GL4_DrawAliasShadows(void)
{
size_t numShadowModels = da_count(shadowModels);
if(numShadowModels == 0)

View file

@ -28,7 +28,6 @@
#include "header/local.h"
#define NUMVERTEXNORMALS 162
#define SHADEDOT_QUANT 16
enum {
TRIANGLE_STRIP = 0,
@ -52,15 +51,10 @@ static modelvert *vertList[2] = {NULL, NULL};
static vec3_t *shadowverts = NULL;
static int verts_count = 0;
/* precalculated dot products for quantized angles */
static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
#include "../constants/anormtab.h"
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
vec3_t shadevector;
float shadelight[3];
float *shadedots = r_avertexnormal_dots[0];
// correction matrix with "hacked depth" for models with RF_DEPTHHACK flag set
static float r_vulkan_correction_dh[16] = {
1.f, 0.f, 0.f, 0.f,
@ -200,9 +194,10 @@ Mesh_Free(void)
}
static void
Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_end,
Vk_DrawAliasFrameLerpCommands(entity_t *currententity, int *order, int *order_end,
float alpha, image_t *skin, float *modelMatrix, int leftHandOffset, int translucentIdx,
dxtrivertx_t *verts, vec4_t *s_lerped, int verts_count)
dxtrivertx_t *verts, vec4_t *s_lerped, int verts_count, const float *shadelight,
const float *shadevector)
{
int vertCounts[2] = { 0, 0 };
int pipeCounters[2] = { 0, 0 };
@ -295,6 +290,7 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e
{
int vertIdx = vertCounts[pipelineIdx];
int index_xyz = order[2];
const float *norm;
float l;
if (Mesh_VertsRealloc(vertIdx))
@ -306,8 +302,10 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e
vertList[pipelineIdx][vertIdx].texCoord[0] = ((float *)order)[0];
vertList[pipelineIdx][vertIdx].texCoord[1] = ((float *)order)[1];
// normals and vertexes come from the frame list
l = shadedots[verts[index_xyz].lightnormalindex];
/* normals and vertexes come from the frame list */
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
vertList[pipelineIdx][vertIdx].color[0] = l * shadelight[0];
vertList[pipelineIdx][vertIdx].color[1] = l * shadelight[1];
@ -400,7 +398,8 @@ FIXME: batch lerp all vertexes
*/
static void
Vk_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp, image_t *skin,
float *modelMatrix, int leftHandOffset, int translucentIdx, vec4_t *s_lerped)
float *modelMatrix, int leftHandOffset, int translucentIdx, vec4_t *s_lerped,
const float *shadelight, const float *shadevector)
{
daliasxframe_t *frame, *oldframe;
dxtrivertx_t *ov, *verts;
@ -469,13 +468,14 @@ Vk_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
alpha, skin,
modelMatrix, leftHandOffset, translucentIdx, verts,
s_lerped, paliashdr->num_xyz);
s_lerped, paliashdr->num_xyz, shadelight, shadevector);
}
}
static void
Vk_DrawAliasShadow(int *order, int *order_end, int posenum,
float *modelMatrix, entity_t *currententity, vec4_t *s_lerped)
float *modelMatrix, entity_t *currententity, vec4_t *s_lerped,
const float *shadevector)
{
vec3_t point;
float height, lheight;
@ -603,6 +603,7 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
{
int leftHandOffset = 0, i;
float prev_viewproj[16], an;
vec3_t shadevector, shadelight;
dmdx_t *paliashdr;
vec4_t *s_lerped;
@ -759,9 +760,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
shadelight[2] = 0.0;
}
shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] *
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
an = currententity->angles[1] / 180 * M_PI;
shadevector[0] = cos(-an);
shadevector[1] = sin(-an);
@ -861,7 +859,7 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
Vk_DrawAliasFrameLerp(currententity, paliashdr, currententity->backlerp,
skin, model, leftHandOffset, (currententity->flags & RF_TRANSLUCENT) ? 1 : 0,
s_lerped);
s_lerped, shadelight, shadevector);
}
if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
@ -898,7 +896,7 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
order + Q_min(paliashdr->num_glcmds,
mesh_nodes[i].ofs_glcmds + mesh_nodes[i].num_glcmds),
currententity->frame, model, currententity,
s_lerped);
s_lerped, shadevector);
}
}
}