Jump to content
The Dark Mod Forums

Recommended Posts

Posted (edited)

I've noticed that the player's light level becomes inconsistent when leaning in any direction.

Standing directly under a light and leaning will change the level to anything ranging from complete darkness to dimming slightly, while leaning into a dark area may make the player more lit up.

I've tested this on the latest stable release(2.12) with shadow maps, stencils, with weak light gem and without. Also, across a random selection of about 5 maps - the behavior is the same. It should be easy to replicate assuming it's a code bug, because once I saw it, I couldn't not notice it.

Here's a video showing it in action:

Spoiler

 

 

Edited by Tinkerton
Posted

Leaning is supposed to slightly reduce your lightgem value, while movement increases it.

Also, most of our flame entities use a flicker table to variably brighten and darken the area.

Can you replicate this under a static light?

The "weak lightgem" has very poor accuracy and is only meant for the weakest hardware.

The only people who seem to use that mode these days are people playing the unofficial Android port.

What Operating System, CPU, GPU, and GPU driver versions do you have installed?

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Posted (edited)

First, the specs:
Windows 10 Professional 64-bit
Intel Core i7-10700k
Geforce RTX 4060 on driver version 565.90 (slightly outdated)
Just in case, I updated the drivers to the latest version(566.03), but didn't seem to change anything.

Also, to make it clear, I just tested the weak light gem to see if it would affect the problem - I don't normally play with it. Video and screenshots were made with the normal/strong light gem.

I've made a small map with a player start and a single light source to test, screenshots:

Spoiler

kSh2f9U.png

EFqPmEI.png

Note that in the 2nd screenshot I'm leaning from the dark edge towards the light source and the gem gets dimmer.

The light gem in this map seems to dim more consistently (or more linearly, so to speak) than out in the wild, but it still doesn't make sense. If I'm standing in a dark area and leaning towards a light, I wouldn't expect for the light gem to go completely dark.

By that same token, I wouldn't expect to be standing under a dim light and leaning into darkness to have the gem brighten even more, which I couldn't replicate in the test map but have captured in the video above when rotating around 12 seconds in (there's a glitch in the footage which I assume to be because of the map's portalling, so pay it no mind).

Couple that with the most common use case: dimly-lit torches that flicker and have low radius, and it becomes a lot more prominent.

There are missions that allowed me to exploit this. The best example is Away 0's casino, where two guards are playing cards next to a candle. Normally, it should be impossible for me to approach the table and snuff out the flame, but by leaning I can go right up to it and extinguish the candle without being noticed, all while being inches away from the light source. In some cases I can just lean+W directly under a torch without being noticed.

Edited by Tinkerton
  • Like 1
Posted (edited)

Yeah I'm seeing this too. Also running TDM 2.12 on Windows 10.

Here's a decent spot to test it in the Training Mission, near a light on the path to the "Stealth and Shadows" tutorial building. Position is (-441.6 -2420.27 221.35) according to the screenshot filename.

Crouched, normal:image.thumb.jpeg.af64036c6fbf28437c97548654e5fd5f.jpeg

 

Crouched, leaning forward:image.thumb.jpeg.eb37c0c4648e723db6d5a7cff8eef806.jpeg

 

It seems to work to some degree on most or all lights, but the strength varies. I feel like it's something to do with the elevation of the light compared to the player, not sure though. Definitely quite abusable to hide where one shouldn't be able to, getting nearly the minimum light gem value despite being very close to a light source.

Edited by sullium
  • Like 1
Posted (edited)

The issue doesn't seem to happen at all for me on version 2.03. Leaning towards a nearby light usually brightens the light gem as expected and never darkens it the way it does in 2.12. Tested several lights in both the Training Mission and St. Lucia.

Edited by sullium
Posted (edited)

So...

I downloaded the source lol.

I found several things that might be of interest.

First is that there's a difference between Game/LightGem.cpp and Renderer/Frontend/tr_subview.cpp.

In tr_subview.cpp there's line 563:

lg->SetOrigin( LGPos ); // Move the lightgem testmodel to the players feet based on the eye position

In LightGem.cpp, the line is missing, meaning that LGPos is never actually used in there.

 

Next up, the player-to-cam offset in LightGem.cpp:157:

LGPos.x += (Cam.x - LGPos.x) * 0.3f + cv_lg_oxoffs.GetFloat(); // Move the lightgem out a fraction along the leaning x vector
LGPos.y += (Cam.y - LGPos.y) * 0.3f + cv_lg_oyoffs.GetFloat(); // Move the lightgem out a fraction along the leaning y vector

It might just be superstition, but I get the feeling that delta*0.3f+offset(0 in both cases) is not actually doing what it obviously should (from a vector math standpoint). As soon as I plug this offset in (with or without x/yoffs), the gem starts "behaving" - meaning that it goes dark in front of lights and all of the other shenanigans described above. Every time I test it, this code is at fault.

 

Finally, we have LightGem.cpp:160:

// Prevent lightgem from clipping into the floor while crouching
if ( player->GetPlayerPhysics()->IsCrouching() ) {
	LGPos.z += 50.0f + cv_lg_ozoffs.GetFloat() ;
} else {
	LGPos.z = Cam.z + cv_lg_ozoffs.GetFloat(); // Set the lightgem's Z-axis position to that of the player's eyes
}

This chunk of code adds to the inconsistent behavior as well, for some reason.
It might be incorrect but I can't be sure. I'll try and lay out the math.
This is taken from Radiant, the player and the lightGem model are placed at world/global origin (0,0,0):

Spoiler

BQgswDv.png

Note that the lightGem is halfway through the floor, meaning that its local origin is at the center of the model(0,0,0).
The player is standing on the floor, meaning that its local origin is where the feet would be(0, 0, -74/2=-37).
This needs to be taken into account when adjusting the gem height.

This means that the local position of the gem when the player is crouching is 50 + ozoffs(-20)=30. The position is (0,0,30).
If the player is standing, the position is Cam.z (aka cvar normalViewHeight at 68) + ozoffs(-20)=48.
The gem's height in radiant is marked as ~53:

Spoiler

JULT4xU.png

This means that if the player is crouching, the lowest point of the lightGem is 30-(53/2)=3.5. The light gem is only 3.5 units off the ground when crouching, perhaps that adds to the darkness detected by the gem?
Now that I think about it, it might be why crouching+leaning next to tables with candleholders is so effective. The gem may be hiding in the table's shadow.

If the player is standing, the calculation for the lowest gem point is 48-(53/2)=21.5, this is plenty of space, but it's at about knee height relative to the player height(74).

 

As for solutions, I leave that up for discussion. I can only describe what I tried and it seems to be working relatively well (albeit in very limited circumstances), but it's definitely incomplete and I haven't even played enough with it to find the best offsets. Not to mention that my inexperience with the codebase might be throwing me off.

// I simply took the cam position:
const idVec3& Cam = player->GetEyePosition();

// Assigned it to LGPos:
idVec3 LGPos = Cam;

// And adjusted the offset to get "kinda consistent" dimming based on crouch:
if (player->GetPlayerPhysics()->IsCrouching()) {
	LGPos.z += 12.f; // This is crouchViewHeight(34)+12=46, the gem is above the player's head when crouched, equivalent to about torso height when stood up
} else {
	LGPos.z -= 4.f; // This is normalViewHeight(68)-4=64, the gem is above the player's head
}
Edited by Tinkerton
Posted

The cvar offset values were tested and working at some juncture.

Can you please bisect to the version that broke it? Was it 2.12?

( if so we may need to ask that you bisect 2.12 dev builds )

( I would do this myself but I fear that I don't have a good enough eye for this type of thing. )

Setting a hard-coded value that works for you, in your environment, for missions that you prefer to play may not be a viable solution.

The values in the offset cvars were fought over extensively in TDM QA tests as well as with beta tests by players so it would probably be a hard sell to convert to a hard-coded value regardless of how optimal it may be.

 

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Posted

I'll try and go through the history over the weekend.

Like I said, I'm just experimenting to see what sticks. The crouch offset, for example, is perfect if you want to keep the gem as close to the ground without clipping into it, but may have the unintended side-effects for gameplay - either way, I don't think that's the main issue here.

That cam adjustment is throwing me off, though. I don't understand why moving the gem a bit left/right/forward would result in it darkening so hard. I've moved the gem's rendering to PLAYER_VIEW to test where it is (not expecting accurate calculations), and it moves around as expected.

I get the feeling that there's some engine machinations happening under the hood that mess this up, but that's why I called it superstition in the first place. In the meantime, maybe someone more experienced could try and discern if this is coming from some other unexpected/unintended part of the player/entity/physics/leaning/camera/culling/etc interaction.

Posted (edited)

Did some more testing just to figure out what's actually going on with the offset.

I moved the gem further from the player to have a sort of "3rd person" view of what it's doing.

The first part of the clip (0-7sec)has the lightGem rendered in VID_PLAYER_VIEW so I can see where it's actually going.

The second part (7sec and onward) is with the lightGem rendered in VID_LIGHTGEM, where it belongs. My interpretation is that it shows that the light calculation appears to be incorrect when the gem is offset from the player. As to why... Hopefully, it's only a matter of time.

Spoiler

 

EDIT: I went back through the game versions one by one. 2.06 works perfectly (I'm not exaggerating, at least for the test case I use).

2.07 is the first that starts exhibiting issues, and they seem to remain consistent for the rest of releases up to 2.12.

EDIT2: I'm having trouble building 2.06 and 2.07 (in VS2013 - toolset v120) due to their dependencies on curl and other external libraries. If anyone has info on how to build these ancient projects, it would be much appreciated. Otherwise, I might just try it on Linux to see if it goes easier.

Edited by Tinkerton
Posted (edited)

Some more debugging using actual debug tools on 2.12, and I've also had a better look at the history and compared the two offending versions better.

The major change between version 2.06 and 2.07 is that the lightgem was moved to a separate subview (or viewport) for rendering. Most of the calculation logic was moved from LightGem.cpp to tr_subview.cpp and it was also adapted to the new system.

I think I've managed to narrow it down to two core issues:

1. Positioning

From what I gather, the gem position should not be adjusted or calculated in tr_subview.cpp. If the subview is only used for rendering the light gem, I presume it should not also have to deal with the logic of its positioning relative to the player/camera. Also, if that's the case, that makes it redundant, since the lightgem's position is already adjusted in LightGem.cpp. To solve this, I simply commented out the position adjustment code in tr_subview.cpp(lines 550-564), and also added the missing lg->SetOrigin( LGPos ) in LightGem.cpp. If this logic is sound, it's presumably a copy-paste artifact from when the code was being moved and adapted to subview.

Spoiler
// This entire chunk was commented out in tr_subview.cpp

/*
const idVec3& Cam = player->GetEyePosition();
idVec3 LGPos = player->GetPhysics()->GetOrigin();// Set the lightgem position to that of the player

// Move the lightgem out a fraction along the leaning vector
LGPos.x += (Cam.x - LGPos.x) * 0.3f + cv_lg_oxoffs.GetFloat(); 
LGPos.y += (Cam.y - LGPos.y) * 0.3f + cv_lg_oyoffs.GetFloat();

// Prevent lightgem from clipping into the floor while crouching
if ( player->GetPlayerPhysics()->IsCrouching() ) {
	LGPos.z += 50.0f + cv_lg_ozoffs.GetFloat();
} else {
	LGPos.z = Cam.z + cv_lg_ozoffs.GetFloat(); // Set the lightgem's Z-axis position to that of the player's eyes
}

lg->SetOrigin( LGPos ); // Move the lightgem testmodel to the players feet based on the eye position
*/

2. Shadows in the light

My current theory is that the player, one of its attachments, or something else entirely is casting a shadow in the VID_LIGHTGEM render layer. Now obviously, the player and the head are specifically flagged not to render their models and shadows in the subview:

Spoiler
// Make sure the player model is hidden in the lightgem renders
renderEntity_t* prent = player->GetRenderEntity();
const int pdef = player->GetModelDefHandle();
const int playerid = prent->suppressSurfaceInViewID;
const int psid = prent->suppressShadowInViewID;
prent->suppressShadowInViewID = VID_LIGHTGEM;
prent->suppressSurfaceInViewID = VID_LIGHTGEM;

// And the player's head 
renderEntity_t* hrent = player->GetHeadEntity()->GetRenderEntity();
const int hdef = player->GetHeadEntity()->GetModelDefHandle();
const int headid = hrent->suppressSurfaceInViewID;
const int hsid = hrent->suppressShadowInViewID;
hrent->suppressShadowInViewID = VID_LIGHTGEM;
hrent->suppressSurfaceInViewID = VID_LIGHTGEM;

The only question then is what is actually casting that shadow.

Spoiler

In the attached video you can see that this theory holds water. Since the gem only moves a little bit towards the lean position, it makes sense that the player leaning towards the light source would obscure the light and darken it. Turning away from the light makes it brighter.

As a side note, player shadow being enabled/disabled has no effect on this.

Sullium mentioned above that it seems to have something to do with light elevation, which is kind of true. Since the player is leaning and offsetting on a flat plane, an overhead light will exhibit this problem less than one at eye level.


Now, this issue is 90% mitigated by fully moving the gem position to the camera position:

Spoiler

Replacing this:

const idVec3& Cam = player->GetEyePosition();
idVec3 LGPos = player->GetPhysics()->GetOrigin();

LGPos.x += (Cam.x - LGPos.x) * 0.3f + cv_lg_oxoffs.GetFloat(); // cv_lg_oxoffs = 0
LGPos.y += (Cam.y - LGPos.y) * 0.3f + cv_lg_oyoffs.GetFloat(); // cv_lg_oyoffs = 0

With this:

const idVec3& Cam = player->GetEyePosition();
idVec3 LGPos = player->GetPhysics()->GetOrigin();

LGPos.x += (Cam.x - LGPos.x);
LGPos.y += (Cam.y - LGPos.y);

However, that's not the real solution. It makes it so that when the player walks around it makes the light level very responsive, but also very jittery. I suppose the player walking/running animations are casting a shadow on the light gem when moving. It's a bit of a leap, but from what I can see it seems consistent. The light level also jitters more slowly when the player is crouching.
I have no solutions for this, as I'm not yet familiar enough with the rendering system, or perhaps any rogue attachments on the player/camera.

EDIT: Scratch that, I think I got it.

// Added this to tr_subview.cpp:567
lightgemRv.vieworg = lg->GetPhysics()->GetOrigin();

Unpacked a fresh copy of the 2.12 source, added this line in, seems to work like a charm. I was considering that the lightgem camera might be offset from where it's actually supposed to be and then I saw that the vieworg is not set anywhere in the subview, when the view should be at the center of the gem model. It just works™.

I'll remove the position adjustment in subview as stated in point 1 above, since it really does seem redundant, and test these changes on a few missions. I'll also test it out with func_peek, since I noticed an issue mentioning it.

Edited by Tinkerton
Never using bullet points again
  • Like 3
  • Thanks 1
Posted

Excellent news.

Haven't had time to play yet, but I've confirmed it has nothing to do with the func_peek bug. I'll raise a new thread when I get enough info on it.

And thanks to the team for keeping the spirit of taffing alive all this time.

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.

  • Recent Status Updates

    • snatcher

      Author of the Visible Player Hands mod: please come forth and collect a round of applause!
      · 2 replies
    • nbohr1more

      Holiday TDM Moddb article is now up: https://www.moddb.com/mods/the-dark-mod/news/happy-holidays-from-the-dark-mod
      · 0 replies
    • nbohr1more

      Cool thing: Thanksgiving break means I don't have to get my son up before dawn

      Not cool thing: My son stays up all night on my PC so I don't get much TDM time...
      · 3 replies
    • datiswous

      Does anyone know if the mission/map in this video posted by @Springheel can still be found somewhere and played? Looks like fun.
       
      · 2 replies
    • taffernicus

      I'm curious about doom and thief multiplayer netcode 😂 or how these games handle networking for multiplayer in general
      a youtube channel called battle(non)sense sometimes posts about netcode analysis
      · 2 replies
×
×
  • Create New...