-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce r_lightMode, implement vertex lighting and use it when needed. #992
Conversation
…e lighting selection, fix bugs - Introduce r_lighting cvar with values: 0: fullbright 1: vertex lighting 2: grid lighting 3: light mapping The default value is 3 (light mapping), users may also use 1 (vertex lighting). All other values use the light mapping code but with different inputs, so none of the others are expected to be faster than light mapping. Values 0 (fullbright) and 2 (grid lighting) may give unfair advantages without satisfying a need for performance, and are considered cheats. The only thing grid lighting or vertex lighting can do is to save GPU memory by not uploading light maps, but the code itself is not faster, and is even a bit slower with grid lighting because there is more computation to do. - Implement fullbright lighting as a debug option. - Implement vertex lighting for both in-game usage when needed and as a debug option. - Use vertex lighting for bsp surfaces without lightmap. - Deeply rewrite the code to make it matching more the description of the need, make it less implicit, and track down bugs. - Limit usage of Half Lambert Lighting and Wrap Around Lighting for models. - Wrap Around Lighting uses the value set in material. - Properly enable Rim Lighting. - Define more GLSL macro conflicts to help the engine skip unused combinations. - Recognize light-styles lightmaps and process all light-styles lightmaps with Render_generic to avoid dynamic lights. - Properly set implicitLightmap on textures without materials. - Do not render lightmaps on collapsed stages without lightmaps. - Make fullbright and grid lighting for world rendering cheats. The engine may still use fullbright rendering or light grid rendering when needed (models use light grid) or as a fallback. renderer: correct light style implementation
I may turn the cvar into a modern one and use a range too, and the final commits may differ, that's why I currently marked the PR as draft, but it should work. |
aee4dee
to
5c246dc
Compare
Some things: I noticed that with I also noticed I forgot to disable deluxe mapping when vertex lighting is enabled. I want to use grid lighting for world movers, if not enforced, at least optional for the mapper. It would prevent the movers to move with their baked shadow, but get the light color and intensity from their position. That may be another PR anyway. If we want to keep grid lighting and vertex ligthing not a cheat, we may do a |
I finally did a very deep revamp, to make the code more obvious, and relying less on hacks. Especially, I had to add a macro to avoid guessing the information out of other macros in GLSL, this means I had to increase by 1 the amount of macros a single shader can received, but since I also did other rewrites to make sure some macro can exclude themselves, the amount of compiled shaders are exactly the same in the end. All the uses case I wanted to take care about are now working. I still see one bug with a Wolf:ET map but it is not introduced by this code and may even require to dive deeper in Wolf:ET specificity so it's out of topic twice. |
I believe vertex lighting should not be faster than light mapping because the implementation is simply to blend vertex light color while using a white light map, meaning the light map code runs in all cases. All it would do would be to save GPU memory by not uploading light maps. To get a faster implementation one would need to write more GLSL code and more C++ plumbing, which is likely not worth the effort. In all cases the base line is light map and that's not bad as we should focus on that. |
a4021a4
to
0e1e04a
Compare
While doing that work I stumbled on many other bugs (I fixed) like:
|
0e1e04a
to
c8fe3d8
Compare
In fact with latest iteration it even fixes the light rendering of Wolf:ET maps like Oasis (something I was aware for 8 years!) and foliage lighting of Wolf:ET maps like Oasis and Goldrush. I'm now unaware of any remaining map lighting bug. |
096bc0c
to
7c1f84d
Compare
oasis
this branch, vertex lighting used as fallback (what should be done): goldrush
this branch, vertex lighting used as fallback (what should be done): elpaso
this branch, no regression: karith
this branch, no regression: |
chasm
this branch, no regression: hangar28
this branch, no regression, this scene is known to break when moving out of the room with plat23
this branch, models lighting may have subtle differences since features that were wrongly disabled are now enabled: forlorn
this branch, models lighting may have subtle differences since features that were wrongly disabled are now enabled: Actually, the armoury screen is interesting on this one. |
7c1f84d
to
8745dee
Compare
This is now ready for review. I played all my recent games with that branch, and the only things I spotted were fixes, even unexpected ones. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will review more later.
Can you explain the concept of vertex lighting more? I don't understand where the lighting information comes from in that case.
In the BSP file, in the struct storing vertexes, there is an RGBA color field:
Cf. http://www.mralligator.com/q3/#Vertexes Those vertex colors are computed by q3map2 at the same time the light grid and the light maps are computed. It means we have 3 sources of light information for every BSP surface, two directly tied to each surface (lightmap, vertex color), one guessable from the nearby space (lightgrid). The code modified in that PR doesn't process those colors, they are assumed to be already applied by the engine in a way the lightmapping GLSL code can blend with them if the correct operation is set. The reason why I assume that is that we already have other features that require that underlying mechanism to be already working, for example terrain blending. This is the feature we can see in outdoor of Thunder map where rock texture blends with sand texture, or in garden in Station15 map, were grass blends with mud. This terrain blending uses vertex colors as well, more precisely the alpha channel of it, the engine is instructed to use an operation that would use such alpha channel to blend a lightmap stage over an already painted lightmap stage. In case of vertex lighting, what I just do is then to set some color field to black and then zero, and tell the engine is has to use an operation to blend over colors. I assume that color field set in lightmapping C++ code do not carry the vertex color and is only used with some operations with vertex colors (here, probably an addition), hence the need for such color field to be zeroed to get the expected results. The alpha channel appears to also need to be zeroed (transparent) when the vertex lighting has to be applied on a transucent texture. Those values (what operation to set, what color to set for the operation: black, transparent…) were guessed with intuition and some kind of trial & error process as I miss knowledge and understanding of some parts of the engine, but I knew vertex colors should already be applied by the engine and that all I had to do was to find the proper blend operation. Vertex color blending was already implemented (otherwise many features would be broken), what I had to do was to tell the engine to blend textures over such vertex color when vertex lighting is enabled, which is like a 5 line patch. The vertex colors are very likely interpolated somewhere in the engine, this is needed for the terrain blending, and we can see on school map screenshot above some emulation of projected shadow on some models using vertex colors, this can be done by interpolating colors of all we have to emulate a shadow is to darken the surface by interpolate light to dark colors between one point to another (and then, between edges). Everything else in that PR is some very detailed decision code to be make all various lighting mode usables in a single scene, plus other rewrites that makes writing that decision code easier. |
393f71e
to
bc26b38
Compare
I can't also exclude there would be actual hacks in lightgrid code (either in q3map2 map compiler, either in engine), to artificially increase light from lightgrid to workaround the fact models get only one source of light without bouncing and other mechanisms. |
If we want to give users alternate ways of lighting the map, we can give
Like Quake 3 and Tremulous did. Vertex lighting should be no faster than light mapping: we still apply a stub lightmap and we can't avoid that without making the code much more complex, so the computation is as heavy, but it will save GPU memory by not uploading lightmaps. Grid lighting uploads lightgrid instead of lightmap, this may use less GPU memory, but the lightgrid computation is heavier than the lightmap/vertex lighting one. I see no reason to provide a grid lighting option to users for performance purpose (even not counting the fact the compute is broken with overBrightBits). |
I did some tests with some maps, actually the benefit of lightgrid in It looks like the big difference affects newer maps like our official ones, and some others like overthehill viewpos viewpos viewpos rusty default view; lightmap, lightgrid, vertex light: chasm default view; lightmap with deluxemap, lightgrid, vertex light: plat23 default view; lightmap with deluxemap, lightmap, lightgrid, vertex light: |
Enabling deluxemapping makes the map a bit brighter too, but not as strong as using light grid on recent maps. Actually people can already get brighter maps with |
6209376
to
4a252a0
Compare
I added a commit adding an |
This looks ready to me. |
I know one map that glitches with this branch, it's nova. But nova was also glitching with Tremulous OpenGL 1 renderer, so actually glitching is being compatible and rendering things as expected. I don't know yet why nova glitches, but this may be a bug in the map data. In 0.54.1 the glitch was not visible because of a bug disabling the features that glitches. |
We may actually name the cvars |
4a252a0
to
4ed1415
Compare
This sounds far better, I did that. |
I don't think this 'cheat lighting' cvar helps anything. Better to do like
|
OK I used I also turned the black list into a white list. |
That's how every other cheat cvar works. E.g. if you set cg_thirdperson 1 then connect to a server, it gets changed to 0. |
I would prefer to return to previous value but I guess it's not decidable. |
I did as you said. |
9dc00fe
to
d7143f7
Compare
I think this was almost a joke in reference to dretches blending in with the texture used in the hall on that map. |
OK, thanks for the answer. 👍️ |
|
d7143f7
to
58ec296
Compare
Today is a great day! 🎉️ |
Historically we had the
r_vertexLighting
cvar, but we didn't have vertexLighting, in fact we used it as reverse cvar for enabling light mapping:r_vertexLighting 0
: enable light mapping (default)r_vertexLighting 1
: disable light mapping, fallback on grid lightingThis replaces it with
r_lightMode
, with possible values:r_lightMode 0
: fullbrightr_lightMode 1
: vertex lightingr_lightMode 2
: grid lightingr_lightMode 3
: light mapping (default)The only
r_lightMode
values expected to be set by players are1
(vertex lighting) and3
(light mapping), especially since others can be a ways to cheat. To use other light modes one should setr_cheatLightModes
toon
.Vertex lighting does not do less computation than light mapping, but skips the uploading of lightmaps and then save on GPU memory size, it is the only reason why it's not a bad idea to provide it to users.
Light grid is not faster than light mapping, there are more GLSL code to execute, it may uses less GPU memory though, but on 20 years old hardware I got less fps last time I compared. Grid lighting is cheaty because the light grid skips the projected shadow.
Fullbright is cheaty.
The cheat light modes are meant for debugging purposes, to give the developer/mapper the ability to see the map with those various lighting techniques.
Currently the engine uses light mapping on world surfaces and grid lighting on game models (players, buildables, weapons…), that's why we have both light mapping and grid lighting implemented. We also used grid lighting on world surfaces when there is no lightmap for the surface. #990 was an example of bug occurring when there is no fallback for world surfaces without lightmap.
But it is expected world surfaces without lightmap don't use grid lighting but vertex lighting. Why? Because the q3map2 map compiler has an option to skip some lightmaps when the color is very similar to vertex colors. So basically, with that option, if the light is consistent, the surface doesn't get a lightmap, and if the light is not consistent (for example it has a projected shadow), it gets a lightmap. A game like Wolf:ET made strong usage of that technique and some maps had like only half of surfaces having a lightmap. On maps using such optimization, the light guessed from the lightgrid is close to the lightmap one but not equal, it makes the map look checkered, since surfaces lit with lightgrid don't match the surfaces lit with lightmap. We should then use vertex lighting on world surfaces without lightmaps.
Since I needed to implement vertex lighting for those surfaces, it was easy to add this light mode to
r_lightMode
options.