Skip to content

Commit 7412e14

Browse files
authored
Add Z-Compression shader to better use position buffer's FP16 (scp-fs2open#7245)
1 parent 8e44f35 commit 7412e14

8 files changed

Lines changed: 112 additions & 9 deletions

File tree

code/def_files/data/effects/deferred-f.sdr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "lighting.sdr" //! #include "lighting.sdr"
33
#include "gamma.sdr" //! #include "gamma.sdr"
44
#include "shadows.sdr" //! #include "shadows.sdr"
5+
#include "z-compress.sdr" //! #include "z-compress.sdr"
56

67
out vec4 fragOut0;
78

@@ -219,7 +220,7 @@ void main()
219220
{
220221
vec2 screenPos = gl_FragCoord.xy * vec2(invScreenWidth, invScreenHeight);
221222
vec4 position_buffer = texture(PositionBuffer, screenPos);
222-
vec3 position = position_buffer.xyz;
223+
vec3 position = vec3(position_buffer.xy, uncompress_depth_value(position_buffer.z));
223224

224225
if(abs(dot(position, position)) < nearPlane * nearPlane)
225226
discard;

code/def_files/data/effects/effect-f.sdr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
#include "gamma.sdr"
3+
#include "z-compress.sdr"
34

45
in float fragRadius;
56
in vec4 fragPosition;
@@ -38,7 +39,7 @@ void main()
3839
float sceneDepthLinear;
3940
float fragDepthLinear;
4041
if ( linear_depth == 1 ) {
41-
sceneDepthLinear = -sceneDepth.z;
42+
sceneDepthLinear = -uncompress_depth_value(sceneDepth.z);
4243
fragDepthLinear = -fragPosition.z;
4344
} else {
4445
sceneDepthLinear = ( 2.0 * farZ * nearZ ) / ( farZ + nearZ - sceneDepth.x * (farZ-nearZ) );

code/def_files/data/effects/main-f.sdr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "shadows.sdr" //! #include "shadows.sdr"
33
#include "lighting.sdr" //! #include "lighting.sdr"
44
#include "gamma.sdr" //! #include "gamma.sdr"
5+
#include "z-compress.sdr" //! #include "z-compress.sdr"
56

67
#conditional_include +"LARGE_SHADER" "main_large.sdr"
78
#conditional_include -"LARGE_SHADER" "main_small.sdr"
@@ -428,7 +429,7 @@ void main()
428429
fragOut0 = baseColor;
429430

430431
#prereplace IF_FLAG MODEL_SDR_FLAG_DEFERRED
431-
fragOut1 = vec4(vertIn.position.xyz, aoFactors.x);
432+
fragOut1 = vec4(vertIn.position.xy, compress_depth_value(vertIn.position.z), aoFactors.x);
432433
fragOut2 = vec4(normal, glossData);
433434
fragOut3 = vec4(specColor.rgb, fresnelFactor);
434435
fragOut4 = emissiveColor;

code/def_files/data/effects/msaa-f.sdr

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include "z-compress.sdr"
2+
13
in vec4 fragTexCoord;
24
out vec4 fragOut0;
35
out vec4 fragOut1;
@@ -32,7 +34,7 @@ float getMedianDist(ivec2 texel) {
3234
float dists[4];
3335

3436
for(int i = 0; i < 4; i++) {
35-
dists[i] = texelFetch(texPos, texel, i).z;
37+
dists[i] = uncompress_depth_value(texelFetch(texPos, texel, i).z);
3638
}
3739

3840
SORT(0, 2)
@@ -51,7 +53,7 @@ float getMedianDist(ivec2 texel) {
5153
float dists[8];
5254

5355
for(int i = 0; i < 8; i++) {
54-
dists[i] = texelFetch(texPos, texel, i).z;
56+
dists[i] = uncompress_depth_value(texelFetch(texPos, texel, i).z);
5557
}
5658

5759
SORT(0, 4)
@@ -82,7 +84,7 @@ float getMedianDist(ivec2 texel) {
8284
float dists[16];
8385

8486
for(int i = 0; i < 16; i++) {
85-
dists[i] = texelFetch(texPos, texel, i).z;
87+
dists[i] = uncompress_depth_value(texelFetch(texPos, texel, i).z);
8688
}
8789

8890
SORT(0, 1)
@@ -145,7 +147,7 @@ float getMedianDist(ivec2 texel) {
145147
float getMedianDist(ivec2 texel) {
146148
float minDist = -1000000;
147149
for(int i = 0; i < samples; i++) {
148-
minDist = max(minDist, texelFetch(texPos, texel, i).z);
150+
minDist = max(minDist, uncompress_depth_value(texelFetch(texPos, texel, i).z));
149151
}
150152
return minDist;
151153
}
@@ -173,6 +175,7 @@ void main()
173175

174176
for(int i = 0; i < samples; i++) {
175177
vec4 localPos = texelFetch(texPos, texel, i);
178+
localPos.z = uncompress_depth_value(localPos.z);
176179
//Calculate local weight from distance Voxel, but if the distance is 0 (i.e. no model at all), set weight to 1 to allow stuff like background emissive
177180
//However, if the median distance is 0, only deal with current texel if it's local distance is 0 as well
178181
float localWeight = max(step(-0.001, dist) * step(-0.001, localPos.z),
@@ -189,8 +192,11 @@ void main()
189192
weight += localWeight;
190193
}
191194

195+
pos /= weight;
196+
pos.z = compress_depth_value(pos.z);
197+
192198
fragOut0 = color / weight;
193-
fragOut1 = pos / weight;
199+
fragOut1 = pos;
194200
fragOut2 = vec4(normalize(normal.xyz), normal.a / weight);
195201
fragOut3 = specular / weight;
196202
fragOut4 = emissive / weight;
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
float compress_depth_value(float linear) {
2+
float linear_mult;
3+
float exponent_mult;
4+
float offset;
5+
6+
linear = max(-linear, 0.0);
7+
8+
if(linear < 10.0) {
9+
linear_mult = 0.00000999908;
10+
exponent_mult = 1.32878452580;
11+
offset = 0.0;
12+
}
13+
else if (linear < 100.0) {
14+
linear_mult = 0.05550473078;
15+
exponent_mult = 0.08493173544;
16+
offset = 0.0;
17+
}
18+
else if (linear < 1570.0) {
19+
linear_mult = 11.53589613947;
20+
exponent_mult = 0.00793869919;
21+
offset = 0.0;
22+
}
23+
else if (linear < 3000.0) {
24+
linear_mult = -0.10000000000;
25+
exponent_mult = 0.00928910863;
26+
offset = 3000.0;
27+
}
28+
else if (linear < 10000.0) {
29+
linear_mult = -0.10000000000;
30+
exponent_mult = 0.00094912231;
31+
offset = 3000.0;
32+
}
33+
else if (linear < 100000.0) {
34+
linear_mult = -6.98947320727;
35+
exponent_mult = 0.00007382062;
36+
offset = 3000.0;
37+
}
38+
else {
39+
linear_mult = -1000.0;
40+
exponent_mult = log2(1000.0 / 65000.0) / (100000.0 - GLOBAL_FAR_Z);
41+
offset = 100000.0;
42+
}
43+
44+
return linear_mult * pow(2.0, (linear - offset) * exponent_mult);
45+
}
46+
47+
float uncompress_depth_value(float compressed) {
48+
float linear_mult;
49+
float exponent_mult;
50+
float offset;
51+
52+
if(compressed < -1000.0) {
53+
linear_mult = -1000.0;
54+
exponent_mult = log2(1000.0 / 65000.0) / (100000.0 - GLOBAL_FAR_Z);
55+
offset = 100000.0;
56+
}
57+
else if (compressed < -10.0) {
58+
linear_mult = -6.98947320727;
59+
exponent_mult = 0.00007382062;
60+
offset = 3000.0;
61+
}
62+
else if (compressed < -0.1) {
63+
linear_mult = -0.10000000000;
64+
exponent_mult = 0.00094912231;
65+
offset = 3000.0;
66+
}
67+
else if (compressed < 0.0) {
68+
linear_mult = -0.10000000000;
69+
exponent_mult = 0.00928910863;
70+
offset = 3000.0;
71+
}
72+
else if (compressed < 0.1) {
73+
linear_mult = 0.00000999908;
74+
exponent_mult = 1.32878452580;
75+
offset = 0.0;
76+
}
77+
else if (compressed < 20.0) {
78+
linear_mult = 0.05550473078;
79+
exponent_mult = 0.08493173544;
80+
offset = 0.0;
81+
}
82+
else {
83+
linear_mult = 11.53589613947;
84+
exponent_mult = 0.00793869919;
85+
offset = 0.0;
86+
}
87+
88+
return -(log2(compressed / linear_mult) / exponent_mult + offset);
89+
}

code/graphics/2d.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ int gr_stencil_mode = 0;
283283

284284
// Default clipping distances
285285
const float Default_min_draw_distance = 1.0f;
286-
const float Default_max_draw_distance = 1e10;
286+
// Reduced from 1e10 to 1e6, as beyond that FSO's physics precision is horrendous anyways, and it allows reasonable lighting and particle clipping all the way out until that point, unlike 1e7 or above where the depth precision just is not enough
287+
const float Default_max_draw_distance = 1e6f;
287288
float Min_draw_distance_cockpit = 0.02f;
288289
float Min_draw_distance = Default_min_draw_distance;
289290
float Max_draw_distance = Default_max_draw_distance;

code/graphics/opengl/gropenglshader.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,9 @@ static SCP_string handle_predefines(const char* filename, const SCP_string& orig
503503
SCP_stringstream output;
504504
SCP_unordered_map<SCP_string, SCP_string> defines;
505505

506+
//In any shader, define GLOBAL_FAR_Z
507+
output << "#define GLOBAL_FAR_Z " << std::fixed << std::setprecision(2) << Max_draw_distance << std::defaultfloat << '\n';
508+
506509
const char* PREDEFINE_STRING = "#predefine";
507510
const char* PREREPLACE_STRING = "#prereplace";
508511

code/source_groups.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ add_file_folder("Default files\\\\data\\\\effects"
278278
def_files/data/effects/video-f.sdr
279279
def_files/data/effects/video-v.sdr
280280
def_files/data/effects/volumetric-f.sdr
281+
def_files/data/effects/z-compress.sdr
281282
)
282283

283284
add_file_folder("Default files\\\\data\\\\maps"

0 commit comments

Comments
 (0)