From: havoc Date: Mon, 24 Oct 2005 04:42:22 +0000 (+0000) Subject: moved d_lightstylevalue into r_refdef.lightstyle X-Git-Tag: xonotic-v0.1.0preview~4519 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=e5580a4c3b96651baab0c55549a5c47f9b517ede;p=xonotic%2Fdarkplaces.git moved d_lightstylevalue into r_refdef.lightstyle moved r_dlights into r_redef.lights and made it an array of pointers into cl_dlights to save memory and time merged R_UpdateLights into CL_DecayLights and renamed it CL_UpdateLights renamed R_RTLight_UpdateFromDLight to R_RTLight_Update and made it take only the dlight pointer implemented cl_activedlights variable to prevent scanning whole MAX_DLIGHTS range every frame git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5765 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_main.c b/cl_main.c index 908c8d15..6c8e851e 100644 --- a/cl_main.c +++ b/cl_main.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "cl_collision.h" #include "cl_video.h" #include "image.h" +#include "r_shadow.h" // we need to declare some mouse variables here, because the menu system // references them even when on a unix system. @@ -83,6 +84,7 @@ int cl_max_beams; int cl_max_dlights; int cl_max_lightstyle; int cl_max_brushmodel_entities; +int cl_activedlights; entity_t *cl_entities; qbyte *cl_entities_active; @@ -150,6 +152,7 @@ void CL_ClearState(void) cl_max_dlights = MAX_DLIGHTS; cl_max_lightstyle = MAX_LIGHTSTYLES; cl_max_brushmodel_entities = MAX_EDICTS; + cl_activedlights = 0; cl_entities = (entity_t *)Mem_Alloc(cl_mempool, cl_max_entities * sizeof(entity_t)); cl_entities_active = (qbyte *)Mem_Alloc(cl_mempool, cl_max_brushmodel_entities * sizeof(qbyte)); @@ -492,7 +495,7 @@ void CL_AllocDlight(entity_render_t *ent, matrix4x4_t *matrix, float radius, flo if (ent) { dl = cl_dlights; - for (i = 0;i < MAX_DLIGHTS;i++, dl++) + for (i = 0;i < cl_activedlights;i++, dl++) if (dl->ent == ent) goto dlightsetup; } @@ -500,9 +503,15 @@ void CL_AllocDlight(entity_render_t *ent, matrix4x4_t *matrix, float radius, flo // then look for anything else dl = cl_dlights; - for (i = 0;i < MAX_DLIGHTS;i++, dl++) + for (i = 0;i < cl_activedlights;i++, dl++) if (!dl->radius) goto dlightsetup; + // if we hit the end of the active dlights and found no gaps, add a new one + if (i < MAX_DLIGHTS) + { + cl_activedlights = i + 1; + goto dlightsetup; + } // unable to find one return; @@ -539,16 +548,55 @@ dlightsetup: dl->specularscale = specularscale; } -void CL_DecayLights(void) +void CL_UpdateLights(void) { - int i; + int i, j, k, l, oldmax; dlight_t *dl; - float time; + float time, frac, f; + + r_refdef.numlights = 0; time = cl.time - cl.oldtime; - for (i = 0, dl = cl_dlights;i < MAX_DLIGHTS;i++, dl++) + oldmax = cl_activedlights; + cl_activedlights = 0; + for (i = 0, dl = cl_dlights;i < oldmax;i++, dl++) + { if (dl->radius) - dl->radius = (cl.time < dl->die) ? max(0, dl->radius - time * dl->decay) : 0; + { + f = dl->radius - time * dl->decay; + if (cl.time < dl->die && f > 0) + { + dl->radius = dl->radius - time * dl->decay; + cl_activedlights = i + 1; + if (r_dynamic.integer) + { + R_RTLight_Update(dl, false); + r_refdef.lights[r_refdef.numlights++] = dl; + } + } + else + dl->radius = 0; + } + } + +// light animations +// 'm' is normal light, 'a' is no light, 'z' is double bright + f = cl.time * 10; + i = (int)floor(f); + frac = f - i; + for (j = 0;j < MAX_LIGHTSTYLES;j++) + { + if (!cl_lightstyle || !cl_lightstyle[j].length) + { + r_refdef.lightstylevalue[j] = 256; + continue; + } + k = i % cl_lightstyle[j].length; + l = (i-1) % cl_lightstyle[j].length; + k = cl_lightstyle[j].map[k] - 'a'; + l = cl_lightstyle[j].map[l] - 'a'; + r_refdef.lightstylevalue[j] = ((k*frac)+(l*(1-frac)))*22; + } } #define MAXVIEWMODELS 32 @@ -1301,7 +1349,7 @@ int CL_ReadFromServer(void) { // prepare for a new frame CL_LerpPlayer(CL_LerpPoint()); - CL_DecayLights(); + CL_UpdateLights(); CL_ClearTempEntities(); V_DriftPitch(); V_FadeViewFlashs(); diff --git a/client.h b/client.h index 3781bd3f..28a0c65c 100644 --- a/client.h +++ b/client.h @@ -710,7 +710,6 @@ extern lightstyle_t *cl_lightstyle; extern client_state_t cl; extern void CL_AllocDlight (entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, int cubemapnum, int style, int shadowenable, vec_t corona, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags); -extern void CL_DecayLights (void); //============================================================================= @@ -901,6 +900,14 @@ typedef struct refdef_s int numentities; int maxentities; + // renderable dynamic lights + dlight_t *lights[MAX_DLIGHTS]; + int numlights; + + // 8.8bit fixed point intensities for light styles + // controls intensity of dynamic lights and lightmap layers + unsigned short lightstylevalue[256]; // 8.8 fraction of base light value + // 2D art drawing queue // TODO: get rid of this qbyte *drawqueue; diff --git a/gl_rmain.c b/gl_rmain.c index b40dea36..4b16a4bf 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -71,9 +71,6 @@ matrix4x4_t r_view_matrix; // refdef_t r_refdef; -// 8.8 fraction of base light value -unsigned short d_lightstylevalue[256]; - cvar_t r_showtris = {0, "r_showtris", "0"}; cvar_t r_drawentities = {0, "r_drawentities","1"}; cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"}; @@ -939,7 +936,6 @@ void R_RenderView(void) R_ClearScreen(); R_Textures_Frame(); R_UpdateFog(); - R_UpdateLights(); R_TimeReport("setup"); qglDepthFunc(GL_LEQUAL); @@ -1457,7 +1453,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) // would normally be baked into the lightmaptexture must be // applied to the color if (ent->model->type == mod_brushq3) - colorscale *= d_lightstylevalue[0] * (1.0f / 256.0f); + colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f); // transparent and fullbright are not affected by r_lightmapintensity if (!(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) colorscale *= r_lightmapintensity; @@ -1655,23 +1651,23 @@ void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i]; if (lm) { - float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f); + float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f); VectorScale(lm, scale, c); if (surface->lightmapinfo->styles[1] != 255) { int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3; lm += size3; - scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f); + scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); if (surface->lightmapinfo->styles[2] != 255) { lm += size3; - scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f); + scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); if (surface->lightmapinfo->styles[3] != 255) { lm += size3; - scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f); + scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); } } @@ -2060,9 +2056,9 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) { for (i = 0;i < model->brushq1.light_styles;i++) { - if (model->brushq1.light_stylevalue[i] != d_lightstylevalue[model->brushq1.light_style[i]]) + if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]]) { - model->brushq1.light_stylevalue[i] = d_lightstylevalue[model->brushq1.light_style[i]]; + model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]]; if ((surfacechain = model->brushq1.light_styleupdatechains[i])) for (;(surface = *surfacechain);surfacechain++) surface->cached_dlight = true; diff --git a/gl_rsurf.c b/gl_rsurf.c index 82655907..c038227c 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -83,7 +83,7 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) { bl = intblocklights; for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++, lightmap += size3) - for (scale = d_lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++) + for (scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++) bl[i] += lightmap[i] * scale; } } diff --git a/model_shared.h b/model_shared.h index 8746c4d0..3dc5644b 100644 --- a/model_shared.h +++ b/model_shared.h @@ -235,7 +235,7 @@ typedef struct msurface_lightmapinfo_s { // texture mapping properties used by this surface mtexinfo_t *texinfo; // q1bsp - // index into d_lightstylevalue array, 255 means not used (black) + // index into r_refdef.lightstylevalue array, 255 means not used (black) qbyte styles[MAXLIGHTMAPS]; // q1bsp // RGB lighting data [numstyles][height][width][3] qbyte *samples; // q1bsp diff --git a/r_light.c b/r_light.c index 13858976..ff6d3021 100644 --- a/r_light.c +++ b/r_light.c @@ -23,9 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "cl_collision.h" #include "r_shadow.h" -dlight_t r_dlight[MAX_DLIGHTS]; -int r_numdlights = 0; - cvar_t r_modellights = {CVAR_SAVE, "r_modellights", "4"}; cvar_t r_vismarklights = {0, "r_vismarklights", "1"}; cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1"}; @@ -67,7 +64,7 @@ void r_light_newmap(void) { int i; for (i = 0;i < 256;i++) - d_lightstylevalue[i] = 264; // normal light value + r_refdef.lightstylevalue[i] = 264; // normal light value } void R_Light_Init(void) @@ -79,51 +76,6 @@ void R_Light_Init(void) R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap); } -/* -================== -R_UpdateLights -================== -*/ -void R_UpdateLights(void) -{ - float frac; - int i, j, k, l; - -// light animations -// 'm' is normal light, 'a' is no light, 'z' is double bright - i = (int)(cl.time * 10); - frac = (cl.time * 10) - i; - for (j = 0;j < MAX_LIGHTSTYLES;j++) - { - if (!cl_lightstyle || !cl_lightstyle[j].length) - { - d_lightstylevalue[j] = 256; - continue; - } - k = i % cl_lightstyle[j].length; - l = (i-1) % cl_lightstyle[j].length; - k = cl_lightstyle[j].map[k] - 'a'; - l = cl_lightstyle[j].map[l] - 'a'; - d_lightstylevalue[j] = ((k*frac)+(l*(1-frac)))*22; - } - - r_numdlights = 0; - - if (!r_dynamic.integer || !cl_dlights) - return; - - // TODO: optimize to not scan whole cl_dlights array if possible - for (i = 0;i < MAX_DLIGHTS;i++) - { - if (cl_dlights[i].radius > 0) - { - R_RTLight_UpdateFromDLight(&cl_dlights[i].rtlight, &cl_dlights[i], false); - // FIXME: use pointer instead of copy - r_dlight[r_numdlights++] = cl_dlights[i]; - } - } -} - void R_DrawCoronas(void) { int i, lnum, flag; @@ -143,8 +95,9 @@ void R_DrawCoronas(void) R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, light->rtlight.shadoworigin, r_viewright, r_viewup, scale, -scale, -scale, scale, light->rtlight.color[0] * cscale, light->rtlight.color[1] * cscale, light->rtlight.color[2] * cscale, 1); } } - for (i = 0, light = r_dlight;i < r_numdlights;i++, light++) + for (i = 0;i < r_refdef.numlights;i++) { + light = r_refdef.lights[i]; if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (dist = (DotProduct(light->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1) { cscale = light->corona * r_coronas.value * 0.25f; @@ -190,13 +143,13 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu for (i = 0;i < r_refdef.worldmodel->brushq1.numlights;i++) { sl = r_refdef.worldmodel->brushq1.lights + i; - if (d_lightstylevalue[sl->style] > 0) + if (r_refdef.lightstylevalue[sl->style] > 0) { VectorSubtract (p, sl->origin, v); f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract); if (f > 0 && CL_TraceBox(p, vec3_origin, vec3_origin, sl->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1) { - f *= d_lightstylevalue[sl->style] * (1.0f / 65536.0f); + f *= r_refdef.lightstylevalue[sl->style] * (1.0f / 65536.0f); if (f > 0) VectorMA(ambientcolor, f, sl->light, ambientcolor); } @@ -210,9 +163,10 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu float f, v[3]; dlight_t *light; // FIXME: this really should handle dlights as diffusecolor/diffusenormal somehow - for (i = 0;i < r_numdlights;i++) + // FIXME: this should be updated to match rtlight falloff! + for (i = 0;i < r_refdef.numlights;i++) { - light = r_dlight + i; + light = r_refdef.lights[i]; VectorSubtract(p, light->origin, v); f = DotProduct(v, v); if (f < light->rtlight.lightmap_cullradius2 && CL_TraceBox(p, vec3_origin, vec3_origin, light->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1) @@ -284,7 +238,7 @@ int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, co for (i = 0;i < ent->numentlights;i++) { sl = r_refdef.worldmodel->brushq1.lights + ent->entlights[i]; - stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f); + stylescale = r_refdef.lightstylevalue[sl->style] * (1.0f / 65536.0f); VectorSubtract (ent->origin, sl->origin, v); f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale; VectorScale(sl->light, f, ambientcolor); @@ -334,9 +288,9 @@ int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, co if (ent->flags & RENDER_TRANSPARENT) { // FIXME: this dlighting doesn't look like rtlights - for (i = 0;i < r_numdlights;i++) + for (i = 0;i < r_refdef.numlights;i++) { - light = r_dlight + i; + light = r_refdef.lights[i]; VectorCopy(light->origin, v); if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0]; if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1]; @@ -385,7 +339,7 @@ int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, co Matrix4x4_Transform(&ent->inversematrix, light->origin, nl->origin); /* Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" - , rd - r_dlight, ent->model->name + , rd - cl_dlights, ent->model->name , light->origin[0], light->origin[1], light->origin[2] , nl->origin[0], nl->origin[1], nl->origin[2] , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3] diff --git a/r_light.h b/r_light.h index ea1e525a..84429ef2 100644 --- a/r_light.h +++ b/r_light.h @@ -2,10 +2,6 @@ #ifndef R_LIGHT_H #define R_LIGHT_H -extern int r_numdlights; -extern dlight_t r_dlight[MAX_DLIGHTS]; - -void R_UpdateLights(void); void R_DrawCoronas(void); void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic); int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, const entity_render_t *ent, float colorr, float colorg, float colorb, float colora, int worldcoords); diff --git a/r_shadow.c b/r_shadow.c index 24a56aa9..7f39f325 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -1074,11 +1074,11 @@ static matrix4x4_t r_shadow_entitytolight; static matrix4x4_t r_shadow_entitytoattenuationxyz; // this transforms only the Z to S, and T is always 0.5 static matrix4x4_t r_shadow_entitytoattenuationz; -// rtlight->color * r_dlightstylevalue[rtlight->style] / 256 * r_shadow_lightintensityscale.value * ent->colormod * ent->alpha +// rtlight->color * r_refdef.lightstylevalue[rtlight->style] / 256 * r_shadow_lightintensityscale.value * ent->colormod * ent->alpha static vec3_t r_shadow_entitylightcolorbase; -// rtlight->color * r_dlightstylevalue[rtlight->style] / 256 * r_shadow_lightintensityscale.value * ent->colormap_pantscolor * ent->alpha +// rtlight->color * r_refdef.lightstylevalue[rtlight->style] / 256 * r_shadow_lightintensityscale.value * ent->colormap_pantscolor * ent->alpha static vec3_t r_shadow_entitylightcolorpants; -// rtlight->color * r_dlightstylevalue[rtlight->style] / 256 * r_shadow_lightintensityscale.value * ent->colormap_shirtcolor * ent->alpha +// rtlight->color * r_refdef.lightstylevalue[rtlight->style] / 256 * r_shadow_lightintensityscale.value * ent->colormap_shirtcolor * ent->alpha static vec3_t r_shadow_entitylightcolorshirt; static int r_shadow_lightpermutation; @@ -2479,10 +2479,11 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t } } -void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int isstatic) +void R_RTLight_Update(dlight_t *light, int isstatic) { int j, k; float scale; + rtlight_t *rtlight = &light->rtlight; R_RTLight_Uncompile(rtlight); memset(rtlight, 0, sizeof(*rtlight)); @@ -2521,7 +2522,7 @@ void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int i rtlight->lightmap_cullradius = bound(0, rtlight->radius, 2048.0f); rtlight->lightmap_cullradius2 = rtlight->lightmap_cullradius * rtlight->lightmap_cullradius; - VectorScale(rtlight->color, rtlight->radius * (rtlight->style >= 0 ? d_lightstylevalue[rtlight->style] : 128) * 0.125f, rtlight->lightmap_light); + VectorScale(rtlight->color, rtlight->radius * (rtlight->style >= 0 ? r_refdef.lightstylevalue[rtlight->style] : 128) * 0.125f, rtlight->lightmap_light); rtlight->lightmap_subtract = 1.0f / rtlight->lightmap_cullradius2; } @@ -2723,7 +2724,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) if (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale < (1.0f / 32768.0f)) return; - f = (rtlight->style >= 0 ? d_lightstylevalue[rtlight->style] : 128) * (1.0f / 256.0f) * r_shadow_lightintensityscale.value; + f = (rtlight->style >= 0 ? r_refdef.lightstylevalue[rtlight->style] : 128) * (1.0f / 256.0f) * r_shadow_lightintensityscale.value; VectorScale(rtlight->color, f, lightcolor); if (VectorLength2(lightcolor) < (1.0f / 32768.0f)) return; @@ -2878,8 +2879,8 @@ void R_ShadowVolumeLighting(qboolean visible) if (light->flags & flag) R_DrawRTLight(&light->rtlight, visible); if (r_rtdlight) - for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++) - R_DrawRTLight(&light->rtlight, visible); + for (lnum = 0;lnum < r_refdef.numlights;lnum++) + R_DrawRTLight(&r_refdef.lights[lnum]->rtlight, visible); R_Shadow_Stage_End(); } @@ -3041,7 +3042,7 @@ void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, ve light->flags = flags; Matrix4x4_CreateFromQuakeEntity(&light->matrix, light->origin[0], light->origin[1], light->origin[2], light->angles[0], light->angles[1], light->angles[2], 1); - R_RTLight_UpdateFromDLight(&light->rtlight, light, true); + R_RTLight_Update(light, true); } void R_Shadow_FreeWorldLight(dlight_t *light) diff --git a/r_shadow.h b/r_shadow.h index e3bbb42b..84078ac5 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -55,7 +55,7 @@ void R_Shadow_UpdateWorldLightSelection(void); extern rtlight_t *r_shadow_compilingrtlight; -void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int isstatic); +void R_RTLight_Update(dlight_t *light, int isstatic); void R_RTLight_Compile(rtlight_t *rtlight); void R_RTLight_Uncompile(rtlight_t *rtlight); diff --git a/render.h b/render.h index eb8795cf..4254877e 100644 --- a/render.h +++ b/render.h @@ -167,7 +167,6 @@ extern float r_view_fov_y; extern matrix4x4_t r_view_matrix; extern mleaf_t *r_viewleaf, *r_oldviewleaf; -extern unsigned short d_lightstylevalue[256]; // 8.8 fraction of base light value extern qboolean envmap;