]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
implemented and debugged BIH (Bounding Interval Hierarchy) code, more
[xonotic/darkplaces.git] / r_shadow.c
index c6168127452a32d66868d3e97d56cdab3d6df18b..b47711144f1845bff441a76804743a8b248ef7f4 100644 (file)
@@ -1507,19 +1507,48 @@ int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border)
        }
        // this next test usually clips off more sides than the former, but occasionally clips fewer/different ones, so do both and combine results
        // check if frustum corners/origin cross plane sides
+#if 1
+    // infinite version, assumes frustum corners merely give direction and extend to infinite distance
+    Matrix4x4_Transform(&rtlight->matrix_worldtolight, r_refdef.view.origin, p);
+    dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn);
+    masks[0] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
+    masks[1] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
+    dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn);
+    masks[2] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
+    masks[3] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
+    dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn);
+    masks[4] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
+    masks[5] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
+    for (i = 0;i < 4;i++)
+    {
+        Matrix4x4_Transform(&rtlight->matrix_worldtolight, r_refdef.view.frustumcorner[i], n);
+        VectorSubtract(n, p, n);
+        dp = n[0] + n[1], dn = n[0] - n[1], ap = fabs(dp), an = fabs(dn);
+        if(ap > 0) masks[0] |= dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2);
+        if(an > 0) masks[1] |= dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2);
+        dp = n[1] + n[2], dn = n[1] - n[2], ap = fabs(dp), an = fabs(dn);
+        if(ap > 0) masks[2] |= dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4);
+        if(an > 0) masks[3] |= dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4);
+        dp = n[2] + n[0], dn = n[2] - n[0], ap = fabs(dp), an = fabs(dn);
+        if(ap > 0) masks[4] |= dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0);
+        if(an > 0) masks[5] |= dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0);
+    }
+#else
+    // finite version, assumes corners are a finite distance from origin dependent on far plane
        for (i = 0;i < 5;i++)
        {
                Matrix4x4_Transform(&rtlight->matrix_worldtolight, !i ? r_refdef.view.origin : r_refdef.view.frustumcorner[i-1], p);
-               dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn),
+               dp = p[0] + p[1], dn = p[0] - p[1], ap = fabs(dp), an = fabs(dn);
                masks[0] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<0)|(1<<2) : (2<<0)|(2<<2));
                masks[1] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<0)|(2<<2) : (2<<0)|(1<<2));
-               dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn),
+               dp = p[1] + p[2], dn = p[1] - p[2], ap = fabs(dp), an = fabs(dn);
                masks[2] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<2)|(1<<4) : (2<<2)|(2<<4));
                masks[3] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<2)|(2<<4) : (2<<2)|(1<<4));
-               dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn),
+               dp = p[2] + p[0], dn = p[2] - p[0], ap = fabs(dp), an = fabs(dn);
                masks[4] |= ap <= bias*an ? 0x3F : (dp >= 0 ? (1<<4)|(1<<0) : (2<<4)|(2<<0));
                masks[5] |= an <= bias*ap ? 0x3F : (dn >= 0 ? (1<<4)|(2<<0) : (2<<4)|(1<<0));
        }
+#endif
        return sides & masks[0] & masks[1] & masks[2] & masks[3] & masks[4] & masks[5];
 }
 
@@ -2108,15 +2137,15 @@ void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
        nearclip = r_shadow_shadowmapping_nearclip.value / rsurface.rtlight->radius;
        farclip = 1.0f;
        bias = r_shadow_shadowmapping_bias.value * nearclip * (1024.0f / size);// * rsurface.rtlight->radius;
-       r_shadow_shadowmap_parameters[2] = 0.5f + 0.5f * (farclip + nearclip) / (farclip - nearclip);
-       r_shadow_shadowmap_parameters[3] = -nearclip * farclip / (farclip - nearclip) - 0.5f * bias;
+       r_shadow_shadowmap_parameters[1] = -nearclip * farclip / (farclip - nearclip) - 0.5f * bias;
+       r_shadow_shadowmap_parameters[3] = 0.5f + 0.5f * (farclip + nearclip) / (farclip - nearclip);
        r_shadow_shadowmapside = side;
        r_shadow_shadowmapsize = size;
        switch (r_shadow_shadowmode)
        {
        case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
                r_shadow_shadowmap_parameters[0] = 0.5f * (size - r_shadow_shadowmapborder);
-               r_shadow_shadowmap_parameters[1] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
+               r_shadow_shadowmap_parameters[2] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
                R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapborder, nearclip, farclip, NULL);
                if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAP2D) goto init_done;
 
@@ -2133,7 +2162,7 @@ void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
                break;
        case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
                r_shadow_shadowmap_parameters[0] = 0.5f * (size - r_shadow_shadowmapborder);
-               r_shadow_shadowmap_parameters[1] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
+               r_shadow_shadowmap_parameters[2] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
                R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapborder, nearclip, farclip, NULL);
                if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE) goto init_done;
 
@@ -2150,7 +2179,7 @@ void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
                break;
        case R_SHADOW_SHADOWMODE_SHADOWMAPCUBESIDE:
                r_shadow_shadowmap_parameters[0] = 1.0f;
-               r_shadow_shadowmap_parameters[1] = 1.0f;
+               r_shadow_shadowmap_parameters[2] = 1.0f;
                R_Viewport_InitCubeSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, nearclip, farclip, NULL);
                if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE) goto init_done;
 
@@ -4203,6 +4232,7 @@ extern cvar_t r_shadows_castfrombmodels;
 extern cvar_t r_shadows_throwdistance;
 extern cvar_t r_shadows_throwdirection;
 extern cvar_t r_shadows_focus;
+extern cvar_t r_shadows_shadowmapscale;
 
 void R_Shadow_PrepareModelShadows(void)
 {
@@ -4232,8 +4262,9 @@ void R_Shadow_PrepareModelShadows(void)
        }
 
        size = 2*r_shadow_shadowmapmaxsize;
-       scale = r_shadow_shadowmapping_precision.value;
+       scale = r_shadow_shadowmapping_precision.value * r_shadows_shadowmapscale.value;
        radius = 0.5f * size / scale;
+
        Math_atov(r_shadows_throwdirection.string, shadowdir);
        VectorNormalize(shadowdir);
        dot1 = DotProduct(r_refdef.view.forward, shadowdir);
@@ -4249,6 +4280,8 @@ void R_Shadow_PrepareModelShadows(void)
        VectorMA(shadoworigin, shadowfocus[1], r_refdef.view.up, shadoworigin);
        VectorMA(shadoworigin, -shadowfocus[2], r_refdef.view.forward, shadoworigin);
        VectorAdd(shadoworigin, r_refdef.view.origin, shadoworigin);
+       if (shadowfocus[0] || shadowfocus[1] || shadowfocus[2])
+               dot1 = 1;
        VectorMA(shadoworigin, (1.0f - fabs(dot1)) * radius, shadowforward, shadoworigin);
 
        shadowmins[0] = shadoworigin[0] - r_shadows_throwdistance.value * fabs(shadowdir[0]) - radius * (fabs(shadowforward[0]) + fabs(shadowright[0]));
@@ -4272,7 +4305,7 @@ void R_Shadow_PrepareModelShadows(void)
 void R_DrawModelShadowMaps(void)
 {
        int i;
-       float relativethrowdistance, scale, size, radius, nearclip, farclip, dot1, dot2;
+       float relativethrowdistance, scale, size, radius, nearclip, farclip, bias, dot1, dot2;
        entity_render_t *ent;
        vec3_t relativelightorigin;
        vec3_t relativelightdirection, relativeforward, relativeright;
@@ -4323,16 +4356,17 @@ void R_DrawModelShadowMaps(void)
        }
 
        size = 2*r_shadow_shadowmapmaxsize;
-
-       r_shadow_shadowmap_parameters[0] = bound(0.0f, 1.0f - r_shadows_darken.value, 1.0f);
-       r_shadow_shadowmap_parameters[1] = 1.0f;
-       r_shadow_shadowmap_parameters[2] = size;
-       r_shadow_shadowmap_parameters[3] = size;
-
-       scale = r_shadow_shadowmapping_precision.value / size;
+       scale = (r_shadow_shadowmapping_precision.value * r_shadows_shadowmapscale.value) / size;
        radius = 0.5f / scale;
        nearclip = -r_shadows_throwdistance.value;
        farclip = r_shadows_throwdistance.value;
+       bias = r_shadow_shadowmapping_bias.value * r_shadow_shadowmapping_nearclip.value / (2 * r_shadows_throwdistance.value) * (1024.0f / size);
+
+       r_shadow_shadowmap_parameters[0] = size;
+       r_shadow_shadowmap_parameters[1] = size;
+       r_shadow_shadowmap_parameters[2] = 1.0;
+       r_shadow_shadowmap_parameters[3] = bound(0.0f, 1.0f - r_shadows_darken.value, 1.0f);
+
        Math_atov(r_shadows_throwdirection.string, shadowdir);
        VectorNormalize(shadowdir);
        Math_atov(r_shadows_focus.string, shadowfocus);
@@ -4348,6 +4382,8 @@ void R_DrawModelShadowMaps(void)
                VectorMA(r_refdef.view.up, -dot2, shadowdir, shadowforward);
        VectorNormalize(shadowforward);
        VectorM(scale, shadowforward, &m[0]);
+       if (shadowfocus[0] || shadowfocus[1] || shadowfocus[2])
+               dot1 = 1;
        m[3] = fabs(dot1) * 0.5f - DotProduct(shadoworigin, &m[0]);
        CrossProduct(shadowdir, shadowforward, shadowright);
        VectorM(scale, shadowright, &m[4]);
@@ -4412,7 +4448,7 @@ void R_DrawModelShadowMaps(void)
        Matrix4x4_Concat(&mvpmatrix, &r_refdef.view.viewport.projectmatrix, &r_refdef.view.viewport.viewmatrix);
        Matrix4x4_Invert_Full(&invmvpmatrix, &mvpmatrix);
        Matrix4x4_CreateScale3(&scalematrix, size, -size, 1); 
-       Matrix4x4_AdjustOrigin(&scalematrix, 0, size, 0);
+       Matrix4x4_AdjustOrigin(&scalematrix, 0, size, -0.5f * bias);
        Matrix4x4_Concat(&texmatrix, &scalematrix, &shadowmatrix);
        Matrix4x4_Concat(&r_shadow_shadowmapmatrix, &texmatrix, &invmvpmatrix);