]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
illuminated surfaces are now sorted by texture, giving a good fps
[xonotic/darkplaces.git] / r_shadow.c
index 032d80dbaa42c398dc14d3f994a6a9cdbe090891..aca5afca6fdd99a6821f1f0ea4de87a893e32b01 100644 (file)
@@ -312,6 +312,7 @@ cvar_t r_shadow_shadowmapping_nearclip = {CVAR_SAVE, "r_shadow_shadowmapping_nea
 cvar_t r_shadow_shadowmapping_bias = {CVAR_SAVE, "r_shadow_shadowmapping_bias", "0.03", "shadowmap bias parameter (this is multiplied by nearclip * 1024 / lodsize)"};
 cvar_t r_shadow_shadowmapping_polygonfactor = {CVAR_SAVE, "r_shadow_shadowmapping_polygonfactor", "2", "slope-dependent shadowmapping bias"};
 cvar_t r_shadow_shadowmapping_polygonoffset = {CVAR_SAVE, "r_shadow_shadowmapping_polygonoffset", "0", "constant shadowmapping bias"};
+cvar_t r_shadow_sortsurfaces = {0, "r_shadow_sortsurfaces", "1", "improve performance by sorting illuminated surfaces by texture"};
 cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"};
 cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"};
 cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel textures for spherical attenuation rather than cylindrical (does not affect OpenGL 2.0 render path)"};
@@ -668,6 +669,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_shadowmapping_bias);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonoffset);
+       Cvar_RegisterVariable(&r_shadow_sortsurfaces);
        Cvar_RegisterVariable(&r_shadow_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_polygonoffset);
        Cvar_RegisterVariable(&r_shadow_texture3d);
@@ -3818,7 +3820,7 @@ void R_Shadow_DrawPrepass(void)
        {
                lightindex = r_shadow_debuglight.integer;
                light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
-               if (light && (light->flags & flag))
+               if (light && (light->flags & flag) && light->rtlight.draw)
                        R_Shadow_DrawLight(&light->rtlight);
        }
        else
@@ -3827,13 +3829,14 @@ void R_Shadow_DrawPrepass(void)
                for (lightindex = 0;lightindex < range;lightindex++)
                {
                        light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
-                       if (light && (light->flags & flag))
+                       if (light && (light->flags & flag) && light->rtlight.draw)
                                R_Shadow_DrawLight(&light->rtlight);
                }
        }
        if (r_refdef.scene.rtdlight)
                for (lnum = 0;lnum < r_refdef.scene.numlights;lnum++)
-                       R_Shadow_DrawLight(r_refdef.scene.lights[lnum]);
+                       if (r_refdef.scene.lights[lnum]->draw)
+                               R_Shadow_DrawLight(r_refdef.scene.lights[lnum]);
 
        R_Mesh_ResetRenderTargets();
 
@@ -6001,7 +6004,7 @@ LIGHT SAMPLING
 =============================================================================
 */
 
-void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic)
+void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, qboolean dynamic, qboolean rtworld)
 {
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
@@ -6016,16 +6019,57 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
 
        if (dynamic)
        {
-               int i;
-               float f, v[3];
+               int i, numlights, flag;
+               float f, relativepoint[3], dist, dist2, lightradius2;
                rtlight_t *light;
+               dlight_t *dlight;
+
+               // sample rtlights
+               if (rtworld)
+               {
+                       flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
+                       numlights = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);
+                       for (i = 0; i < numlights; i++)
+                       {
+                               dlight = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, i);
+                               if (!dlight)
+                                       continue;
+                               light = &dlight->rtlight;
+                               if (!(light->flags & flag))
+                                       continue;
+                               // sample
+                               lightradius2 = light->radius * light->radius;
+                               VectorSubtract(light->shadoworigin, p, relativepoint);
+                               dist2 = VectorLength2(relativepoint);
+                               if (dist2 >= lightradius2)
+                                       continue;
+                               dist = sqrt(dist2) / light->radius;
+                               f = dist < 1 ? (r_shadow_lightintensityscale.value * ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist))) : 0;
+                               if (f <= 0)
+                                       continue;
+                               // todo: add to both ambient and diffuse
+                               if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
+                                       VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);
+                       }
+               }
+
+               // sample dlights
                for (i = 0;i < r_refdef.scene.numlights;i++)
                {
                        light = r_refdef.scene.lights[i];
-                       Matrix4x4_Transform(&light->matrix_worldtolight, p, v);
-                       f = 1 - VectorLength2(v);
-                       if (f > 0 && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
-                               VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);
+                       // sample
+                       lightradius2 = light->radius * light->radius;
+                       VectorSubtract(light->shadoworigin, p, relativepoint);
+                       dist2 = VectorLength2(relativepoint);
+                       if (dist2 >= lightradius2)
+                               continue;
+                       dist = sqrt(dist2) / light->radius;
+                       f = dist < 1 ? (r_shadow_lightintensityscale.value * ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist))) : 0;
+                       if (f <= 0)
+                               continue;
+                       // todo: add to both ambient and diffuse
+                       if (!light->shadow || CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
+                               VectorMA(ambientcolor, f, light->color, ambientcolor);
                }
        }
 }