Texture this

- Add blue noise texture
This commit is contained in:
Jozufozu 2025-02-21 22:27:05 -08:00
parent 91ffde5cf5
commit 8407d206ba
8 changed files with 97 additions and 76 deletions

View file

@ -0,0 +1,43 @@
package dev.engine_room.flywheel.backend;
import java.io.IOException;
import org.jetbrains.annotations.UnknownNullability;
import com.mojang.blaze3d.platform.NativeImage;
import dev.engine_room.flywheel.api.Flywheel;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
public class NoiseTextures {
public static final ResourceLocation NOISE_TEXTURE = Flywheel.rl("textures/flywheel/noise/blue/0.png");
public static final int NOISE_LAYERS = 16;
@UnknownNullability
public static DynamicTexture BLUE_NOISE;
public static void reload(ResourceManager manager) {
if (BLUE_NOISE != null) {
BLUE_NOISE.close();
BLUE_NOISE = null;
}
var optional = manager.getResource(NOISE_TEXTURE);
if (optional.isEmpty()) {
return;
}
try (var is = optional.get()
.open()) {
var image = NativeImage.read(NativeImage.Format.LUMINANCE, is);
BLUE_NOISE = new DynamicTexture(image);
} catch (IOException e) {
}
}
}

View file

@ -13,4 +13,5 @@ public class Samplers {
public static final GlTextureUnit DEPTH_RANGE = GlTextureUnit.T7;
public static final GlTextureUnit COEFFICIENTS = GlTextureUnit.T8;
public static final GlTextureUnit NOISE = GlTextureUnit.T9;
}

View file

@ -222,7 +222,7 @@ public class IndirectCullingGroup<I extends Instance> {
// Don't need to do this unless the program changes.
drawProgram.bind();
drawProgram.setFloat("_flw_blueNoiseFactor", 0.08f);
drawProgram.setFloat("_flw_blueNoiseFactor", 0.07f);
}
MaterialRenderState.setupOit(multiDraw.material);

View file

@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL46;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.engine_room.flywheel.backend.NoiseTextures;
import dev.engine_room.flywheel.backend.Samplers;
import dev.engine_room.flywheel.backend.compile.IndirectPrograms;
import dev.engine_room.flywheel.backend.gl.GlTextureUnit;
@ -63,6 +64,14 @@ public class OitFramebuffer {
Samplers.DEPTH_RANGE.makeActive();
GlStateManager._bindTexture(depthBounds);
Samplers.NOISE.makeActive();
NoiseTextures.BLUE_NOISE.bind();
NoiseTextures.BLUE_NOISE.setFilter(true, false);
GL46.glTextureParameteri(NoiseTextures.BLUE_NOISE.getId(), GL32.GL_TEXTURE_WRAP_S, GL32.GL_REPEAT);
GL46.glTextureParameteri(NoiseTextures.BLUE_NOISE.getId(), GL32.GL_TEXTURE_WRAP_T, GL32.GL_REPEAT);
GL46.glNamedFramebufferDrawBuffers(fbo, new int[]{GL46.GL_COLOR_ATTACHMENT1, GL46.GL_COLOR_ATTACHMENT2, GL46.GL_COLOR_ATTACHMENT3, GL46.GL_COLOR_ATTACHMENT4});
GL46.glClearNamedFramebufferfv(fbo, GL46.GL_COLOR, 0, new float[]{0, 0, 0, 0});
@ -85,9 +94,11 @@ public class OitFramebuffer {
Samplers.COEFFICIENTS.makeActive();
GlStateManager._bindTexture(0);
GL46.glBindTextureUnit(Samplers.COEFFICIENTS.number, coefficients);
Samplers.NOISE.makeActive();
NoiseTextures.BLUE_NOISE.bind();
GL46.glNamedFramebufferDrawBuffers(fbo, new int[]{GL46.GL_COLOR_ATTACHMENT5});
GL46.glClearNamedFramebufferfv(fbo, GL46.GL_COLOR, 0, new float[]{0, 0, 0, 0});

View file

@ -27,6 +27,42 @@ layout (binding = 7) uniform sampler2D _flw_depthRange;
layout (binding = 8) uniform sampler2DArray _flw_coefficients;
layout (binding = 9) uniform sampler2D _flw_blueNoise;
uniform float _flw_blueNoiseFactor = 0.08;
float tented_blue_noise(float normalizedDepth) {
float tentIn = abs(normalizedDepth * 2. - 1);
float tentIn2 = tentIn * tentIn;
float tentIn4 = tentIn2 * tentIn2;
float tent = 1 - (tentIn2 * tentIn4);
float b = texture(_flw_blueNoise, gl_FragCoord.xy / vec2(64)).r;
return b * tent;
}
float linearize_depth(float d, float zNear, float zFar) {
float z_n = 2.0 * d - 1.0;
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}
float linear_depth() {
return linearize_depth(gl_FragCoord.z, _flw_cullData.znear, _flw_cullData.zfar);
}
float depth() {
float linearDepth = linear_depth();
vec2 depthRange = texelFetch(_flw_depthRange, ivec2(gl_FragCoord.xy), 0).rg;
float delta = depthRange.x + depthRange.y;
float depth = (linearDepth + depthRange.x) / delta;
return depth - tented_blue_noise(depth) * _flw_blueNoiseFactor;
}
#ifdef _FLW_DEPTH_RANGE
layout (location = 0) out vec2 _flw_depthRange_out;
@ -155,80 +191,6 @@ float evaluate_transmittance_wavelets(in sampler2DArray coefficients, float dept
#endif
// TODO: blue noise texture
uint HilbertIndex(uvec2 p) {
uint i = 0u;
for (uint l = 0x4000u; l > 0u; l >>= 1u) {
uvec2 r = min(p & l, 1u);
i = (i << 2u) | ((r.x * 3u) ^ r.y);
p = r.y == 0u ? (0x7FFFu * r.x) ^ p.yx : p;
}
return i;
}
uint ReverseBits(uint x) {
x = ((x & 0xaaaaaaaau) >> 1) | ((x & 0x55555555u) << 1);
x = ((x & 0xccccccccu) >> 2) | ((x & 0x33333333u) << 2);
x = ((x & 0xf0f0f0f0u) >> 4) | ((x & 0x0f0f0f0fu) << 4);
x = ((x & 0xff00ff00u) >> 8) | ((x & 0x00ff00ffu) << 8);
return (x >> 16) | (x << 16);
}
// from: https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
uint OwenHash(uint x, uint seed) { // seed is any random number
x ^= x * 0x3d20adeau;
x += seed;
x *= (seed >> 16) | 1u;
x ^= x * 0x05526c56u;
x ^= x * 0x53a22864u;
return x;
}
// https://www.shadertoy.com/view/ssBBW1
float blue() {
uint m = HilbertIndex(uvec2(gl_FragCoord.xy));// map pixel coords to hilbert curve index
m = OwenHash(ReverseBits(m), 0xe7843fbfu);// owen-scramble hilbert index
m = OwenHash(ReverseBits(m), 0x8d8fb1e0u);// map hilbert index to sobol sequence and owen-scramble
float mask = float(ReverseBits(m)) / 4294967296.0;// convert to float
return mask;
}
uniform float _flw_blueNoiseFactor = 0.08;
float tented_blue_noise(float normalizedDepth) {
float tentIn = abs(normalizedDepth * 2. - 1);
float tentIn2 = tentIn * tentIn;
float tentIn4 = tentIn2 * tentIn2;
float tent = 1 - (tentIn2 * tentIn4);
float b = blue();
return b * tent;
}
float linearize_depth(float d, float zNear, float zFar) {
float z_n = 2.0 * d - 1.0;
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}
float linear_depth() {
return linearize_depth(gl_FragCoord.z, _flw_cullData.znear, _flw_cullData.zfar);
}
float depth() {
float linearDepth = linear_depth();
vec2 depthRange = texelFetch(_flw_depthRange, ivec2(gl_FragCoord.xy), 0).rg;
float delta = depthRange.x + depthRange.y;
float depth = (linearDepth + depthRange.x) / delta;
return depth - tented_blue_noise(depth) * _flw_blueNoiseFactor;
}
#else
out vec4 _flw_outputColor;

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -1,6 +1,7 @@
package dev.engine_room.flywheel.backend.compile;
import dev.engine_room.flywheel.api.Flywheel;
import dev.engine_room.flywheel.backend.NoiseTextures;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
@ -16,6 +17,7 @@ public final class FlwProgramsReloader implements SimpleSynchronousResourceReloa
@Override
public void onResourceManagerReload(ResourceManager manager) {
FlwPrograms.reload(manager);
NoiseTextures.reload(manager);
}
@Override

View file

@ -1,5 +1,6 @@
package dev.engine_room.flywheel.backend.compile;
import dev.engine_room.flywheel.backend.NoiseTextures;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
@ -12,5 +13,6 @@ public final class FlwProgramsReloader implements ResourceManagerReloadListener
@Override
public void onResourceManagerReload(ResourceManager manager) {
FlwPrograms.reload(manager);
NoiseTextures.reload(manager);
}
}