refactor abstract shader base class and ssao renderer
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOApplyShader;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOShader;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class SSAORenderer
|
||||
{
|
||||
public static SSAORenderer INSTANCE = new SSAORenderer();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
|
||||
private boolean init = false;
|
||||
|
||||
private int width = -1;
|
||||
private int height = -1;
|
||||
private int ssaoFramebuffer = -1;
|
||||
|
||||
private int ssaoTexture = -1;
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
private SSAORenderer() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init) return;
|
||||
this.init = true;
|
||||
|
||||
SSAOShader.INSTANCE.init();
|
||||
|
||||
SSAOApplyShader.INSTANCE.init();
|
||||
}
|
||||
|
||||
private void createFramebuffer(int width, int height)
|
||||
{
|
||||
if (this.ssaoFramebuffer != -1)
|
||||
{
|
||||
GL32.glDeleteFramebuffers(this.ssaoFramebuffer);
|
||||
this.ssaoFramebuffer = -1;
|
||||
}
|
||||
|
||||
if (this.ssaoTexture != -1)
|
||||
{
|
||||
GL32.glDeleteTextures(this.ssaoTexture);
|
||||
this.ssaoTexture = -1;
|
||||
}
|
||||
|
||||
this.ssaoFramebuffer = GL32.glGenFramebuffers();
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer);
|
||||
|
||||
this.ssaoTexture = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R16F, width, height, 0, GL32.GL_RED, GL32.GL_HALF_FLOAT, (ByteBuffer) null);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR);
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.ssaoTexture, 0);
|
||||
}
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
|
||||
public void render(GLState primaryState, float partialTicks)
|
||||
{
|
||||
GLState state = new GLState();
|
||||
|
||||
this.init();
|
||||
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
if (this.width != width || this.height != height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.createFramebuffer(width, height);
|
||||
}
|
||||
|
||||
ScreenQuad.INSTANCE.bind();
|
||||
|
||||
SSAOShader.INSTANCE.render(partialTicks, ssaoFramebuffer);
|
||||
|
||||
primaryState.RestoreFrameBuffer();
|
||||
|
||||
SSAOApplyShader.INSTANCE.render(partialTicks, ssaoTexture);
|
||||
|
||||
state.restore();
|
||||
}
|
||||
|
||||
public void free()
|
||||
{
|
||||
SSAOShader.INSTANCE.free();
|
||||
SSAOApplyShader.INSTANCE.free();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class ScreenQuad
|
||||
{
|
||||
public static ScreenQuad INSTANCE = new ScreenQuad();
|
||||
|
||||
private static final float[] box_vertices = {
|
||||
-1, -1,
|
||||
1, -1,
|
||||
1, 1,
|
||||
-1, -1,
|
||||
1, 1,
|
||||
-1, 1,
|
||||
};
|
||||
|
||||
private GLVertexBuffer boxBuffer;
|
||||
private VertexAttribute va;
|
||||
private boolean init = false;
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
private ScreenQuad() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init) return;
|
||||
this.init = true;
|
||||
|
||||
this.va = VertexAttribute.create();
|
||||
this.va.bind();
|
||||
|
||||
// Pos
|
||||
this.va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
this.va.completeAndCheck(Float.BYTES * 2);
|
||||
|
||||
// Framebuffer
|
||||
this.createBuffer();
|
||||
}
|
||||
|
||||
public void bind()
|
||||
{
|
||||
this.init();
|
||||
|
||||
this.va.bind();
|
||||
this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId());
|
||||
}
|
||||
|
||||
public void render()
|
||||
{
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.asFloatBuffer().put(box_vertices);
|
||||
buffer.rewind();
|
||||
|
||||
this.boxBuffer = new GLVertexBuffer(false);
|
||||
this.boxBuffer.bind();
|
||||
this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES);
|
||||
}
|
||||
}
|
||||
+4
-94
@@ -19,116 +19,26 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public abstract class AbstractShaderRenderer
|
||||
{
|
||||
protected static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
protected static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final float[] box_vertices = {
|
||||
-1, -1,
|
||||
1, -1,
|
||||
1, 1,
|
||||
-1, -1,
|
||||
1, 1,
|
||||
-1, 1,
|
||||
};
|
||||
|
||||
protected final ShaderProgram shader;
|
||||
public GLVertexBuffer boxBuffer;
|
||||
protected VertexAttribute va;
|
||||
protected ShaderProgram shader;
|
||||
|
||||
boolean init = false;
|
||||
|
||||
|
||||
protected AbstractShaderRenderer(ShaderProgram shader)
|
||||
{
|
||||
this.shader = shader;
|
||||
}
|
||||
protected AbstractShaderRenderer() {}
|
||||
|
||||
private void init()
|
||||
public void init()
|
||||
{
|
||||
if (init) return;
|
||||
init = true;
|
||||
|
||||
va = VertexAttribute.create();
|
||||
va.bind();
|
||||
|
||||
// Pos
|
||||
setVertexAttributes();
|
||||
va.completeAndCheck(Float.BYTES * 2);
|
||||
|
||||
// Some shader stuff needs to be set a bit later than
|
||||
this.postInit();
|
||||
|
||||
// Framebuffer
|
||||
this.createBuffer();
|
||||
}
|
||||
|
||||
/** Sets all the vertex attributes */
|
||||
void setVertexAttributes()
|
||||
{
|
||||
va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
}
|
||||
|
||||
/** Overwrite this to apply uniforms to the shader */
|
||||
void setShaderUniforms(float partialTicks) { }
|
||||
|
||||
/** Overwrite if you need to run something on runtime */
|
||||
void postInit() { }
|
||||
|
||||
|
||||
// TODO pass in the Model View and Projection Matrices along with the ticks
|
||||
public void render(float partialTicks)
|
||||
{
|
||||
GLState state = new GLState();
|
||||
this.init();
|
||||
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
GL32.glViewport(0, 0, width, height);
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
|
||||
shader.bind();
|
||||
this.setShaderUniforms(partialTicks);
|
||||
|
||||
va.bind();
|
||||
va.bindBufferToAllBindingPoint(boxBuffer.getId());
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
|
||||
GL32.glEnable(GL11.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
|
||||
state.restore();
|
||||
}
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.asFloatBuffer().put(box_vertices);
|
||||
buffer.rewind();
|
||||
|
||||
this.boxBuffer = new GLVertexBuffer(false);
|
||||
this.boxBuffer.bind();
|
||||
this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES);
|
||||
}
|
||||
|
||||
public void free()
|
||||
|
||||
+44
-2
@@ -19,15 +19,57 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
public class DarkShader extends AbstractShaderRenderer
|
||||
{
|
||||
public static DarkShader INSTANCE = new DarkShader();
|
||||
|
||||
|
||||
protected DarkShader()
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super(new ShaderProgram("shaders/normal.vert", "shaders/test/dark.frag", "fragColor", new String[]{"vPosition", "color"}));
|
||||
super.init();
|
||||
|
||||
this.shader = new ShaderProgram(
|
||||
"shaders/normal.vert",
|
||||
"shaders/test/dark.frag",
|
||||
"fragColor",
|
||||
new String[]{"vPosition", "color"});
|
||||
}
|
||||
|
||||
void setShaderUniforms()
|
||||
{
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
}
|
||||
|
||||
public void render()
|
||||
{
|
||||
GLState state = new GLState();
|
||||
|
||||
this.init();
|
||||
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
GL32.glViewport(0, 0, width, height);
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
|
||||
shader.bind();
|
||||
|
||||
this.setShaderUniforms();
|
||||
|
||||
ScreenQuad.INSTANCE.bind();
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
ScreenQuad.INSTANCE.render();
|
||||
|
||||
state.restore();
|
||||
}
|
||||
}
|
||||
|
||||
+37
-5
@@ -23,11 +23,14 @@ import com.seibel.distanthorizons.api.enums.rendering.EFogColorMode;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
@@ -36,6 +39,8 @@ import java.awt.*;
|
||||
public class FogShader extends AbstractShaderRenderer
|
||||
{
|
||||
public static FogShader INSTANCE = new FogShader(LodFogConfig.generateFogConfig());
|
||||
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
|
||||
|
||||
@@ -51,15 +56,14 @@ public class FogShader extends AbstractShaderRenderer
|
||||
public final int fullFogModeUniform;
|
||||
|
||||
|
||||
|
||||
public FogShader(LodFogConfig fogConfig)
|
||||
{
|
||||
super(new ShaderProgram(
|
||||
this.shader = new ShaderProgram(
|
||||
// TODO rename normal.vert to something like "postProcess.vert"
|
||||
() -> Shader.loadFile("shaders/normal.vert", false, new StringBuilder()).toString(),
|
||||
() -> fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(),
|
||||
"fragColor", new String[]{"vPosition"}
|
||||
));
|
||||
);
|
||||
|
||||
// all uniforms should be tryGet...
|
||||
// because disabling fog can cause the GLSL to optimize out most (if not all) uniforms
|
||||
@@ -78,7 +82,7 @@ public class FogShader extends AbstractShaderRenderer
|
||||
this.nearFogLengthUniform = this.shader.tryGetUniformLocation("nearFogLength");
|
||||
}
|
||||
|
||||
@Override
|
||||
//@Override
|
||||
void setShaderUniforms(float partialTicks)
|
||||
{
|
||||
this.shader.bind();
|
||||
@@ -135,4 +139,32 @@ public class FogShader extends AbstractShaderRenderer
|
||||
|
||||
this.shader.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
public void render(float partialTicks)
|
||||
{
|
||||
GLState state = new GLState();
|
||||
|
||||
this.init();
|
||||
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
GL32.glViewport(0, 0, width, height);
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
|
||||
shader.bind();
|
||||
|
||||
this.setShaderUniforms(partialTicks);
|
||||
|
||||
ScreenQuad.INSTANCE.bind();
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
ScreenQuad.INSTANCE.render();
|
||||
|
||||
state.restore();
|
||||
}}
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
public class SSAOApplyShader extends AbstractShaderRenderer
|
||||
{
|
||||
public static SSAOApplyShader INSTANCE = new SSAOApplyShader();
|
||||
|
||||
|
||||
// apply uniforms
|
||||
private final ApplyShaderUniforms applyShaderUniforms = new ApplyShaderUniforms();
|
||||
|
||||
private static class ApplyShaderUniforms
|
||||
{
|
||||
public int gSSAOMapUniform;
|
||||
public int gDepthMapUniform;
|
||||
public int gViewSizeUniform;
|
||||
public int gBlurRadiusUniform;
|
||||
public int gNearUniform;
|
||||
public int gFarUniform;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.shader = new ShaderProgram(
|
||||
"shaders/normal.vert",
|
||||
"shaders/ssao/apply.frag",
|
||||
"fragColor",
|
||||
new String[]{"vPosition"});
|
||||
|
||||
// uniform setup
|
||||
this.applyShaderUniforms.gSSAOMapUniform = this.shader.getUniformLocation("gSSAOMap");
|
||||
this.applyShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap");
|
||||
this.applyShaderUniforms.gViewSizeUniform = this.shader.tryGetUniformLocation("gViewSize");
|
||||
this.applyShaderUniforms.gBlurRadiusUniform = this.shader.tryGetUniformLocation("gBlurRadius");
|
||||
this.applyShaderUniforms.gNearUniform = this.shader.tryGetUniformLocation("gNear");
|
||||
this.applyShaderUniforms.gFarUniform = this.shader.tryGetUniformLocation("gFar");
|
||||
}
|
||||
|
||||
private void setShaderUniforms(float partialTicks, int ssaoTexture)
|
||||
{
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 0);
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE1);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, ssaoTexture);
|
||||
GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1);
|
||||
|
||||
int blurRadius = Config.Client.Advanced.Graphics.Ssao.blurRadius.get();
|
||||
GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, blurRadius);
|
||||
|
||||
if (this.applyShaderUniforms.gViewSizeUniform >= 0)
|
||||
{
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, width, height);
|
||||
}
|
||||
|
||||
if (this.applyShaderUniforms.gNearUniform >= 0)
|
||||
{
|
||||
float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks);
|
||||
GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, near);
|
||||
}
|
||||
|
||||
if (this.applyShaderUniforms.gFarUniform >= 0)
|
||||
{
|
||||
float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2));
|
||||
GL32.glUniform1f(this.applyShaderUniforms.gFarUniform, far);
|
||||
}
|
||||
}
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
|
||||
public void render(float partialTicks, int ssaoTexture)
|
||||
{
|
||||
this.init();
|
||||
|
||||
this.shader.bind();
|
||||
|
||||
setShaderUniforms(partialTicks, ssaoTexture);
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE);
|
||||
|
||||
ScreenQuad.INSTANCE.render();
|
||||
}
|
||||
}
|
||||
-277
@@ -1,277 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttribute;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class SSAORenderer
|
||||
{
|
||||
public static SSAORenderer INSTANCE = new SSAORenderer();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final float[] box_vertices = {
|
||||
-1, -1,
|
||||
1, -1,
|
||||
1, 1,
|
||||
-1, -1,
|
||||
1, 1,
|
||||
-1, 1,
|
||||
};
|
||||
|
||||
|
||||
private ShaderProgram ssaoShader;
|
||||
private ShaderProgram applyShader;
|
||||
|
||||
private GLVertexBuffer boxBuffer;
|
||||
private VertexAttribute va;
|
||||
private boolean init = false;
|
||||
|
||||
private int width = -1;
|
||||
private int height = -1;
|
||||
private int ssaoFramebuffer = -1;
|
||||
|
||||
private int ssaoTexture = -1;
|
||||
|
||||
// ssao uniforms
|
||||
private final SsaoShaderUniforms ssaoShaderUniforms = new SsaoShaderUniforms();
|
||||
private static class SsaoShaderUniforms
|
||||
{
|
||||
public int gProjUniform;
|
||||
public int gInvProjUniform;
|
||||
public int gSampleCountUniform;
|
||||
public int gRadiusUniform;
|
||||
public int gStrengthUniform;
|
||||
public int gMinLightUniform;
|
||||
public int gBiasUniform;
|
||||
public int gDepthMapUniform;
|
||||
}
|
||||
|
||||
// apply uniforms
|
||||
private final ApplyShaderUniforms applyShaderUniforms = new ApplyShaderUniforms();
|
||||
private static class ApplyShaderUniforms
|
||||
{
|
||||
public int gSSAOMapUniform;
|
||||
public int gDepthMapUniform;
|
||||
public int gViewSizeUniform;
|
||||
public int gBlurRadiusUniform;
|
||||
public int gNearUniform;
|
||||
public int gFarUniform;
|
||||
}
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
private SSAORenderer() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init) return;
|
||||
this.init = true;
|
||||
|
||||
this.va = VertexAttribute.create();
|
||||
this.va.bind();
|
||||
|
||||
// Pos
|
||||
this.va.setVertexAttribute(0, 0, VertexAttribute.VertexPointer.addVec2Pointer(false));
|
||||
this.va.completeAndCheck(Float.BYTES * 2);
|
||||
this.ssaoShader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
|
||||
this.applyShader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/apply.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
|
||||
// SSAO uniform setup
|
||||
this.ssaoShaderUniforms.gProjUniform = this.ssaoShader.getUniformLocation("gProj");
|
||||
this.ssaoShaderUniforms.gInvProjUniform = this.ssaoShader.getUniformLocation("gInvProj");
|
||||
this.ssaoShaderUniforms.gSampleCountUniform = this.ssaoShader.getUniformLocation("gSampleCount");
|
||||
this.ssaoShaderUniforms.gRadiusUniform = this.ssaoShader.getUniformLocation("gRadius");
|
||||
this.ssaoShaderUniforms.gStrengthUniform = this.ssaoShader.getUniformLocation("gStrength");
|
||||
this.ssaoShaderUniforms.gMinLightUniform = this.ssaoShader.getUniformLocation("gMinLight");
|
||||
this.ssaoShaderUniforms.gBiasUniform = this.ssaoShader.getUniformLocation("gBias");
|
||||
this.ssaoShaderUniforms.gDepthMapUniform = this.ssaoShader.getUniformLocation("gDepthMap");
|
||||
|
||||
// Apply uniform setup
|
||||
this.applyShaderUniforms.gSSAOMapUniform = this.applyShader.getUniformLocation("gSSAOMap");
|
||||
this.applyShaderUniforms.gDepthMapUniform = this.applyShader.getUniformLocation("gDepthMap");
|
||||
this.applyShaderUniforms.gViewSizeUniform = this.applyShader.tryGetUniformLocation("gViewSize");
|
||||
this.applyShaderUniforms.gBlurRadiusUniform = this.applyShader.tryGetUniformLocation("gBlurRadius");
|
||||
this.applyShaderUniforms.gNearUniform = this.applyShader.tryGetUniformLocation("gNear");
|
||||
this.applyShaderUniforms.gFarUniform = this.applyShader.tryGetUniformLocation("gFar");
|
||||
|
||||
// Framebuffer
|
||||
this.createBuffer();
|
||||
}
|
||||
|
||||
private void createFramebuffer(int width, int height)
|
||||
{
|
||||
if (this.ssaoFramebuffer != -1)
|
||||
{
|
||||
GL32.glDeleteFramebuffers(this.ssaoFramebuffer);
|
||||
this.ssaoFramebuffer = -1;
|
||||
}
|
||||
|
||||
if (this.ssaoTexture != -1)
|
||||
{
|
||||
GL32.glDeleteTextures(this.ssaoTexture);
|
||||
this.ssaoTexture = -1;
|
||||
}
|
||||
|
||||
this.ssaoFramebuffer = GL32.glGenFramebuffers();
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer);
|
||||
|
||||
this.ssaoTexture = GL32.glGenTextures();
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture);
|
||||
GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R16F, width, height, 0, GL32.GL_RED, GL32.GL_HALF_FLOAT, (ByteBuffer) null);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR);
|
||||
GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR);
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.ssaoTexture, 0);
|
||||
}
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(box_vertices.length * Float.BYTES);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.asFloatBuffer().put(box_vertices);
|
||||
buffer.rewind();
|
||||
|
||||
this.boxBuffer = new GLVertexBuffer(false);
|
||||
this.boxBuffer.bind();
|
||||
this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EGpuUploadMethod.DATA, box_vertices.length * Float.BYTES);
|
||||
}
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
|
||||
public void render(GLState primaryState, float partialTicks)
|
||||
{
|
||||
GLState state = new GLState();
|
||||
|
||||
this.init();
|
||||
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
if (this.width != width || this.height != height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.createFramebuffer(width, height);
|
||||
}
|
||||
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer);
|
||||
GL32.glViewport(0, 0, width, height);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL11.GL_BLEND);
|
||||
|
||||
float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks);
|
||||
float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2));
|
||||
|
||||
Mat4f perspective = Mat4f.perspective(
|
||||
(float) MC_RENDER.getFov(partialTicks),
|
||||
width / (float) height,
|
||||
near, far);
|
||||
|
||||
Mat4f invertedPerspective = new Mat4f(perspective);
|
||||
invertedPerspective.invert();
|
||||
|
||||
int sampleCount = Config.Client.Advanced.Graphics.Ssao.sampleCount.get();
|
||||
int blurRadius = Config.Client.Advanced.Graphics.Ssao.blurRadius.get();
|
||||
float radius = Config.Client.Advanced.Graphics.Ssao.radius.get().floatValue();
|
||||
float strength = Config.Client.Advanced.Graphics.Ssao.strength.get().floatValue();
|
||||
float minLight = Config.Client.Advanced.Graphics.Ssao.minLight.get().floatValue();
|
||||
float bias = Config.Client.Advanced.Graphics.Ssao.bias.get().floatValue();
|
||||
|
||||
this.ssaoShader.bind();
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gProjUniform, perspective);
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gInvProjUniform, invertedPerspective);
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gSampleCountUniform, sampleCount);
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gRadiusUniform, radius);
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gStrengthUniform, strength);
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gMinLightUniform, minLight);
|
||||
this.ssaoShader.setUniform(this.ssaoShaderUniforms.gBiasUniform, bias);
|
||||
|
||||
this.va.bind();
|
||||
this.va.bindBufferToAllBindingPoint(this.boxBuffer.getId());
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
|
||||
GL32.glUniform1i(this.ssaoShaderUniforms.gDepthMapUniform, 0);
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
|
||||
this.applyShader.bind();
|
||||
|
||||
primaryState.RestoreFrameBuffer();
|
||||
|
||||
GL32.glEnable(GL11.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE);
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
GL32.glUniform1i(this.applyShaderUniforms.gDepthMapUniform, 0);
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE1);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, this.ssaoTexture);
|
||||
GL32.glUniform1i(this.applyShaderUniforms.gSSAOMapUniform, 1);
|
||||
|
||||
GL32.glUniform1i(this.applyShaderUniforms.gBlurRadiusUniform, blurRadius);
|
||||
|
||||
if (this.applyShaderUniforms.gViewSizeUniform >= 0)
|
||||
GL32.glUniform2f(this.applyShaderUniforms.gViewSizeUniform, width, height);
|
||||
|
||||
if (this.applyShaderUniforms.gNearUniform >= 0)
|
||||
GL32.glUniform1f(this.applyShaderUniforms.gNearUniform, near);
|
||||
|
||||
if (this.applyShaderUniforms.gFarUniform >= 0)
|
||||
GL32.glUniform1f(this.applyShaderUniforms.gFarUniform, far);
|
||||
|
||||
GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6);
|
||||
|
||||
state.restore();
|
||||
}
|
||||
|
||||
public void free()
|
||||
{
|
||||
this.ssaoShader.free();
|
||||
this.applyShader.free();
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
public class SSAOShader extends AbstractShaderRenderer
|
||||
{
|
||||
public static SSAOShader INSTANCE = new SSAOShader();
|
||||
|
||||
|
||||
// uniforms
|
||||
private final SsaoShaderUniforms ssaoShaderUniforms = new SsaoShaderUniforms();
|
||||
|
||||
private static class SsaoShaderUniforms
|
||||
{
|
||||
public int gProjUniform;
|
||||
public int gInvProjUniform;
|
||||
public int gSampleCountUniform;
|
||||
public int gRadiusUniform;
|
||||
public int gStrengthUniform;
|
||||
public int gMinLightUniform;
|
||||
public int gBiasUniform;
|
||||
public int gDepthMapUniform;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.shader = new ShaderProgram("shaders/normal.vert", "shaders/ssao/ao.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
|
||||
// uniform setup
|
||||
this.ssaoShaderUniforms.gProjUniform = this.shader.getUniformLocation("gProj");
|
||||
this.ssaoShaderUniforms.gInvProjUniform = this.shader.getUniformLocation("gInvProj");
|
||||
this.ssaoShaderUniforms.gSampleCountUniform = this.shader.getUniformLocation("gSampleCount");
|
||||
this.ssaoShaderUniforms.gRadiusUniform = this.shader.getUniformLocation("gRadius");
|
||||
this.ssaoShaderUniforms.gStrengthUniform = this.shader.getUniformLocation("gStrength");
|
||||
this.ssaoShaderUniforms.gMinLightUniform = this.shader.getUniformLocation("gMinLight");
|
||||
this.ssaoShaderUniforms.gBiasUniform = this.shader.getUniformLocation("gBias");
|
||||
this.ssaoShaderUniforms.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap");
|
||||
}
|
||||
|
||||
void setShaderUniforms(float partialTicks)
|
||||
{
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
float near = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks);
|
||||
float far = (float) ((RenderUtil.getFarClipPlaneDistanceInBlocks() + LodUtil.REGION_WIDTH) * Math.sqrt(2));
|
||||
|
||||
Mat4f perspective = Mat4f.perspective(
|
||||
(float) MC_RENDER.getFov(partialTicks),
|
||||
width / (float) height,
|
||||
near, far);
|
||||
|
||||
Mat4f invertedPerspective = new Mat4f(perspective);
|
||||
invertedPerspective.invert();
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gProjUniform, perspective);
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gInvProjUniform, invertedPerspective);
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gSampleCountUniform,
|
||||
Config.Client.Advanced.Graphics.Ssao.sampleCount.get());
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gRadiusUniform,
|
||||
Config.Client.Advanced.Graphics.Ssao.radius.get().floatValue());
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gStrengthUniform,
|
||||
Config.Client.Advanced.Graphics.Ssao.strength.get().floatValue());
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gMinLightUniform,
|
||||
Config.Client.Advanced.Graphics.Ssao.minLight.get().floatValue());
|
||||
|
||||
this.shader.setUniform(this.ssaoShaderUniforms.gBiasUniform,
|
||||
Config.Client.Advanced.Graphics.Ssao.bias.get().floatValue());
|
||||
|
||||
GL32.glActiveTexture(GL32.GL_TEXTURE0);
|
||||
GL32.glBindTexture(GL32.GL_TEXTURE_2D, MC_RENDER.getDepthTextureId());
|
||||
|
||||
GL32.glUniform1i(this.ssaoShaderUniforms.gDepthMapUniform, 0);
|
||||
}
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
|
||||
public void render(float partialTicks, int ssaoFramebuffer)
|
||||
{
|
||||
this.init();
|
||||
|
||||
int width = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
int height = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
this.shader.bind();
|
||||
|
||||
setShaderUniforms(partialTicks);
|
||||
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, ssaoFramebuffer);
|
||||
GL32.glViewport(0, 0, width, height);
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
GL32.glDisable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDisable(GL11.GL_BLEND);
|
||||
|
||||
ScreenQuad.INSTANCE.render();
|
||||
|
||||
shader.unbind();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user