Jump to content
The Dark Mod Forums

Light frustums different in DR and TDM


Recommended Posts

I checked a few missions which show up in my lists of "weird" ones, and the projected lights exactly match right now (compared to 2.00, 2.04, 2.05 --- whatever is necessary to boot FM).

Regarding DarkRadiant, the frustum it shows also matches the old behavior of Doom 3 and TDM.
I'd say it would be great to do the following in DR:

  1. Warn mappers when they try to create a projected light with unbounded frustum. Such lights will not work well. They'd better know it immediately.
  2. If Doom 3 BFG mapping is a real thing and DR needs to support it, then you'll need to implement different computation specifically for D3BFG (well, unless you have already).
Link to comment
Share on other sites

1 hour ago, stgatilov said:

I checked a few missions which show up in my lists of "weird" ones, and the projected lights exactly match right now (compared to 2.00, 2.04, 2.05 --- whatever is necessary to boot FM).

Regarding DarkRadiant, the frustum it shows also matches the old behavior of Doom 3 and TDM.
I'd say it would be great to do the following in DR:

  1. Warn mappers when they try to create a projected light with unbounded frustum. Such lights will not work well. They'd better know it immediately.
  2. If Doom 3 BFG mapping is a real thing and DR needs to support it, then you'll need to implement different computation specifically for D3BFG (well, unless you have already).

I think the DR change would be as trivial as copy-pasting the BFG projection function from TDM

Link to comment
Share on other sites

11 minutes ago, duzenko said:

I think the DR change would be as trivial as copy-pasting the BFG projection function from TDM

Not exactly, since you have to do the conversion.

But one can follow the code in current SVN, and see what R_ComputeSpotLightProjectionMatrix puts into "oldProject" under "r_spotlightBehavior 1". Although I'd say it must be checked against the reference (i.e. check the visual result against Doom 3 BFG).

Link to comment
Share on other sites

6 minutes ago, stgatilov said:

Not exactly, since you have to do the conversion.

But one can follow the code in current SVN, and see what R_ComputeSpotLightProjectionMatrix puts into "oldProject" under "r_spotlightBehavior 1". Although I'd say it must be checked against the reference (i.e. check the visual result against Doom 3 BFG).

But basically we stick with D3 projections for now visually while we still keep using BFG projections for culling? If so, DR changes are not needed (for TDM at least)

Link to comment
Share on other sites

It sounds like the DR frustum is OK, but we already know that the preview light rendering is broken for projected lights. So some changes are definitely needed, but they may not be related to this recent work.

I already tried a simple copy-paste of the game code to fix the rendering, but it didn't work. However that was right at the beginning when I had no idea what the X/Y/Z/W values were supposed to be doing in the matrix, so it was basically cargo cult programming. Now we have a better idea of the correct behaviour as well as more thorough unit tests, so perhaps a careful integration of the game code would be more successful.

Link to comment
Share on other sites

There is 4x4 matrix used for culling, and 4x4 matrix used for shading.

The shading matrix is computed by Doom 3 code now (under default "r_spotlightBehavior 0"). This matrix defines how the lighting will actually look. This matrix defines the light polytope. Even when TRU are not orthogonal, the polytope is not necessarily a frustum, because start/end points define falloff direction.

The culling matrix is computed from the shading matrix: most parts are taken "as is", but front/back planes are computed from the vertices of light polytope. This matrix is only used in some culling code, and that's the only reason why it exists (deleting it would save us from confusion). It always defines a frustum in case of orthogonal TRU. This matrix does not affect how the light looks, except that the light can be culled away it the frustum is fully outside view, so it must contain the polytope of the shading frustum. In principle, we can take bounding box of the light polytope and set culling matrix corresponding to this box, and most likely it will be OK too.

The shading matrix defines the behavior, the culling matrix is merely an implementation detail of TDM engine. DarkRadiant does not need any fancy culling, so it only need to reproduce the shading matrix correctly.

Link to comment
Share on other sites

  • 1 month later...
On 11/21/2021 at 12:39 AM, stgatilov said:

Ok, I found one more issue on current TDM: the projected lights do light stuff outside their frustum.

The issue is very easy to see on the test map that I added, especially with "r_useLightScissors 0". With scissoring enabled, most of wrong spots go away, but some are still visible with obvious scissoring artefacts as you move around.

@duzenko has already noticed one such issue and committed a fix in svn rev 9640. Basically, he disabled lighting of "antiworld" (where divisor w<0).

Another problem is that there are many more bad areas where light works while it should not. Basically, both U and V texcoords on projection texture and fallof parameter can get out of [0..1] interval, in which case something weird happens. Perhaps it worked properly in Doom 3 and old TDM because textures were set to "clamp-to-zero" mode, but now they do not. So I added explicit if-s for the out-of-bounds case in svn rev 9646. After that I no longer see some magically lit zones outside frustum.

That fix broke scrolling light textures (5860).

Aside from the matrix which defined light frustum, there is also texture matrix. The shader sees only the product of these matrices. My fix basically forces "clamp-to-zero" rule on both projection and falloff textures, while scrolling textures are specifically designed to exhibit "repeat" rule on projection texture.

I see two ways to proceed:

  1. Pass texture matrix separately from the light projection matrix. Compute texcoord using light projection matrix in vertex shader, then force black color in fragment shader if texcoord is outside [0..1], finally multiply the texcoord by texture matrix in fragment shader.
  2. Rely on artist setting "zeroClamp" on projection texture, also enforce the same for falloff textures (right now they are always TR_CLAMP for some reason). Of course, in case of a scrolling texture, artist won't set zeroClamp.

The only downside in p.1 is performance (although it is unlikely anyone would notice it).

The downside in p.2 is that shader will still allow to highlight surfaces outside the light volume, despite the fact that various frontend techniques (culling and scissoring) will break it to various extent.

P.S. Of course, the check that perspective divisor is positive (added by @duzenko) is a good one, it should retain no matter what.

Link to comment
Share on other sites

Was that fix urgently required? I remember complains on projected lights two-sidedness, but the followup fix was also requested by mappers? If not, we can revert it for 2.10 and leave in svn to return to it after beta ends

Link to comment
Share on other sites

14 minutes ago, duzenko said:

Was that fix urgently required? I remember complains on projected lights two-sidedness, but the followup fix was also requested by mappers? If not, we can revert it for 2.10 and leave in svn to return to it after beta ends

The security camera required that fix to two-sidedness and also to proper falloff. The spotlight now works perfectly in both those regards.

Link to comment
Share on other sites

31 minutes ago, Dragofer said:

The security camera required that fix to two-sidedness and also to proper falloff. The spotlight now works perfectly in both those regards.

Wasn't the two-sided thing and falloff the same issue?

Link to comment
Share on other sites

3 hours ago, stgatilov said:
  1. Pass texture matrix separately from the light projection matrix. Compute texcoord using light projection matrix in vertex shader, then force black color in fragment shader if texcoord is outside [0..1], finally multiply the texcoord by texture matrix in fragment shader.

That's what we do in DR (although DR is not exactly an authority on the correct way to implement lighting shaders, particularly with regard to performance).

  • Like 1
Link to comment
Share on other sites

1 hour ago, duzenko said:

Wasn't the two-sided thing and falloff the same issue?

Not as far as I can tell, you committed something that fixed the two-sidedness, then a while later I noticed the falloff has become properly smooth instead of cutting off to black abruptly. It's the first time I've seen a projected light with correct length-wise falloff in TDM.

  • Thanks 1
Link to comment
Share on other sites

4 hours ago, duzenko said:

Was that fix urgently required? I remember complains on projected lights two-sidedness, but the followup fix was also requested by mappers? If not, we can revert it for 2.10 and leave in svn to return to it after beta ends

There is projection texture and falloff texture.

For projection texture, mapper can/should set zeroClamp and the problem of going outside frustum by U or V won't happen.
For falloff texture, mapper has no control over its clamping, it is just "clamp" right now. I guess the end values of falloff are not zero, because I see excessive lighting on test map due to falloff texture.

Link to comment
Share on other sites

1 hour ago, stgatilov said:

There is projection texture and falloff texture.

For projection texture, mapper can/should set zeroClamp and the problem of going outside frustum by U or V won't happen.
For falloff texture, mapper has no control over its clamping, it is just "clamp" right now. I guess the end values of falloff are not zero, because I see excessive lighting on test map due to falloff texture.

Can we reliably do texture projection in vertex shader? I'd think that any perspective division can only happen in fragment shader

Maybe zeroclamp on projection lights only?

Link to comment
Share on other sites

17 minutes ago, duzenko said:

Can we reliably do texture projection in vertex shader? I'd think that any perspective division can only happen in fragment shader

One can of course do perspective division in fragment shader, but there is no reason to.

In p.1, perspective division is only needed after applying light volume transformation. The texture matrix has dimensions 2x3, and only allows rotation, translation, and scaling. There is no perspective division involved when dealing with it.

Quote

Maybe zeroclamp on projection lights only?

Technically, no light source should be allowed to light anything outside its light volume, because of the conflict with frontend culling/scissoring/triangle filtering.
Ordinary lights are no exception. I don't really see why projected lights should be special here.

Link to comment
Share on other sites

13 minutes ago, stgatilov said:

Technically, no light source should be allowed to light anything outside its light volume, because of the conflict with frontend culling/scissoring/triangle filtering.
Ordinary lights are no exception. I don't really see why projected lights should be special here.

But light texture coordinate transformation does not mean anything will be lit outside of the volume. The texture could be e.g. a sinusoid.

At least for ambient lights

Link to comment
Share on other sites

22 minutes ago, duzenko said:

But light texture coordinate transformation does not mean anything will be lit outside of the volume. The texture could be e.g. a sinusoid.

If a triangle (e.g. a large one) passes all frontend tests against light volume, then it is sent for actual rendering.
Shader computes texcoords and fetches the textures even for fragment outside light volume, it has no way to distinguish.  If both texture fetches return non-zero, then fragment outside light volume gets lit.

The check that I introduced forces clamp-to-zero rule on both textures, so this issue does not happen... unless a nontrivial texture matrix is used (I simply did not think about texture matrix when I implemented it). Imagine that texture matrix shifts U parameter by 0.5. If a fragment has texcoords (-0.3, 0.5) without texture matrix, then it will have texcoords (0.2, 0.5) with texture matrix, so this fragment will be lit despite it being outside light volume. And this can easily happen for point light as well.

The most reliable fix is to pass light volume matrix and texture matrices separately, and apply clamp-to-zero rule to intermediate texcoords (i.e. the ones computed with light volume matrix but without texture matrix applied). Of course, it means that texture matrix has to be applied in fragment shader, while light volume matrix can be applied in vertex shader and get builtin prespective division.

Link to comment
Share on other sites

Here is how cloudscroll works on fresh SVN (with all kinds of clamp-to-zero present in fragment shader):

The volumetric light and r_showLights 4 show the light frustum.
You can easily see that floor is lit outside light volume, sometimes pretty far outside, and with ugly scissoring.

If we clamp texcoords before applying texture matrix, then the light will always be inside frustum.

UPDATE: See it yourself on test/volumetric_light_shadows.map.

  • Like 2
Link to comment
Share on other sites

On 1/4/2022 at 2:56 PM, stgatilov said:

That fix broke scrolling light textures (5860).

  1. Pass texture matrix separately from the light projection matrix. Compute texcoord using light projection matrix in vertex shader, then force black color in fragment shader if texcoord is outside [0..1], finally multiply the texcoord by texture matrix in fragment shader.

Applied p.1 in svn rev 9780.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share


×
×
  • Create New...