View Issue Details

IDProjectCategoryView StatusLast Update
0003584The Dark ModAIpublic02.07.2024 00:27
Reportergrayman Assigned Tograyman  
Status resolvedResolutionfixed 
Product VersionTDM 2.00 
Target VersionTDM 2.02Fixed in VersionTDM 2.02 
Summary0003584: Object Illumination code is wrong
DescriptionAI are seeing bodies in darkness, and not seeing bodies in the light.
Additional InformationThe cause of the problem is bad math when determining the intersection of lines and ellipsoid point lights, and the intersection of lines and projected lights.
TagsNo tags attached.


related to 0006546 assignedstgatilov Proper system for measuring light factor of bodies 




23.10.2013 15:59

developer   ~0006215

This is probably an obvious factor but I will state it as a reminder.

The light volume could be completely dark because the light textures (projection and falloff) are black yet the body would be considered illuminated because it's within the volume bounding box. The same would apply to any variance in the texture brightness unless each AI had their own sampling system similar to the light-gem...


23.10.2013 16:58

viewer   ~0006216

What I'm fixing is the inside/outside volume check, which is borked in a few cases, for both point lights and projected lights. The current code can give both false positives and false negatives.

Once we have a correct "inside" determination, the code goes on to check the light textures. At first glance, that part seems fine. I need to verify, though, that the point on the texture that's chosen to make the final brightness determination is correct.


26.10.2013 00:49

viewer   ~0006217

I see no evidence that the falloff and projection images are being used for illumination.

When the code enters that area, it successfully finds the images in a list, but the light hasn't stored any data for the images, so it doesn't get used. I've dug about as deep as I can for now, and still don't know where that data is supposed to be read in or why it's not there.

So all the illumination math defaults to "distance from light origin".


26.10.2013 02:31

viewer   ~0006218

Last edited: 26.10.2013 04:02

Illumination of an object is done by drawing a line from the min corner to the max corner of the object’s bounding box. Then intersections of that line and the light volumes of nearby lights determined the amount of illumination present on the object.

Numerous problems needed to be fixed.

1 – A quick way of determining whether a line segment was beyond the light volume was to check the distance from its starting point to the light origin. If it was greater than the max radius of the light, the line was considered beyond the reach of the light. The problem with this check was that the other end of the line could be inside the light volume, or a long line could have both ends of the line outside the light volume, with the line passing through the light volume of a small light. Since this check could cause a light’s illumination to be ignored, I removed it.

2 – When checking line intersections with a point light volume, it was possible to determine the wrong intersecting point, or an intersecting point where none was possible. I corrected this math. Having both ends of the line inside the light volume was also not handled correctly, and I fixed that as well.

3 – When checking line intersections with a projected light frustum, the intersection routine was grossly wrong. It included some notes about id doing it one way, but the developer saying that was wrong, and continuing with his own different solution. That solution was also wrong, causing obviously bad intersection points to be calculated. I replaced the bad code with good code.

4 – When doing a visibility trace to a light holder, the code wasn’t considering the light holder itself. So the model of a light was getting in the way of the trace, causing it to assume there was no visibility. I corrected this to allow for light holders.

5 – Read light textures from files other than materials/

6 - The code for projected lights was assuming the light always projected downwards, which screwed up the x/y coordinates of the illumination spot used on a falloff or projected image. The fix is to rotate the coordinate system of the projected light into a state where that assumption is valid, and use the rotated x/y coordinates. (This turned out to be meaningless as long as the falloff and projected image data is not available.)

7 – TODO: The code that determines illumination based on falloff/projection images is in place, but it’s unable to retrieve any image data. I can’t find where/how that data is read and stored. So the default of “how far away the point is from the light origin” is always used.

Rev. 5900:




07.12.2013 05:49

developer   ~0006309

I think your last item is currently impossible. Once the volume representation is roughly determined in the rendering frontend it is forwarded to the backend to do GL calls. The engine never "knows" the contents of any textures (light or otherwise) all of the texture processing and light shading is done on the GPU at the pixel level. You would need to decompress the DDS textures locally and parse them in parallel to their rendering. This would likely be too expensive so you'd need to down sample to a lower resolution representation (16x16 ?). I guess you could use a pixel buffer request to the GPU but I'm not sure how well you could isolate the needed part of the buffer without making the engine re-render part of the scene just like the light gem. Plus pixel buffer requests are still dog slow on most hardware. In short, I think this is as good as it gets without you building a parallel data representation of the texture data.


07.12.2013 13:26

viewer   ~0006310

Okay, thanks.

I suspect that whoever wrote the original code stopped short of doing what you're suggesting, since the code certainly behaves like it wants to know where the illumination point is in the falloff/projection image. It just has no image to process, so they might have tried it, found it was expensive, and abandoned the idea w/o removing the code that leads up to it.


09.03.2014 00:57

viewer   ~0006422

Reverting status back to assigned because there are some issues when AI are at the fringe of a light volume, and oriented such that the line used to determine illumination lies outside the volume, yet the renderer is casting shadows from the body. Looks like a disconnect between the DLL's illumination code and the renderer's light code.


09.03.2014 19:48

reporter   ~0006429

Are there debug visualizations implemented for this ? Things like drawing the internally used volumes and the test-lines.

With that it would be easy to see if the volumes match the Doom3 Light Volumes ( using r_showLights 3+ ), and if the test-line is barely missing the volume.


10.03.2014 15:07

viewer   ~0006430

What am I seeing with r_showLights 3+?

The screen is painted with hundreds of boxes and some blue shading.

I can't establish any correlation between the boxes/shading and the lights.


10.03.2014 16:05

reporter   ~0006431

The blue shading are the light-frustum sides drawn as transparent polygons, the triangles are the light-frustum sides drawn as triangles.

They should directly correlate to what the renderer uses as the light frustums.


10.03.2014 16:21

viewer   ~0006432

So what I'm seeing is that the body lies inside the frustum of the closest light, yet the illumination code says the body is outside the ellipsoid of the light, which is a point light.

I'm thinking that the renderer doesn't use the ellipsoid to determine the light volume, causing a disconnect between what the player sees and what the ellipsoid intersection math tells us is going on. (i.e. I can see light on the body, but at the same time it's outside the light volume.)


10.03.2014 16:33

reporter   ~0006433

Last edited: 10.03.2014 16:34

Yes, the lights in Doom3 are not really ellipsoid, they are projections - in the case of point-lights the projection volume is a box ( and a proper frustum for projected lights ).

If the light material happens to use "round" textures, the projection makes them look like they only use a spherical volume, but that's not really the case.

Is the light in question using more rectangular shapes in the light-material textures ?



10.03.2014 16:52

viewer   ~0006434

The light in question uses a round texture.

So what I'm seeing on the ground where the body is is a projected box of light that's darkening the corners where it hits the ground, in order to simulate an ellipsoid light volume.

This means the illumination code needs to do the same thing, and not what it's doing now.

The problem is that the illumination code has no way to know what the light texture is, so a body sitting in the corners will be considered lit when the renderer paints that area dark.

The illumination code is written to take the light textures into account, but I found that the light data represented by the texture is unavailable to the code. (See my comments above in the 10/25/13 note.)


11.03.2014 22:48

developer   ~0006436

So (since we are going in circles), to implement the abstraction model:

1) Pass all of our light images trough a desaturate filter in GIMP (etc)
2) Reduce all resolutions to 16x16 or 32x32
3) Use ImageMagick to get a listing of all pixel RGB values
4) Save these values in tables that are referenced in the material defs for their corresponding light
5) Sample the tables as part of the illumination check


Example conversion:

" can get a result using ImageMagick

the command convert file.jpg file.txt dumps a listing of pixel values.

A little test example here."




11.03.2014 23:02

viewer   ~0006437

That's a lot of work, so I'd rather give it its own bugtracker issue and deal with it when we have time.

It's more than I want to get into for 2.02, which looks like it's going to be made sooner rather than later because of the sound issues.


12.03.2014 02:19

developer   ~0006438

Sure, a long term project. Additional side-benefits may include an even faster lightgem implementation and possibly some more granular dynamic ambient control... maybe even some more ways to do visibility checks on lights to cull some via LOD.

You can always farm out the grunt work of the conversion to folks like me or other forum regulars. I wont start this work unless I know for sure that you plan on implementing step 5 though...

Rebb? Any better solution?


18.03.2014 21:41

viewer   ~0006444

Another round:

Overall, improve the accuracy of the illumination check for bodies, since they seem to be giving us the most trouble.

1 – Create a list of ambient lights, identified by the “ambientLight” keyword in their light texture. This shortens the search time for finding ambient lights that might be contributing to object illumination. In 2.01, only “ambient_world” or info_location entities contributed uniform illumination to the areas they cover. Now we’re including all ambient lights covering the point where illumination is being checked.

2 – Instead of using the axis-aligned bounding box of a fallen body, orient a bounding box to the angles of the body. This should reduce false positives and false negatives when determining illumination, especially when the body is dropped near the boundaries of light volumes.

3 – No longer use a test line from the minimum corner of a bounding box to the maximum corner. Find the box edge that’s closest to the light source. This has to be done per light, so different lights might use different edges.

4 – Turn on lights that have faded out to OFF and are fading back in. For such a light, the renderer would show the brightening light source, but the light script wasn’t changing the skin, nor was the renderer painting the brightening light volume on nearby surfaces.

5 – For a fallen body, the bounding box can extend below the ground or floor. Since light isn’t going to reach box edges that are below the ground or floor, bring the bottom of the box up so it sits just above the floor.

Rev. 5943:


Issue History

Date Modified Username Field Change
23.10.2013 13:22 grayman New Issue
23.10.2013 13:22 grayman Status new => assigned
23.10.2013 13:22 grayman Assigned To => grayman
23.10.2013 15:59 nbohr1more Note Added: 0006215
23.10.2013 16:58 grayman Note Added: 0006216
26.10.2013 00:49 grayman Note Added: 0006217
26.10.2013 02:31 grayman Note Added: 0006218
26.10.2013 02:31 grayman Status assigned => feedback
26.10.2013 02:31 grayman Resolution open => fixed
26.10.2013 02:31 grayman Fixed in Version => TDM 2.01
26.10.2013 04:02 grayman Note Edited: 0006218
07.12.2013 05:49 nbohr1more Note Added: 0006309
07.12.2013 13:26 grayman Note Added: 0006310
07.12.2013 13:26 grayman Status feedback => assigned
25.12.2013 03:21 grayman Status assigned => feedback
29.01.2014 02:04 Springheel Status feedback => resolved
09.03.2014 00:57 grayman Note Added: 0006422
09.03.2014 00:57 grayman Status resolved => assigned
09.03.2014 19:48 rebb Note Added: 0006429
10.03.2014 15:07 grayman Note Added: 0006430
10.03.2014 16:05 rebb Note Added: 0006431
10.03.2014 16:21 grayman Note Added: 0006432
10.03.2014 16:33 rebb Note Added: 0006433
10.03.2014 16:34 rebb Note Edited: 0006433
10.03.2014 16:52 grayman Note Added: 0006434
11.03.2014 22:48 nbohr1more Note Added: 0006436
11.03.2014 23:02 grayman Note Added: 0006437
12.03.2014 02:19 nbohr1more Note Added: 0006438
18.03.2014 21:41 grayman Note Added: 0006444
18.03.2014 21:41 grayman Status assigned => feedback
18.03.2014 21:41 grayman Fixed in Version TDM 2.01 => TDM 2.02
18.03.2014 21:41 grayman Target Version TDM 2.01 => TDM 2.02
15.04.2014 21:07 grayman Status feedback => resolved
02.07.2024 00:27 nbohr1more Relationship added related to 0006546