mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Starting sunlight experimentation branch
This commit is contained in:
parent
ed87774a77
commit
974b938f8f
5 changed files with 210 additions and 4 deletions
|
@ -3350,6 +3350,192 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
// determine vertex light directions
|
||||
R_CalcVertexLightDirs();
|
||||
|
||||
// determine which parts of the map are in sunlight
|
||||
if (0)
|
||||
{
|
||||
world_t *w;
|
||||
|
||||
w = &s_worldData;
|
||||
uint8_t *primaryLightGrid, *data;
|
||||
int lightGridSize;
|
||||
int i;
|
||||
|
||||
lightGridSize = w->lightGridBounds[0] * w->lightGridBounds[1] * w->lightGridBounds[2];
|
||||
primaryLightGrid = ri.Malloc(lightGridSize * sizeof(*primaryLightGrid));
|
||||
|
||||
memset(primaryLightGrid, 0, lightGridSize * sizeof(*primaryLightGrid));
|
||||
|
||||
data = w->lightGridData;
|
||||
for (i = 0; i < lightGridSize; i++, data += 8)
|
||||
{
|
||||
int lat, lng;
|
||||
vec3_t gridLightDir, gridLightCol;
|
||||
|
||||
// skip samples in wall
|
||||
if (!(data[0]+data[1]+data[2]+data[3]+data[4]+data[5]) )
|
||||
continue;
|
||||
|
||||
gridLightCol[0] = ByteToFloat(data[3]);
|
||||
gridLightCol[1] = ByteToFloat(data[4]);
|
||||
gridLightCol[2] = ByteToFloat(data[5]);
|
||||
|
||||
lat = data[7];
|
||||
lng = data[6];
|
||||
lat *= (FUNCTABLE_SIZE/256);
|
||||
lng *= (FUNCTABLE_SIZE/256);
|
||||
|
||||
// decode X as cos( lat ) * sin( long )
|
||||
// decode Y as sin( lat ) * sin( long )
|
||||
// decode Z as cos( long )
|
||||
|
||||
gridLightDir[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
|
||||
gridLightDir[1] = tr.sinTable[lat] * tr.sinTable[lng];
|
||||
gridLightDir[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
|
||||
|
||||
// FIXME: magic number for determining if light direction is close enough to sunlight
|
||||
if (DotProduct(gridLightDir, tr.sunDirection) > 0.75f)
|
||||
{
|
||||
primaryLightGrid[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
primaryLightGrid[i] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
int i;
|
||||
byte *buffer = ri.Malloc(w->lightGridBounds[0] * w->lightGridBounds[1] * 3 + 18);
|
||||
byte *out;
|
||||
uint8_t *in;
|
||||
char fileName[MAX_QPATH];
|
||||
|
||||
Com_Memset (buffer, 0, 18);
|
||||
buffer[2] = 2; // uncompressed type
|
||||
buffer[12] = w->lightGridBounds[0] & 255;
|
||||
buffer[13] = w->lightGridBounds[0] >> 8;
|
||||
buffer[14] = w->lightGridBounds[1] & 255;
|
||||
buffer[15] = w->lightGridBounds[1] >> 8;
|
||||
buffer[16] = 24; // pixel size
|
||||
|
||||
in = primaryLightGrid;
|
||||
for (i = 0; i < w->lightGridBounds[2]; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
sprintf(fileName, "primarylg%d.tga", i);
|
||||
|
||||
out = buffer + 18;
|
||||
for (j = 0; j < w->lightGridBounds[0] * w->lightGridBounds[1]; j++)
|
||||
{
|
||||
if (*in == 1)
|
||||
{
|
||||
*out++ = 255;
|
||||
*out++ = 255;
|
||||
*out++ = 255;
|
||||
}
|
||||
else if (*in == 255)
|
||||
{
|
||||
*out++ = 64;
|
||||
*out++ = 64;
|
||||
*out++ = 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = 0;
|
||||
*out++ = 0;
|
||||
*out++ = 0;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
ri.FS_WriteFile(fileName, buffer, w->lightGridBounds[0] * w->lightGridBounds[1] * 3 + 18);
|
||||
}
|
||||
|
||||
ri.Free(buffer);
|
||||
}
|
||||
|
||||
for (i = 0; i < w->numWorldSurfaces; i++)
|
||||
{
|
||||
msurface_t *surf = w->surfaces + i;
|
||||
cullinfo_t *ci = &surf->cullinfo;
|
||||
|
||||
if(ci->type & CULLINFO_PLANE)
|
||||
{
|
||||
if (DotProduct(ci->plane.normal, tr.sunDirection) <= 0.0f)
|
||||
{
|
||||
//ri.Printf(PRINT_ALL, "surface %d is not oriented towards sunlight\n", i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(ci->type & CULLINFO_BOX)
|
||||
{
|
||||
int ibounds[2][3], x, y, z, goodSamples, numSamples;
|
||||
vec3_t lightOrigin;
|
||||
|
||||
VectorSubtract( ci->bounds[0], w->lightGridOrigin, lightOrigin );
|
||||
|
||||
ibounds[0][0] = floor(lightOrigin[0] * w->lightGridInverseSize[0]);
|
||||
ibounds[0][1] = floor(lightOrigin[1] * w->lightGridInverseSize[1]);
|
||||
ibounds[0][2] = floor(lightOrigin[2] * w->lightGridInverseSize[2]);
|
||||
|
||||
VectorSubtract( ci->bounds[1], w->lightGridOrigin, lightOrigin );
|
||||
|
||||
ibounds[1][0] = ceil(lightOrigin[0] * w->lightGridInverseSize[0]);
|
||||
ibounds[1][1] = ceil(lightOrigin[1] * w->lightGridInverseSize[1]);
|
||||
ibounds[1][2] = ceil(lightOrigin[2] * w->lightGridInverseSize[2]);
|
||||
|
||||
ibounds[0][0] = CLAMP(ibounds[0][0], 0, w->lightGridSize[0]);
|
||||
ibounds[0][1] = CLAMP(ibounds[0][1], 0, w->lightGridSize[1]);
|
||||
ibounds[0][2] = CLAMP(ibounds[0][2], 0, w->lightGridSize[2]);
|
||||
|
||||
ibounds[1][0] = CLAMP(ibounds[1][0], 0, w->lightGridSize[0]);
|
||||
ibounds[1][1] = CLAMP(ibounds[1][1], 0, w->lightGridSize[1]);
|
||||
ibounds[1][2] = CLAMP(ibounds[1][2], 0, w->lightGridSize[2]);
|
||||
|
||||
/*
|
||||
ri.Printf(PRINT_ALL, "surf %d bounds (%f %f %f)-(%f %f %f) ibounds (%d %d %d)-(%d %d %d)\n", i,
|
||||
ci->bounds[0][0], ci->bounds[0][1], ci->bounds[0][2],
|
||||
ci->bounds[1][0], ci->bounds[1][1], ci->bounds[1][2],
|
||||
ibounds[0][0], ibounds[0][1], ibounds[0][2],
|
||||
ibounds[1][0], ibounds[1][1], ibounds[1][2]);
|
||||
*/
|
||||
|
||||
goodSamples = 0;
|
||||
numSamples = 0;
|
||||
for (x = ibounds[0][0]; x <= ibounds[1][0]; x++)
|
||||
{
|
||||
for (y = ibounds[0][1]; y <= ibounds[1][1]; y++)
|
||||
{
|
||||
for (z = ibounds[0][2]; z <= ibounds[1][2]; z++)
|
||||
{
|
||||
uint8_t primaryLight = primaryLightGrid[x * 8 + y * 8 * w->lightGridBounds[0] + z * 8 * w->lightGridBounds[0] * w->lightGridBounds[2]];
|
||||
|
||||
if (primaryLight == 0)
|
||||
continue;
|
||||
|
||||
numSamples++;
|
||||
|
||||
if (primaryLight == 1)
|
||||
goodSamples++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: magic number for determining whether object is mostly in sunlight
|
||||
if (goodSamples > numSamples * 0.75f)
|
||||
{
|
||||
//ri.Printf(PRINT_ALL, "surface %d is in sunlight\n", i);
|
||||
//surf->primaryLight = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ri.Free(primaryLightGrid);
|
||||
}
|
||||
|
||||
// create static VBOS from the world
|
||||
R_CreateWorldVBO();
|
||||
if (r_mergeLeafSurfaces->integer)
|
||||
|
|
|
@ -1047,7 +1047,8 @@ void GLSL_InitGPUShaders(void)
|
|||
if (!(i & LIGHTDEF_USE_NORMALMAP) && (i & LIGHTDEF_USE_PARALLAXMAP))
|
||||
continue;
|
||||
|
||||
if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHT_VECTOR))
|
||||
//if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHT_VECTOR))
|
||||
if (!(i & LIGHTDEF_LIGHTTYPE_MASK))
|
||||
{
|
||||
if (i & LIGHTDEF_USE_SHADOWMAP)
|
||||
continue;
|
||||
|
|
|
@ -441,7 +441,11 @@ int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *w
|
|||
Com_Memset(&ent, 0, sizeof(ent));
|
||||
VectorCopy( point, ent.e.origin );
|
||||
R_SetupEntityLightingGrid( &ent, world );
|
||||
VectorCopy(ent.lightDir, lightDir);
|
||||
|
||||
if (DotProduct(ent.lightDir, normal) > 0.2f)
|
||||
VectorCopy(ent.lightDir, lightDir);
|
||||
else
|
||||
VectorCopy(normal, lightDir);
|
||||
|
||||
return qtrue;
|
||||
}
|
|
@ -407,12 +407,12 @@ enum
|
|||
TB_DIFFUSEMAP = 0,
|
||||
TB_LIGHTMAP = 1,
|
||||
TB_LEVELSMAP = 1,
|
||||
TB_SHADOWMAP = 1,
|
||||
TB_SHADOWMAP3 = 1,
|
||||
TB_NORMALMAP = 2,
|
||||
TB_DELUXEMAP = 3,
|
||||
TB_SHADOWMAP2 = 3,
|
||||
TB_SPECULARMAP = 4,
|
||||
TB_SHADOWMAP3 = 5,
|
||||
TB_SHADOWMAP = 5,
|
||||
NUM_TEXTURE_BUNDLES = 6
|
||||
};
|
||||
|
||||
|
|
|
@ -1329,6 +1329,11 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
index |= LIGHTDEF_ENTITY;
|
||||
}
|
||||
|
||||
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && ((index & LIGHTDEF_USE_LIGHTMAP) || (index & LIGHTDEF_USE_LIGHT_VERTEX)))
|
||||
{
|
||||
index |= LIGHTDEF_USE_SHADOWMAP;
|
||||
}
|
||||
|
||||
if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP)
|
||||
{
|
||||
index = LIGHTDEF_USE_LIGHTMAP;
|
||||
|
@ -1492,6 +1497,14 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
{
|
||||
int i;
|
||||
|
||||
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && ((pStage->glslShaderIndex & LIGHTDEF_USE_LIGHTMAP) || (pStage->glslShaderIndex & LIGHTDEF_USE_LIGHT_VERTEX)))
|
||||
{
|
||||
GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
|
||||
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, backEnd.refdef.sunAmbCol);
|
||||
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol);
|
||||
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir);
|
||||
}
|
||||
|
||||
if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0])
|
||||
{
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
|
@ -1782,11 +1795,13 @@ void RB_StageIteratorGeneric( void )
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && tess.shader->sort <= SS_OPAQUE
|
||||
//if ((tr.sunShadows || r_forceSunlight->value > 0.0f) && tess.shader->sort <= SS_OPAQUE
|
||||
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {
|
||||
ForwardSunlight();
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// now do fog
|
||||
|
|
Loading…
Reference in a new issue