Render fogs with one draw call per fog instead of re-drawing every surface inside#1888
Render fogs with one draw call per fog instead of re-drawing every surface inside#1888slipher wants to merge 11 commits intoDaemonEngine:masterfrom
Conversation
306c81e to
cc477b4
Compare
Add a shader keyword that can be used to configure a gradient for fog density, which tapers to 0 at the edge of the fog. The density of the fog is scaled by a factor of (1 - exp(-k * t)) where t is the distance under the fog plane and k a configurable constant. fogGradient expFalloff <dist> configures the exponential falloff such that the density is at 50% of the maximum at <dist> qu from the fog plane. fogGradient const does the same thing as the current default - no gradient; hard-edged fog.
Make the default gradient like `fogGradient expFalloff 5`. This makes the fogs have softer edges without changing the appearance too much.
This cheat cvar controlled whether the Quake 3 fog shader is used (while leaving the ET global fog unaffected). Instead you can use r_noFog which toggles all fogs.
A shader with a name 58-63 chars long would fail to generate a depth pass shader due to a length check. Add some extra space in the name buffer so this can't happen.
When the viewer is inside a fog volume, render the fog with a single draw call instead of drawing a corresponding fog surface for every opaque surface. The fogGlobal GLSL shader is modified to use a vertex position so it can handle finite-sized fogs. Before: - Each opaque surface inside a fog volume is drawn a second time using the fog shader with GL_EQUAL depth test. - The underside of the fog plane is drawn with a normal depth test, to cover things outside the fog when the viewer is inside. After: - If the viewer is inside the fog, draw all inside faces of the fog brush, using the depth buffer to reduce the fog distance in the case that something is in front of the fog boundary. - If the viewer is outside the fog, do everything as before. For the moment this is only used when material system is disabled. Fixes seams at the edge of fog that appear when MSAA is enabled.
Add a new macro variant of the 'fogGlobal' shader which can be used for fogs that the viewer is outside of. Now when material system is not active, this shader is used for all fogs. The "outside" version of the shader is more complex than the inside one, since it is necessary to trace against all planes of the fog to find the length in fog. This change removes the requirement that a fog be enclosed by opaque walls on all sides except one (the "surface plane"). Now fogs can be rendered (almost) correctly from any side. The exception is that if eye position is very close but not inside the fog, within about 5 qu, the inside fog shader has to be used instead of the outside one to avoid near plane culling. This causes an artifact when passing into the fog through a non-surface side which can be noticed if you look closely.
Use the depth-based fog shaders (currently called "fogGlobal") when the material system is enabled as well. For now they are always run with the 'core' rendering loop. NUKE the fogQuake3 shader and all the code for propagating fog nums with surfaces. Fixes DaemonEngine#1798 (marks drawn over fog with material system) by virtue of not drawing fogs with the material system. Also brings improvements described for the core renderer in previous commits: - MSAA works with fog without artifacts - Fog volumes can be open on any side
Also move the Render_fog function with its friends.
Use CPU-side frustum culling to avoid drawing fogs when possible. Also don't recalculate the near plane distance (for checking if fogs are too close to the camera) every iteration when looping fogs.
|
This is now ready. But stacked on #1889. Functional changes to what is rendered:
There are two variants of the For now all fogs are rendered outside of the material system. Integrating them would be a bit tricky since you have two variants of the shader requiring different GL state, which must be selectively enabled based on the view position. As for performance, the new fog is sadly slower on an Intel UHD 630 I tested. Turns out this is ~entirely due to reading from the depth buffer. I checked this by editing the GLSL. But also it can be seen that on master, with the ET |
Adapt the global fog shader to use a vertex position so it can draw finite-sized fogs. Right now it is only implemented for fogs that the viewer is inside of, but this is enough to fix the artifacts with MSAA as in #1480 (comment). Later I will update the PR with commits to draw fogs the viewer is outside of this way as well.