Skip to content

Commit fe55693

Browse files
committed
Cleanups and depth
- Centralized wavelet code and roughly document - Add a full screen pass to render the depth at which transmittance falls to zero
1 parent 8407d20 commit fe55693

File tree

8 files changed

+307
-189
lines changed

8 files changed

+307
-189
lines changed

common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class IndirectPrograms extends AtomicReferenceCounted {
3434

3535
private static final ResourceLocation FULLSCREEN = Flywheel.rl("internal/indirect/fullscreen.vert");
3636
private static final ResourceLocation OIT_COMPOSITE = Flywheel.rl("internal/indirect/oit_composite.frag");
37+
private static final ResourceLocation OIT_DEPTH = Flywheel.rl("internal/indirect/oit_depth.frag");
3738

3839
private static final Compile<InstanceType<?>> CULL = new Compile<>();
3940
private static final Compile<ResourceLocation> UTIL = new Compile<>();
@@ -138,6 +139,7 @@ private static CompilationHarness<ResourceLocation> createFullscreenCompiler(Sha
138139
.link(UTIL.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.FRAGMENT)
139140
.nameMapper(rl -> "fullscreen/" + ResourceUtil.toDebugFileNameNoExtension(rl))
140141
.withResource(s -> s))
142+
.postLink((key, program) -> Uniforms.setUniformBlockBindings(program))
141143
.harness("fullscreen", sources);
142144
}
143145

@@ -192,6 +194,10 @@ public GlProgram getOitCompositeProgram() {
192194
return fullscreen.get(OIT_COMPOSITE);
193195
}
194196

197+
public GlProgram getOitDepthProgram() {
198+
return fullscreen.get(OIT_DEPTH);
199+
}
200+
195201
@Override
196202
protected void _delete() {
197203
pipeline.delete();

common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor
158158
group.submitTransparent(PipelineCompiler.OitMode.GENERATE_COEFFICIENTS);
159159
}
160160

161-
// wboitFrameBuffer.adjustBackgroundForTotalTransmittance();
161+
wboitFrameBuffer.renderDepth();
162162

163-
// vertexArray.bindForDraw();
163+
vertexArray.bindForDraw();
164164

165165
wboitFrameBuffer.shade();
166166

common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/OitFramebuffer.java

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414

1515
public class OitFramebuffer {
1616

17-
public final int fbo;
1817
private final IndirectPrograms programs;
1918
private final int vao;
2019

21-
public int depthBounds;
22-
public int coefficients;
23-
public int accumulate;
20+
public int fbo = -1;
21+
public int depthBounds = -1;
22+
public int coefficients = -1;
23+
public int accumulate = -1;
2424

2525
private int lastWidth = -1;
2626
private int lastHeight = -1;
@@ -39,6 +39,7 @@ public void depthRange() {
3939

4040
// No depth writes, but we'll still use the depth test
4141
RenderSystem.depthMask(false);
42+
RenderSystem.colorMask(true, true, true, true);
4243
RenderSystem.enableBlend();
4344
RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE);
4445
RenderSystem.blendEquation(GL46.GL_MAX);
@@ -57,6 +58,7 @@ public void depthRange() {
5758
public void renderTransmittance() {
5859
// No depth writes, but we'll still use the depth test
5960
RenderSystem.depthMask(false);
61+
RenderSystem.colorMask(true, true, true, true);
6062
RenderSystem.enableBlend();
6163
RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE);
6264
RenderSystem.blendEquation(GL46.GL_FUNC_ADD);
@@ -85,6 +87,7 @@ public void renderTransmittance() {
8587
public void shade() {
8688
// No depth writes, but we'll still use the depth test
8789
RenderSystem.depthMask(false);
90+
RenderSystem.colorMask(true, true, true, true);
8891
RenderSystem.enableBlend();
8992
RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE);
9093
RenderSystem.blendEquation(GL46.GL_FUNC_ADD);
@@ -106,9 +109,34 @@ public void shade() {
106109
GlStateManager._glBindFramebuffer(GL46.GL_FRAMEBUFFER, fbo);
107110
}
108111

112+
public void renderDepth() {
113+
// No depth writes, but we'll still use the depth test
114+
RenderSystem.depthMask(true);
115+
RenderSystem.colorMask(false, false, false, false);
116+
RenderSystem.disableBlend();
117+
118+
Samplers.COEFFICIENTS.makeActive();
119+
GlStateManager._bindTexture(0);
120+
GL46.glBindTextureUnit(0, coefficients);
121+
122+
Samplers.DEPTH_RANGE.makeActive();
123+
GlStateManager._bindTexture(depthBounds);
124+
125+
GL46.glNamedFramebufferDrawBuffers(fbo, new int[]{});
126+
127+
programs.getOitDepthProgram()
128+
.bind();
129+
130+
// Empty VAO, the actual full screen triangle is generated in the vertex shader
131+
GlStateManager._glBindVertexArray(vao);
132+
133+
GL46.glDrawArrays(GL46.GL_TRIANGLES, 0, 3);
134+
}
135+
109136
public void composite() {
110137
// No depth writes, but we'll still use the depth test
111138
RenderSystem.depthMask(false);
139+
RenderSystem.colorMask(true, true, true, true);
112140
RenderSystem.enableBlend();
113141
RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.DestFactor.SRC_ALPHA);
114142
RenderSystem.blendEquation(GL46.GL_FUNC_ADD);
@@ -141,9 +169,15 @@ public void delete() {
141169
}
142170

143171
private void deleteTextures() {
144-
GL46.glDeleteTextures(depthBounds);
145-
GL46.glDeleteTextures(coefficients);
146-
GL46.glDeleteTextures(accumulate);
172+
if (depthBounds != -1) {
173+
GL46.glDeleteTextures(depthBounds);
174+
}
175+
if (coefficients != -1) {
176+
GL46.glDeleteTextures(coefficients);
177+
}
178+
if (accumulate != -1) {
179+
GL46.glDeleteTextures(accumulate);
180+
}
147181
}
148182

149183
private void createTextures(int width, int height) {

common/src/backend/resources/assets/flywheel/flywheel/internal/common.frag

Lines changed: 4 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "flywheel:internal/packed_material.glsl"
22
#include "flywheel:internal/diffuse.glsl"
33
#include "flywheel:internal/colorizer.glsl"
4+
#include "flywheel:internal/wavelet.glsl"
5+
#include "flywheel:internal/depth.glsl"
46

57
// optimize discard usage
68
#if defined(GL_ARB_conservative_depth) && defined(_FLW_USE_DISCARD)
@@ -19,10 +21,6 @@ flat in uvec2 _flw_ids;
1921

2022
#ifdef _FLW_OIT
2123

22-
#define TRANSPARENCY_WAVELET_RANK 3
23-
#define TRANSPARENCY_WAVELET_COEFFICIENT_COUNT 16
24-
#define REMOVE_SIGNAL true
25-
2624
layout (binding = 7) uniform sampler2D _flw_depthRange;
2725

2826
layout (binding = 8) uniform sampler2DArray _flw_coefficients;
@@ -44,11 +42,6 @@ float tented_blue_noise(float normalizedDepth) {
4442
return b * tent;
4543
}
4644

47-
float linearize_depth(float d, float zNear, float zFar) {
48-
float z_n = 2.0 * d - 1.0;
49-
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
50-
}
51-
5245
float linear_depth() {
5346
return linearize_depth(gl_FragCoord.z, _flw_cullData.znear, _flw_cullData.zfar);
5447
}
@@ -69,126 +62,19 @@ layout (location = 0) out vec2 _flw_depthRange_out;
6962

7063
#endif
7164

72-
7365
#ifdef _FLW_COLLECT_COEFFS
7466

75-
7667
layout (location = 0) out vec4 _flw_coeffs0;
7768
layout (location = 1) out vec4 _flw_coeffs1;
7869
layout (location = 2) out vec4 _flw_coeffs2;
7970
layout (location = 3) out vec4 _flw_coeffs3;
8071

81-
void add_to_index(inout vec4[4] coefficients, uint index, float addend) {
82-
coefficients[index >> 2][index & 3u] = addend;
83-
}
84-
85-
void add_event_to_wavelets(inout vec4[4] coefficients, float signal, float depth)
86-
{
87-
depth *= float(TRANSPARENCY_WAVELET_COEFFICIENT_COUNT-1) / TRANSPARENCY_WAVELET_COEFFICIENT_COUNT;
88-
89-
int index = clamp(int(floor(depth * TRANSPARENCY_WAVELET_COEFFICIENT_COUNT)), 0, TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1);
90-
index += TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1;
91-
92-
for (int i = 0; i < (TRANSPARENCY_WAVELET_RANK+1); ++i)
93-
{
94-
int power = TRANSPARENCY_WAVELET_RANK - i;
95-
int new_index = (index - 1) >> 1;
96-
float k = float((new_index + 1) & ((1 << power) - 1));
97-
98-
int wavelet_sign = ((index & 1) << 1) - 1;
99-
float wavelet_phase = ((index + 1) & 1) * exp2(-power);
100-
float addend = fma(fma(-exp2(-power), k, depth), wavelet_sign, wavelet_phase) * exp2(power * 0.5) * signal;
101-
add_to_index(coefficients, new_index, addend);
102-
103-
index = new_index;
104-
}
105-
106-
float addend = fma(signal, -depth, signal);
107-
add_to_index(coefficients, TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1, addend);
108-
}
109-
110-
void add_transmittance_event_to_wavelets(inout vec4[4] coefficients, float transmittance, float depth)
111-
{
112-
float absorbance = -log(max(transmittance, 0.00001));// transforming the signal from multiplicative transmittance to additive absorbance
113-
add_event_to_wavelets(coefficients, absorbance, depth);
114-
}
115-
11672
#endif
11773

11874
#ifdef _FLW_EVALUATE
11975

12076
layout (location = 0) out vec4 _flw_accumulate;
12177

122-
123-
float get_coefficients(in sampler2DArray coefficients, uint index) {
124-
return texelFetch(coefficients, ivec3(gl_FragCoord.xy, index >> 2), 0)[index & 3u];
125-
}
126-
127-
float evaluate_wavelets(in sampler2DArray coefficients, float depth, float signal)
128-
{
129-
float scale_coefficient = get_coefficients(coefficients, TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1);
130-
if (scale_coefficient == 0)
131-
{
132-
return 0;
133-
}
134-
135-
depth *= float(TRANSPARENCY_WAVELET_COEFFICIENT_COUNT-1) / TRANSPARENCY_WAVELET_COEFFICIENT_COUNT;
136-
137-
if (REMOVE_SIGNAL)
138-
{
139-
float scale_coefficient_addend = fma(signal, -depth, signal);
140-
scale_coefficient -= scale_coefficient_addend;
141-
}
142-
143-
float coefficient_depth = depth * TRANSPARENCY_WAVELET_COEFFICIENT_COUNT;
144-
int index_b = clamp(int(floor(coefficient_depth)), 0, TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1);
145-
bool sample_a = index_b >= 1;
146-
int index_a = sample_a ? (index_b - 1) : index_b;
147-
148-
index_b += TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1;
149-
index_a += TRANSPARENCY_WAVELET_COEFFICIENT_COUNT - 1;
150-
151-
float b = scale_coefficient;
152-
float a = sample_a ? scale_coefficient : 0;
153-
154-
for (int i = 0; i < (TRANSPARENCY_WAVELET_RANK+1); ++i)
155-
{
156-
int power = TRANSPARENCY_WAVELET_RANK - i;
157-
158-
int new_index_b = (index_b - 1) >> 1;
159-
int wavelet_sign_b = ((index_b & 1) << 1) - 1;
160-
float coeff_b = get_coefficients(coefficients, new_index_b);
161-
if (REMOVE_SIGNAL)
162-
{
163-
float wavelet_phase_b = ((index_b + 1) & 1) * exp2(-power);
164-
float k = float((new_index_b + 1) & ((1 << power) - 1));
165-
float addend = fma(fma(-exp2(-power), k, depth), wavelet_sign_b, wavelet_phase_b) * exp2(power * 0.5) * signal;
166-
coeff_b -= addend;
167-
}
168-
b -= exp2(float(power) * 0.5) * coeff_b * wavelet_sign_b;
169-
index_b = new_index_b;
170-
171-
if (sample_a)
172-
{
173-
int new_index_a = (index_a - 1) >> 1;
174-
int wavelet_sign_a = ((index_a & 1) << 1) - 1;
175-
float coeff_a = (new_index_a == new_index_b) ? coeff_b : get_coefficients(coefficients, new_index_a);// No addend here on purpose, the original signal didn't contribute to this coefficient
176-
a -= exp2(float(power) * 0.5) * coeff_a * wavelet_sign_a;
177-
index_a = new_index_a;
178-
}
179-
}
180-
181-
float t = coefficient_depth >= TRANSPARENCY_WAVELET_COEFFICIENT_COUNT ? 1.0 : fract(coefficient_depth);
182-
183-
return mix(a, b, t);
184-
}
185-
186-
float evaluate_transmittance_wavelets(in sampler2DArray coefficients, float depth, float signal)
187-
{
188-
float absorbance = evaluate_wavelets(coefficients, depth, signal);
189-
return clamp(exp(-absorbance), 0., 1.);// undoing the transformation from absorbance back to transmittance
190-
}
191-
19278
#endif
19379

19480
#else
@@ -298,7 +184,7 @@ void _flw_main() {
298184
result[2] = vec4(0.);
299185
result[3] = vec4(0.);
300186

301-
add_transmittance_event_to_wavelets(result, 1. - color.a, depth());
187+
add_transmittance(result, 1. - color.a, depth());
302188

303189
_flw_coeffs0 = result[0];
304190
_flw_coeffs1 = result[1];
@@ -309,7 +195,7 @@ void _flw_main() {
309195

310196
#ifdef _FLW_EVALUATE
311197

312-
float transmittance = evaluate_transmittance_wavelets(_flw_coefficients, depth(), 1. - color.a);
198+
float transmittance = signal_corrected_transmittance(_flw_coefficients, depth(), 1. - color.a);
313199

314200
_flw_accumulate = vec4(color.rgb * color.a, color.a) * transmittance;
315201

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
float linearize_depth(float d, float zNear, float zFar) {
2+
float z_n = 2.0 * d - 1.0;
3+
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
4+
}
5+
6+
float delinearize_depth(float linearDepth, float zNear, float zFar) {
7+
float z_n = (2.0 * zNear * zFar / linearDepth) - (zFar + zNear);
8+
return 0.5 * (z_n / (zNear - zFar) + 1.0);
9+
}

0 commit comments

Comments
 (0)