View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0003584||The Dark Mod||AI||public||23.10.2013 13:22||15.04.2014 21:07|
|Product Version||TDM 2.00|
|Target Version||TDM 2.02||Fixed in Version||TDM 2.02|
|Summary||0003584: Object Illumination code is wrong|
|Description||AI are seeing bodies in darkness, and not seeing bodies in the light.|
|Additional Information||The 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.|
|Tags||No tags attached.|
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...
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.
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".
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/lights.mtr.
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.
|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.|
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.
|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.|
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.
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.
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.
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.)
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 ?
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.)
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
"...you can get a result using ImageMagick
the command convert file.jpg file.txt dumps a listing of pixel values.
A little test example here."
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.
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?
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.
|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||View Revisions|
|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||View Revisions|
|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|