mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-31 07:15:00 +01:00
I can see you
- Add visibility buffer fbo attachment - Write instance id to visbuffer - Move instance id in/out from common to impl shaders
This commit is contained in:
parent
ce51e1f534
commit
77d64aa5a2
9 changed files with 151 additions and 14 deletions
|
@ -49,6 +49,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
private final MatrixBuffer matrixBuffer;
|
private final MatrixBuffer matrixBuffer;
|
||||||
|
|
||||||
private final DepthPyramid depthPyramid;
|
private final DepthPyramid depthPyramid;
|
||||||
|
private final VisibilityBuffer visibilityBuffer;
|
||||||
|
|
||||||
private boolean needsBarrier = false;
|
private boolean needsBarrier = false;
|
||||||
|
|
||||||
|
@ -64,6 +65,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
matrixBuffer = new MatrixBuffer();
|
matrixBuffer = new MatrixBuffer();
|
||||||
|
|
||||||
depthPyramid = new DepthPyramid(programs.getDepthReduceProgram());
|
depthPyramid = new DepthPyramid(programs.getDepthReduceProgram());
|
||||||
|
visibilityBuffer = new VisibilityBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -100,6 +102,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
matrixBuffer.bind();
|
matrixBuffer.bind();
|
||||||
Uniforms.bindAll();
|
Uniforms.bindAll();
|
||||||
|
|
||||||
|
visibilityBuffer.attach();
|
||||||
|
|
||||||
if (needsBarrier) {
|
if (needsBarrier) {
|
||||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
||||||
needsBarrier = false;
|
needsBarrier = false;
|
||||||
|
@ -111,6 +115,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
|
|
||||||
MaterialRenderState.reset();
|
MaterialRenderState.reset();
|
||||||
TextureBinder.resetLightAndOverlay();
|
TextureBinder.resetLightAndOverlay();
|
||||||
|
|
||||||
|
visibilityBuffer.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +191,10 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
crumblingDrawBuffer.delete();
|
crumblingDrawBuffer.delete();
|
||||||
|
|
||||||
programs.release();
|
programs.release();
|
||||||
|
|
||||||
|
depthPyramid.delete();
|
||||||
|
|
||||||
|
visibilityBuffer.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
|
public void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks) {
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
package dev.engine_room.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||||
|
import dev.engine_room.flywheel.backend.gl.GlTextureUnit;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
|
public class VisibilityBuffer {
|
||||||
|
private static final int ATTACHMENT = GL30.GL_COLOR_ATTACHMENT1;
|
||||||
|
|
||||||
|
private final int textureId;
|
||||||
|
|
||||||
|
private int lastWidth = -1;
|
||||||
|
private int lastHeight = -1;
|
||||||
|
|
||||||
|
private final IntSet attached = new IntArraySet();
|
||||||
|
|
||||||
|
public VisibilityBuffer() {
|
||||||
|
textureId = GL32.glGenTextures();
|
||||||
|
|
||||||
|
GlStateManager._bindTexture(textureId);
|
||||||
|
GlStateManager._texParameter(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST);
|
||||||
|
GlStateManager._texParameter(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST);
|
||||||
|
GlStateManager._texParameter(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_EDGE);
|
||||||
|
GlStateManager._texParameter(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attach() {
|
||||||
|
// TODO: clear the vis buffer. maybe do this when we read it?
|
||||||
|
|
||||||
|
var mainRenderTarget = Minecraft.getInstance()
|
||||||
|
.getMainRenderTarget();
|
||||||
|
|
||||||
|
setupTexture(mainRenderTarget.width, mainRenderTarget.height);
|
||||||
|
|
||||||
|
if (attached.add(mainRenderTarget.frameBufferId)) {
|
||||||
|
GL46.glNamedFramebufferTexture(mainRenderTarget.frameBufferId, ATTACHMENT, textureId, 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mainRenderTarget.checkStatus();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FlwBackend.LOGGER.error("Error attaching visbuffer", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable writes
|
||||||
|
GL46.glNamedFramebufferDrawBuffers(mainRenderTarget.frameBufferId, new int[] { GL30.GL_COLOR_ATTACHMENT0, ATTACHMENT });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void detach() {
|
||||||
|
var mainRenderTarget = Minecraft.getInstance()
|
||||||
|
.getMainRenderTarget();
|
||||||
|
|
||||||
|
// Disable writes
|
||||||
|
GL46.glNamedFramebufferDrawBuffers(mainRenderTarget.frameBufferId, new int[] { GL30.GL_COLOR_ATTACHMENT0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
GL32.glDeleteTextures(textureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupTexture(int width, int height) {
|
||||||
|
if (lastWidth == width && lastHeight == height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to rebind to all fbos because an attachment becomes incomplete when it's resized
|
||||||
|
attached.clear();
|
||||||
|
|
||||||
|
lastWidth = width;
|
||||||
|
lastHeight = height;
|
||||||
|
|
||||||
|
GlTextureUnit.T0.makeActive();
|
||||||
|
GlStateManager._bindTexture(textureId);
|
||||||
|
|
||||||
|
// TODO: DSA texture storage?
|
||||||
|
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R32UI, width, height, 0, GL32.GL_RED_INTEGER, GL32.GL_UNSIGNED_INT, 0);
|
||||||
|
GlStateManager._bindTexture(0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,9 +13,7 @@ uniform sampler2D _flw_crumblingTex;
|
||||||
in vec2 _flw_crumblingTexCoord;
|
in vec2 _flw_crumblingTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flat in uint _flw_instanceID;
|
layout(location = 0) out vec4 _flw_outputColor;
|
||||||
|
|
||||||
out vec4 _flw_outputColor;
|
|
||||||
|
|
||||||
float _flw_diffuseFactor() {
|
float _flw_diffuseFactor() {
|
||||||
if (flw_material.diffuse) {
|
if (flw_material.diffuse) {
|
||||||
|
@ -29,7 +27,7 @@ float _flw_diffuseFactor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _flw_main() {
|
void _flw_main(uint instanceID) {
|
||||||
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
|
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
|
||||||
flw_fragColor = flw_vertexColor * flw_sampleColor;
|
flw_fragColor = flw_vertexColor * flw_sampleColor;
|
||||||
flw_fragOverlay = flw_vertexOverlay;
|
flw_fragOverlay = flw_vertexOverlay;
|
||||||
|
@ -72,7 +70,7 @@ void _flw_main() {
|
||||||
color = vec4(flw_vertexNormal * .5 + .5, 1.);
|
color = vec4(flw_vertexNormal * .5 + .5, 1.);
|
||||||
break;
|
break;
|
||||||
case 2u:
|
case 2u:
|
||||||
color = _flw_id2Color(_flw_instanceID);
|
color = _flw_id2Color(instanceID);
|
||||||
break;
|
break;
|
||||||
case 3u:
|
case 3u:
|
||||||
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
|
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
|
||||||
|
|
|
@ -71,9 +71,7 @@ mat4 _flw_modelMatrix;
|
||||||
mat3 _flw_normalMatrix;
|
mat3 _flw_normalMatrix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flat out uint _flw_instanceID;
|
void _flw_main(in FlwInstance instance) {
|
||||||
|
|
||||||
void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
|
||||||
_flw_layoutVertex();
|
_flw_layoutVertex();
|
||||||
flw_instanceVertex(instance);
|
flw_instanceVertex(instance);
|
||||||
flw_materialVertex();
|
flw_materialVertex();
|
||||||
|
@ -92,6 +90,4 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
||||||
flw_distance = fogDistance(flw_vertexPos.xyz, flw_cameraPos, flw_fogShape);
|
flw_distance = fogDistance(flw_vertexPos.xyz, flw_cameraPos, flw_fogShape);
|
||||||
|
|
||||||
gl_Position = flw_viewProjection * flw_vertexPos;
|
gl_Position = flw_viewProjection * flw_vertexPos;
|
||||||
|
|
||||||
_flw_instanceID = stableInstanceID;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,16 @@
|
||||||
|
|
||||||
flat in uvec3 _flw_packedMaterial;
|
flat in uvec3 _flw_packedMaterial;
|
||||||
|
|
||||||
|
flat in uint _flw_instanceID;
|
||||||
|
|
||||||
|
layout(location = 1) out uint _flw_out_instanceID;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.x;
|
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.x;
|
||||||
_flw_unpackUint2x16(_flw_packedMaterial.y, _flw_uberFogIndex, _flw_uberCutoutIndex);
|
_flw_unpackUint2x16(_flw_packedMaterial.y, _flw_uberFogIndex, _flw_uberCutoutIndex);
|
||||||
_flw_unpackMaterialProperties(_flw_packedMaterial.z, flw_material);
|
_flw_unpackMaterialProperties(_flw_packedMaterial.z, flw_material);
|
||||||
|
|
||||||
_flw_main();
|
_flw_main(_flw_instanceID);
|
||||||
|
|
||||||
|
_flw_out_instanceID = _flw_instanceID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,14 @@ layout(std430, binding = _FLW_MATRIX_BUFFER_BINDING) restrict buffer MatrixBuffe
|
||||||
|
|
||||||
uniform uint _flw_baseDraw;
|
uniform uint _flw_baseDraw;
|
||||||
|
|
||||||
|
// We read the visibility buffer for all culling groups into a single shared buffer.
|
||||||
|
// This offset is used to know where each culling group starts.
|
||||||
|
uniform uint _flw_globalInstanceIdOffset = 0;
|
||||||
|
|
||||||
flat out uvec3 _flw_packedMaterial;
|
flat out uvec3 _flw_packedMaterial;
|
||||||
|
|
||||||
|
flat out uint _flw_instanceID;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
#if __VERSION__ < 460
|
#if __VERSION__ < 460
|
||||||
uint drawIndex = gl_DrawIDARB + _flw_baseDraw;
|
uint drawIndex = gl_DrawIDARB + _flw_baseDraw;
|
||||||
|
@ -49,5 +55,8 @@ void main() {
|
||||||
#endif
|
#endif
|
||||||
FlwInstance instance = _flw_unpackInstance(instanceIndex);
|
FlwInstance instance = _flw_unpackInstance(instanceIndex);
|
||||||
|
|
||||||
_flw_main(instance, instanceIndex);
|
_flw_main(instance);
|
||||||
|
|
||||||
|
// Add 1 because a 0 instance id means null.
|
||||||
|
_flw_instanceID = _flw_globalInstanceIdOffset + instanceIndex + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
layout(local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform usampler2D visBuffer;
|
||||||
|
|
||||||
|
layout(std430) restrict buffer VisibleFlagBuffer {
|
||||||
|
uint _flw_visibleFlag[];
|
||||||
|
};
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
uint instanceID = texelFetch(visBuffer, ivec2(gl_GlobalInvocationID.xy), 0).r;
|
||||||
|
|
||||||
|
// Null instance id.
|
||||||
|
if (instanceID == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust for null to find the actual index.
|
||||||
|
instanceID = instanceID - 1;
|
||||||
|
|
||||||
|
uint index = instanceID >> 5;
|
||||||
|
|
||||||
|
uint mask = 1u << (instanceID & 31u);
|
||||||
|
|
||||||
|
atomicOr(_flw_visibleFlag[index], mask);
|
||||||
|
}
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
uniform uvec4 _flw_packedMaterial;
|
uniform uvec4 _flw_packedMaterial;
|
||||||
|
|
||||||
|
flat in uint _flw_instanceID;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.y;
|
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.y;
|
||||||
_flw_unpackUint2x16(_flw_packedMaterial.z, _flw_uberFogIndex, _flw_uberCutoutIndex);
|
_flw_unpackUint2x16(_flw_packedMaterial.z, _flw_uberFogIndex, _flw_uberCutoutIndex);
|
||||||
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
||||||
|
|
||||||
_flw_main();
|
_flw_main(_flw_instanceID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ uniform mat4 _flw_modelMatrixUniform;
|
||||||
uniform mat3 _flw_normalMatrixUniform;
|
uniform mat3 _flw_normalMatrixUniform;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
flat out uint _flw_instanceID;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_flw_uberMaterialVertexIndex = _flw_packedMaterial.x;
|
_flw_uberMaterialVertexIndex = _flw_packedMaterial.x;
|
||||||
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
||||||
|
@ -21,5 +23,7 @@ void main() {
|
||||||
_flw_normalMatrix = _flw_normalMatrixUniform;
|
_flw_normalMatrix = _flw_normalMatrixUniform;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_flw_main(instance, uint(gl_InstanceID));
|
_flw_main(instance);
|
||||||
|
|
||||||
|
_flw_instanceID = gl_InstanceID;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue