Significant rework of bouncegrid photon distribution and coloring.
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 27 Nov 2016 22:20:28 +0000 (22:20 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 27 Nov 2016 22:20:28 +0000 (22:20 +0000)
r_editlights mode now shows render stats in the overlay.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12300 d7cf8633-e32d-0410-b094-e92efae38249

client.h
r_shadow.c
r_shadow.h

index 4230c6a..aae1c86 100644 (file)
--- a/client.h
+++ b/client.h
@@ -395,8 +395,11 @@ typedef struct rtlight_s
        rtlight_particle_t *particlecache_particles;
 
        /// bouncegrid light info
-       float photoncolor[3];
-       float photons;
+       float bouncegrid_photoncolor[3];
+       float bouncegrid_photons;
+       int bouncegrid_hits;
+       int bouncegrid_traces;
+       float bouncegrid_effectiveradius;
 }
 rtlight_t;
 
index e888fc0..caef494 100644 (file)
@@ -337,6 +337,7 @@ cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel texture
 cvar_t r_shadow_bouncegrid = {CVAR_SAVE, "r_shadow_bouncegrid", "0", "perform particle tracing for indirect lighting (Global Illumination / radiosity) using a 3D texture covering the scene, only active on levels with realtime lights active (r_shadow_realtime_world is usually required for these)"};
 cvar_t r_shadow_bouncegrid_blur = {CVAR_SAVE, "r_shadow_bouncegrid_blur", "1", "apply a 1-radius blur on bouncegrid to denoise it and deal with boundary issues with surfaces"};
 cvar_t r_shadow_bouncegrid_bounceanglediffuse = {CVAR_SAVE, "r_shadow_bouncegrid_bounceanglediffuse", "0", "use random bounce direction rather than true reflection, makes some corner areas dark"};
+cvar_t r_shadow_bouncegrid_dynamic_bounceminimumintensity = { CVAR_SAVE, "r_shadow_bouncegrid_dynamic_bounceminimumintensity", "0.01", "stop bouncing once intensity drops below this fraction of the original particle color" };
 cvar_t r_shadow_bouncegrid_dynamic_culllightpaths = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_culllightpaths", "1", "skip accumulating light in the bouncegrid texture where the light paths are out of view (dynamic mode only)"};
 cvar_t r_shadow_bouncegrid_dynamic_dlightparticlemultiplier = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_dlightparticlemultiplier", "1", "if set to a high value like 16 this can make dlights look great, but 0 is recommended for performance reasons"};
 cvar_t r_shadow_bouncegrid_dynamic_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_dynamic_directionalshading", "0", "use diffuse shading rather than ambient, 3D texture becomes 8x as many pixels to hold the additional data"};
@@ -359,6 +360,7 @@ cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_
 cvar_t r_shadow_bouncegrid_sortlightpaths = {CVAR_SAVE, "r_shadow_bouncegrid_sortlightpaths", "1", "sort light paths before accumulating them into the bouncegrid texture, this reduces cpu cache misses"};
 cvar_t r_shadow_bouncegrid_lightpathsize = {CVAR_SAVE, "r_shadow_bouncegrid_lightpathsize", "1", "width of the light path for accumulation of light in the bouncegrid texture"};
 cvar_t r_shadow_bouncegrid_static = {CVAR_SAVE, "r_shadow_bouncegrid_static", "1", "use static radiosity solution (high quality) rather than dynamic (splotchy)"};
+cvar_t r_shadow_bouncegrid_static_bounceminimumintensity = { CVAR_SAVE, "r_shadow_bouncegrid_static_bounceminimumintensity", "0.01", "stop bouncing once intensity drops below this fraction of the original particle color" };
 cvar_t r_shadow_bouncegrid_static_directionalshading = {CVAR_SAVE, "r_shadow_bouncegrid_static_directionalshading", "1", "whether to use directionalshading when in static mode"};
 cvar_t r_shadow_bouncegrid_static_energyperphoton = {CVAR_SAVE, "r_shadow_bouncegrid_static_energyperphoton", "10000", "amount of light that one photon should represent in static mode"};
 cvar_t r_shadow_bouncegrid_static_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_static_lightradiusscale", "10", "particles stop at this fraction of light radius (can be more than 1) when in static mode"};
@@ -802,6 +804,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_bouncegrid);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_blur);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_bounceanglediffuse);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_bounceminimumintensity);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_culllightpaths);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_directionalshading);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_dynamic_dlightparticlemultiplier);
@@ -824,12 +827,13 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_bouncegrid_particleintensity);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_sortlightpaths);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static);
-       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_spacing);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_bounceminimumintensity);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_directionalshading);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_energyperphoton);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_lightradiusscale);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxbounce);
        Cvar_RegisterVariable(&r_shadow_bouncegrid_static_maxphotons);
-       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_energyperphoton);
+       Cvar_RegisterVariable(&r_shadow_bouncegrid_static_spacing);
        Cvar_RegisterVariable(&r_coronas);
        Cvar_RegisterVariable(&r_coronas_occlusionsizescale);
        Cvar_RegisterVariable(&r_coronas_occlusionquery);
@@ -2547,6 +2551,7 @@ static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t
 {
        qboolean s = r_shadow_bouncegrid_static.integer != 0;
        float spacing = s ? r_shadow_bouncegrid_static_spacing.value : r_shadow_bouncegrid_dynamic_spacing.value;
+       float bounceminimumintensity = s ? r_shadow_bouncegrid_static_bounceminimumintensity.value : r_shadow_bouncegrid_dynamic_bounceminimumintensity.value;
 
        // prevent any garbage in alignment padded areas as we'll be using memcmp
        memset(settings, 0, sizeof(*settings)); 
@@ -2564,13 +2569,14 @@ static void R_Shadow_BounceGrid_GenerateSettings(r_shadow_bouncegrid_settings_t
        settings->lightradiusscale              = (s ? r_shadow_bouncegrid_static_lightradiusscale.value : r_shadow_bouncegrid_dynamic_lightradiusscale.value);
        settings->maxbounce                     = (s ? r_shadow_bouncegrid_static_maxbounce.integer : r_shadow_bouncegrid_dynamic_maxbounce.integer);
        settings->particlebounceintensity       = r_shadow_bouncegrid_particlebounceintensity.value;
-       settings->particleintensity             = r_shadow_bouncegrid_particleintensity.value * 16384.0f * (settings->directionalshading ? 4.0f : 1.0f) / (spacing * spacing);
+       settings->particleintensity             = r_shadow_bouncegrid_particleintensity.value * (settings->directionalshading ? 4.0f : 1.0f) * 16384 / (spacing * spacing) / 262144.0f;
        settings->maxphotons                    = s ? r_shadow_bouncegrid_static_maxphotons.integer : r_shadow_bouncegrid_dynamic_maxphotons.integer;
-       settings->energyperphoton            = s ? r_shadow_bouncegrid_static_energyperphoton.integer : r_shadow_bouncegrid_dynamic_energyperphoton.integer;
+       settings->energyperphoton               = s ? r_shadow_bouncegrid_static_energyperphoton.value : r_shadow_bouncegrid_dynamic_energyperphoton.value;
        settings->spacing[0]                    = spacing;
        settings->spacing[1]                    = spacing;
        settings->spacing[2]                    = spacing;
        settings->stablerandom                  = s ? 1 : r_shadow_bouncegrid_dynamic_stablerandom.integer;
+       settings->bounceminimumintensity2       = bounceminimumintensity * bounceminimumintensity;
 
        // bound the values for sanity
        settings->maxphotons = bound(1, settings->maxphotons, 25000000);
@@ -2721,17 +2727,16 @@ static void R_Shadow_BounceGrid_UpdateSpacing(void)
        Matrix4x4_FromArrayFloatD3D(&r_shadow_bouncegrid_state.matrix, m);
 }
 
-#define MAXBOUNCEGRIDPARTICLESPERLIGHT 1048576
-
 // enumerate world rtlights and sum the overall amount of light in the world,
 // from that we can calculate a scaling factor to fairly distribute photons
 // to all the lights
 //
 // this modifies rtlight->photoncolor and rtlight->photons
-static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *settings, unsigned int range, unsigned int range1, unsigned int range2, int flag, float *photonscaling)
+static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *settings, unsigned int range, unsigned int range1, unsigned int range2, int flag)
 {
        float normalphotonscaling;
-       float maxphotonscaling;
+       float photonscaling;
+       float photonintensity;
        float photoncount = 0.0f;
        float lightintensity;
        float radius;
@@ -2742,16 +2747,20 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
        unsigned int lightindex;
        dlight_t *light;
        rtlight_t *rtlight;
+       normalphotonscaling = 1.0f / max(0.0001f, settings->energyperphoton);
        for (lightindex = 0;lightindex < range2;lightindex++)
        {
                if (lightindex < range)
                {
-                       light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+                       light = (dlight_t *)Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                        if (!light)
                                continue;
                        rtlight = &light->rtlight;
-                       VectorClear(rtlight->photoncolor);
-                       rtlight->photons = 0;
+                       VectorClear(rtlight->bouncegrid_photoncolor);
+                       rtlight->bouncegrid_photons = 0;
+                       rtlight->bouncegrid_hits = 0;
+                       rtlight->bouncegrid_traces = 0;
+                       rtlight->bouncegrid_effectiveradius = 0;
                        if (!(light->flags & flag))
                                continue;
                        if (settings->staticmode)
@@ -2760,12 +2769,17 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                                if (rtlight->style > 0 && r_shadow_bouncegrid.integer != 2)
                                        continue;
                        }
+                       else if (r_shadow_debuglight.integer >= 0 && (int)lightindex != r_shadow_debuglight.integer)
+                               continue;
                }
                else
                {
                        rtlight = r_refdef.scene.lights[lightindex - range];
-                       VectorClear(rtlight->photoncolor);
-                       rtlight->photons = 0;
+                       VectorClear(rtlight->bouncegrid_photoncolor);
+                       rtlight->bouncegrid_photons = 0;
+                       rtlight->bouncegrid_hits = 0;
+                       rtlight->bouncegrid_traces = 0;
+                       rtlight->bouncegrid_effectiveradius = 0;
                }
                // draw only visible lights (major speedup)
                radius = rtlight->radius * settings->lightradiusscale;
@@ -2792,9 +2806,9 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                if (rtlight->radius == 0.0f || VectorLength2(rtlight->color) == 0.0f)
                        continue;
                w *= ((rtlight->style >= 0 && rtlight->style < MAX_LIGHTSTYLES) ? r_refdef.scene.rtlightstylevalue[rtlight->style] : 1);
-               VectorScale(rtlight->color, w, rtlight->photoncolor);
+               VectorScale(rtlight->color, w, rtlight->bouncegrid_photoncolor);
                // skip lights that will emit no photons
-               if (!VectorLength2(rtlight->photoncolor))
+               if (!VectorLength2(rtlight->bouncegrid_photoncolor))
                        continue;
                // shoot particles from this light
                // use a calculation for the number of particles that will not
@@ -2805,20 +2819,41 @@ static void R_Shadow_BounceGrid_AssignPhotons(r_shadow_bouncegrid_settings_t *se
                lightintensity = VectorLength(rtlight->color) * (rtlight->ambientscale + rtlight->diffusescale + rtlight->specularscale);
                if (lightindex >= range)
                        lightintensity *= settings->dlightparticlemultiplier;
-               rtlight->photons = bound(0.0f, lightintensity * s * s, MAXBOUNCEGRIDPARTICLESPERLIGHT);
-               photoncount += rtlight->photons;
+               rtlight->bouncegrid_photons = lightintensity * s * s * normalphotonscaling;
+               photoncount += rtlight->bouncegrid_photons;
+               VectorScale(rtlight->bouncegrid_photoncolor, settings->particleintensity * settings->energyperphoton, rtlight->bouncegrid_photoncolor);
                // if the lightstyle happens to be off right now, we can skip actually
                // firing the photons, but we did have to count them in the total.
                //if (VectorLength2(rtlight->photoncolor) == 0.0f)
-               //      rtlight->photons = 0;
+               //      rtlight->bouncegrid_photons = 0;
        }
        // the user provided an energyperphoton value which we try to use
        // if that results in too many photons to shoot this frame, then we cap it
        // which causes photons to appear/disappear from frame to frame, so we don't
        // like doing that in the typical case
-       normalphotonscaling = 1.0f / max(0.0001f, settings->energyperphoton);
-       maxphotonscaling = (float)settings->maxphotons / max(1, photoncount);
-       *photonscaling = min(normalphotonscaling, maxphotonscaling);
+       photonscaling = 1.0f;
+       photonintensity = 1.0f;
+       if (photoncount > settings->maxphotons)
+       {
+               photonscaling = settings->maxphotons / photoncount;
+               photonintensity = 1.0f / photonscaling;
+       }
+
+       // modify the lights to reflect our computed scaling
+       for (lightindex = 0; lightindex < range2; lightindex++)
+       {
+               if (lightindex < range)
+               {
+                       light = (dlight_t *)Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+                       if (!light)
+                               continue;
+                       rtlight = &light->rtlight;
+               }
+               else
+                       rtlight = r_refdef.scene.lights[lightindex - range];
+               rtlight->bouncegrid_photons *= photonscaling;
+               VectorScale(rtlight->bouncegrid_photoncolor, photonintensity, rtlight->bouncegrid_photoncolor);
+       }
 }
 
 static int R_Shadow_BounceGrid_SplatPathCompare(const void *pa, const void *pb)
@@ -3223,7 +3258,7 @@ static void R_Shadow_BounceGrid_ConvertPixelsAndUpload(void)
        r_shadow_bouncegrid_state.lastupdatetime = realtime;
 }
 
-static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t settings, unsigned int range, unsigned int range1, unsigned int range2, float photonscaling, int flag)
+static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t settings, unsigned int range, unsigned int range1, unsigned int range2, int flag)
 {
        vec3_t bouncerandom[10];
        dlight_t *light;
@@ -3233,6 +3268,7 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
        int maxbounce;
        int shootparticles;
        int shotparticles;
+       float bounceminimumintensity2;
        trace_t cliptrace;
        //trace_t cliptrace2;
        //trace_t cliptrace3;
@@ -3275,15 +3311,20 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                // note that this code used to keep track of residual photons and
                // distribute them evenly to achieve exactly a desired photon count,
                // but that caused unwanted flickering in dynamic mode
-               shootparticles = (int)floor(rtlight->photons * photonscaling);
+               shootparticles = (int)floor(rtlight->bouncegrid_photons);
                // skip if we won't be shooting any photons
                if (!shootparticles)
                        continue;
                radius = rtlight->radius * settings.lightradiusscale;
-               s = settings.particleintensity / shootparticles;
-               VectorScale(rtlight->photoncolor, s, baseshotcolor);
+               //s = settings.particleintensity / shootparticles;
+               //VectorScale(rtlight->bouncegrid_photoncolor, s, baseshotcolor);
+               VectorCopy(rtlight->bouncegrid_photoncolor, baseshotcolor);
+               if (VectorLength2(baseshotcolor) <= 0.0f)
+                       continue;
                r_refdef.stats[r_stat_bouncegrid_lights]++;
                r_refdef.stats[r_stat_bouncegrid_particles] += shootparticles;
+               // we stop caring about bounces once the brightness goes below this fraction of the original intensity
+               bounceminimumintensity2 = VectorLength(baseshotcolor) * settings.bounceminimumintensity2;
                switch (settings.stablerandom)
                {
                default:
@@ -3340,6 +3381,7 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                        for (bouncecount = 0;;bouncecount++)
                        {
                                r_refdef.stats[r_stat_bouncegrid_traces]++;
+                               rtlight->bouncegrid_traces++;
                                //r_refdef.scene.worldmodel->TraceLineAgainstSurfaces(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace, clipstart, clipend, hitsupercontentsmask);
                                //r_refdef.scene.worldmodel->TraceLine(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace2, clipstart, clipend, hitsupercontentsmask);
                                if (settings.staticmode || settings.stablerandom <= 0)
@@ -3359,9 +3401,13 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                                        VectorCopy(cliptrace.endpos, hitpos);
                                        R_Shadow_BounceGrid_AddSplatPath(clipstart, hitpos, shotcolor);
                                }
+                               s = VectorDistance(rtlight->shadoworigin, cliptrace.endpos);
+                               if (rtlight->bouncegrid_effectiveradius < s)
+                                       rtlight->bouncegrid_effectiveradius = s;
                                if (cliptrace.fraction >= 1.0f)
                                        break;
                                r_refdef.stats[r_stat_bouncegrid_hits]++;
+                               rtlight->bouncegrid_hits++;
                                if (bouncecount >= maxbounce)
                                        break;
                                // scale down shot color by bounce intensity and texture color (or 50% if no texture reported)
@@ -3375,7 +3421,7 @@ static void R_Shadow_BounceGrid_TracePhotons(r_shadow_bouncegrid_settings_t sett
                                surfcolor[1] = min(surfcolor[1], 1.0f);
                                surfcolor[2] = min(surfcolor[2], 1.0f);
                                VectorMultiply(shotcolor, surfcolor, shotcolor);
-                               if (VectorLength2(baseshotcolor) == 0.0f)
+                               if (VectorLength2(shotcolor) <= bounceminimumintensity2)
                                        break;
                                r_refdef.stats[r_stat_bouncegrid_bounces]++;
                                if (settings.bounceanglediffuse)
@@ -3409,7 +3455,6 @@ void R_Shadow_UpdateBounceGridTexture(void)
        unsigned int range; // number of world lights
        unsigned int range1; // number of dynamic lights (or zero if disabled)
        unsigned int range2; // range+range1
-       float photonscaling;
 
        enable = R_Shadow_BounceGrid_CheckEnable(flag);
        
@@ -3461,10 +3506,10 @@ void R_Shadow_UpdateBounceGridTexture(void)
        range2 = range + range1;
 
        // calculate weighting factors for distributing photons among the lights
-       R_Shadow_BounceGrid_AssignPhotons(&settings, range, range1, range2, flag, &photonscaling);
+       R_Shadow_BounceGrid_AssignPhotons(&settings, range, range1, range2, flag);
 
        // trace the photons from lights and accumulate illumination
-       R_Shadow_BounceGrid_TracePhotons(settings, range, range1, range2, photonscaling, flag);
+       R_Shadow_BounceGrid_TracePhotons(settings, range, range1, range2, flag);
 
        // clear the texture
        R_Shadow_BounceGrid_ClearPixels();
@@ -7144,9 +7189,9 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        // draw properties on screen
        if (!r_editlights_drawproperties.integer)
                return;
-       x = vid_conwidth.value - 240;
+       x = vid_conwidth.value - 320;
        y = 5;
-       DrawQ_Pic(x-5, y-5, NULL, 250, 155, 0, 0, 0, 0.75, 0);
+       DrawQ_Pic(x-5, y-5, NULL, 250, 243, 0, 0, 0, 0.75, 0);
        lightnumber = -1;
        lightcount = 0;
        range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked
@@ -7179,6 +7224,17 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        dpsnprintf(temp, sizeof(temp), "Specular     : %.2f\n", r_shadow_selectedlight->specularscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
        dpsnprintf(temp, sizeof(temp), "NormalMode   : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
        dpsnprintf(temp, sizeof(temp), "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
+       y += 8;
+       dpsnprintf(temp, sizeof(temp), "Render stats\n"); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Current color: %.3f %.3f %.3f\n", r_shadow_selectedlight->rtlight.currentcolor[0], r_shadow_selectedlight->rtlight.currentcolor[1], r_shadow_selectedlight->rtlight.currentcolor[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Shadow size  : %ix%ix6\n", r_shadow_selectedlight->rtlight.shadowmapatlassidesize, r_shadow_selectedlight->rtlight.shadowmapatlassidesize); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "World surfs  : %i\n", r_shadow_selectedlight->rtlight.cached_numsurfaces); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Shadow ents  : %i + %i noself\n", r_shadow_selectedlight->rtlight.cached_numshadowentities, r_shadow_selectedlight->rtlight.cached_numshadowentities_noselfshadow); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "Lit ents     : %i + %i noself\n", r_shadow_selectedlight->rtlight.cached_numlightentities, r_shadow_selectedlight->rtlight.cached_numlightentities_noselfshadow); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG photons   : %.3f\n", r_shadow_selectedlight->rtlight.bouncegrid_photons); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG radius    : %.0f\n", r_shadow_selectedlight->rtlight.bouncegrid_effectiveradius); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG color     : %.3f %.3f %.3f\n", r_shadow_selectedlight->rtlight.bouncegrid_photoncolor[0], r_shadow_selectedlight->rtlight.bouncegrid_photoncolor[1], r_shadow_selectedlight->rtlight.bouncegrid_photoncolor[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
+       dpsnprintf(temp, sizeof(temp), "BG stats     : %i traces %i hits\n", r_shadow_selectedlight->rtlight.bouncegrid_traces, r_shadow_selectedlight->rtlight.bouncegrid_hits); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT); y += 8;
 }
 
 static void R_Shadow_EditLights_ToggleShadow_f(void)
index f59edaa..10f8e1e 100644 (file)
@@ -57,6 +57,7 @@ typedef struct r_shadow_bouncegrid_settings_s
        float energyperphoton;
        float spacing[3];
        int stablerandom;
+       float bounceminimumintensity2;
 }
 r_shadow_bouncegrid_settings_t;