diff --git a/include/light/entities.h b/include/light/entities.h index dfaa808c..59837c98 100644 --- a/include/light/entities.h +++ b/include/light/entities.h @@ -71,6 +71,7 @@ typedef struct entity_s { /* worldspawn only */ vec_t dirtdepth; int dirtmode; + float dirtangle; int minlight_dirt; vec_t dist; vec_t range; diff --git a/include/light/light.h b/include/light/light.h index 9722e353..c123c0c7 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -124,6 +124,7 @@ extern int dirtMode; extern float dirtDepth; extern float dirtScale; extern float dirtGain; +extern float dirtAngle; extern qboolean globalDirt; // apply dirt to all lights (unless they override it)? extern qboolean minlightDirt; // apply dirt to minlight? @@ -132,6 +133,7 @@ extern qboolean dirtModeSetOnCmdline; extern qboolean dirtDepthSetOnCmdline; extern qboolean dirtScaleSetOnCmdline; extern qboolean dirtGainSetOnCmdline; +extern qboolean dirtAngleSetOnCmdline; /* * Return space for the lightmap and colourmap at the same time so it can diff --git a/light/entities.c b/light/entities.c index 4c53f61c..82cade51 100644 --- a/light/entities.c +++ b/light/entities.c @@ -748,6 +748,8 @@ LoadEntities(const bsp2_t *bsp) entity->dirtdepth = atof(com_token); else if (!strcmp(key, "_dirtmode")) entity->dirtmode = atoi(com_token); + else if (!strcmp(key, "_dirtangle")) + entity->dirtangle = atoi(com_token); else if (!strcmp(key, "_sunlight_dirt")) sunlight_dirt = atoi(com_token); else if (!strcmp(key, "_sunlight2_dirt")) @@ -849,6 +851,11 @@ LoadEntities(const bsp2_t *bsp) logprint("Using dirtgain value %f from worldspawn.\n", dirtGain); } + if (entity->dirtangle && !dirtAngleSetOnCmdline) { + dirtAngle = entity->dirtangle; + logprint("Using dirtangle value %f from worldspawn.\n", + dirtAngle); + } if (entity->dirt == 1) { globalDirt = true; dirty = true; diff --git a/light/light.c b/light/light.c index 3251b38a..3f4df767 100644 --- a/light/light.c +++ b/light/light.c @@ -43,6 +43,7 @@ int dirtMode = 0; float dirtDepth = 128.0f; float dirtScale = 1.0f; float dirtGain = 1.0f; +float dirtAngle = 88.0f; qboolean globalDirt = false; qboolean minlightDirt = false; @@ -52,6 +53,7 @@ qboolean dirtModeSetOnCmdline = false; qboolean dirtDepthSetOnCmdline = false; qboolean dirtScaleSetOnCmdline = false; qboolean dirtGainSetOnCmdline = false; +qboolean dirtAngleSetOnCmdline = false; qboolean testFenceTextures = false; @@ -353,6 +355,10 @@ main(int argc, const char **argv) dirtGain = 1.0f; } logprint( "Dirtmapping gain set to %.1f\n", dirtGain ); + } else if ( !strcmp( argv[ i ], "-dirtangle" ) ) { + dirtAngleSetOnCmdline = true; + dirtAngle = atof( argv[ ++i ] ); + logprint( "Dirtmapping cone angle set to %.1f\n", dirtAngle ); } else if ( !strcmp( argv[ i ], "-fence" ) ) { testFenceTextures = true; logprint( "Fence texture tracing enabled on command line\n" ); @@ -373,7 +379,7 @@ main(int argc, const char **argv) printf("usage: light [-threads num] [-extra|-extra4]\n" " [-light num] [-addmin] [-anglescale|-anglesense]\n" " [-dist n] [-range n] [-gate n] [-lit] [-lux]\n" - " [-dirt] [-dirtdebug] [-dirtmode n] [-dirtdepth n] [-dirtscale n] [-dirtgain n]\n" + " [-dirt] [-dirtdebug] [-dirtmode n] [-dirtdepth n] [-dirtscale n] [-dirtgain n] [-dirtangle n]\n" " [-soft [n]] [-fence] [-gamma n] [-surflight_subdivide n] [-onlyents] bspfile\n"); exit(1); } diff --git a/light/ltface.c b/light/ltface.c index 7cfb989f..c47b5846 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -1027,7 +1027,6 @@ LightFace_DirtDebug(const lightsurf_t *lightsurf, lightmap_t *lightmaps) /* Dirtmapping borrowed from q3map2, originally by RaP7oR */ -#define DIRT_CONE_ANGLE 88 /* degrees */ #define DIRT_NUM_ANGLE_STEPS 16 #define DIRT_NUM_ELEVATION_STEPS 3 #define DIRT_NUM_VECTORS ( DIRT_NUM_ANGLE_STEPS * DIRT_NUM_ELEVATION_STEPS ) @@ -1049,9 +1048,17 @@ void SetupDirt( void ) { /* note it */ logprint("--- SetupDirt ---\n" ); + /* clamp dirtAngle */ + if ( dirtAngle <= 1.0f ) { + dirtAngle = 1.0f; + } + if ( dirtAngle >= 90.0f) { + dirtAngle = 90.0f; + } + /* calculate angular steps */ angleStep = DEG2RAD( 360.0f / DIRT_NUM_ANGLE_STEPS ); - elevationStep = DEG2RAD( DIRT_CONE_ANGLE / DIRT_NUM_ELEVATION_STEPS ); + elevationStep = DEG2RAD( dirtAngle / DIRT_NUM_ELEVATION_STEPS ); /* iterate angle */ angle = 0.0f; @@ -1159,7 +1166,7 @@ DirtForSample(const dmodel_t *model, const vec3_t origin, const vec3_t normal){ for ( i = 0; i < numDirtVectors; i++ ) { /* get random vector */ angle = Random() * DEG2RAD( 360.0f ); - elevation = Random() * DEG2RAD( DIRT_CONE_ANGLE ); + elevation = Random() * DEG2RAD( dirtAngle ); temp[ 0 ] = cos( angle ) * sin( elevation ); temp[ 1 ] = sin( angle ) * sin( elevation ); temp[ 2 ] = cos( elevation ); diff --git a/man/light.1 b/man/light.1 index 25fc6008..839881bf 100644 --- a/man/light.1 +++ b/man/light.1 @@ -65,7 +65,7 @@ key. See "_dirt" for more details. .IP "\fB\-dirtdebug\fP" Implies "-dirt", and renders just the dirtmap against a fullbright background, ignoring all lights in the map. Useful for previewing and turning the dirt settings. -.IP "\fB\-dirtmode n\fP | \fB\-dirtdepth n\fP | \fB\-dirtscale n\fP | \fB\-dirtgain n\fP" +.IP "\fB\-dirtmode n\fP | \fB\-dirtdepth n\fP | \fB\-dirtscale n\fP | \fB\-dirtgain n\fP | \fB\-dirtangle n\fP" Fine-tune the dirtmapping, overriding the corresponding worldspawn keys. See the worldspawn keys below. .IP "\fB\-fence\fP" @@ -174,6 +174,10 @@ the dirt fainter, 2.0 would create much darker shadows. Exponent used in dirt calculation, default 1. Lower values (e.g. 0.5) make the shadows darker and stretch further away from corners. +.IP "\fB""_dirtangle"" ""n""\fP" +Cone angle in degrees for occlusion testing, default 88. Allowed range 1-90. +Lower values can avoid unwanted dirt on arches, pipe interiors, etc. + .IP "\fB""_gamma"" ""n""\fP" Adjust brightness of final lightmap. Default 1, >1 is brighter, <1 is darker.