
com.gempukku.libgdx.graph.pipeline.producer.postprocessor.DepthOfFieldPipelineNodeProducer Maven / Gradle / Ivy
package com.gempukku.libgdx.graph.pipeline.producer.postprocessor;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.ObjectMap;
import com.gempukku.libgdx.graph.pipeline.RenderPipeline;
import com.gempukku.libgdx.graph.pipeline.RenderPipelineBuffer;
import com.gempukku.libgdx.graph.pipeline.config.postprocessor.DepthOfFieldPipelineNodeConfiguration;
import com.gempukku.libgdx.graph.pipeline.producer.FullScreenRender;
import com.gempukku.libgdx.graph.pipeline.producer.PipelineRenderingContext;
import com.gempukku.libgdx.graph.pipeline.producer.node.OncePerFrameJobPipelineNode;
import com.gempukku.libgdx.graph.pipeline.producer.node.PipelineNode;
import com.gempukku.libgdx.graph.pipeline.producer.node.PipelineNodeProducerImpl;
import com.gempukku.libgdx.graph.pipeline.producer.node.PipelineRequirements;
import com.gempukku.libgdx.graph.shader.builder.GLSLFragmentReader;
import java.nio.charset.StandardCharsets;
public class DepthOfFieldPipelineNodeProducer extends PipelineNodeProducerImpl {
public DepthOfFieldPipelineNodeProducer() {
super(new DepthOfFieldPipelineNodeConfiguration());
}
@Override
public PipelineNode createNodeForSingleInputs(JsonValue data, ObjectMap> inputFields) {
float maxBlurFloat = data.getFloat("maxBlur");
final int maxBlur = MathUtils.round(maxBlurFloat);
boolean blurBackground = data.getBoolean("blurBackground", false);
String viewToScreenCoords = getShader("viewToScreenCoords.vert");
String depthOfField = getShader("depthOfField.frag");
depthOfField = depthOfField.replaceAll("MAX_BLUR", String.valueOf(maxBlur));
depthOfField = depthOfField.replaceAll("UNPACK_FUNCTION;", GLSLFragmentReader.getFragment("unpackVec3ToFloat"));
depthOfField = depthOfField.replaceAll("BLUR_BACKGROUND", String.valueOf(blurBackground));
final ShaderProgram shaderProgram = new ShaderProgram(
viewToScreenCoords, depthOfField);
if (!shaderProgram.isCompiled())
throw new IllegalArgumentException("Error compiling shader: " + shaderProgram.getLog());
final PipelineNode.FieldOutput renderPipelineInput = (PipelineNode.FieldOutput) inputFields.get("input");
final PipelineNode.FieldOutput processorEnabled = (PipelineNode.FieldOutput) inputFields.get("enabled");
final PipelineNode.FieldOutput cameraInput = (PipelineNode.FieldOutput) inputFields.get("camera");
final PipelineNode.FieldOutput focusDistanceInput = (PipelineNode.FieldOutput) inputFields.get("focusDistance");
final PipelineNode.FieldOutput nearDistanceBlurInput = (PipelineNode.FieldOutput) inputFields.get("nearDistanceBlur");
final PipelineNode.FieldOutput farDistanceBlurInput = (PipelineNode.FieldOutput) inputFields.get("farDistanceBlur");
return new OncePerFrameJobPipelineNode(configuration, inputFields) {
@Override
protected void executeJob(PipelineRenderingContext pipelineRenderingContext, PipelineRequirements pipelineRequirements, ObjectMap outputValues) {
if (maxBlur > 0)
pipelineRequirements.setRequiringDepthTexture();
RenderPipeline renderPipeline = renderPipelineInput.getValue(pipelineRenderingContext, pipelineRequirements);
boolean enabled = processorEnabled == null || processorEnabled.getValue(pipelineRenderingContext, null);
if (enabled && maxBlur > 0) {
Camera camera = cameraInput.getValue(pipelineRenderingContext, null);
Vector2 focusDistance = focusDistanceInput.getValue(pipelineRenderingContext, null);
float nearDistanceBlur = nearDistanceBlurInput != null ? nearDistanceBlurInput.getValue(pipelineRenderingContext, null) : 10f;
float farDistanceBlur = farDistanceBlurInput != null ? farDistanceBlurInput.getValue(pipelineRenderingContext, null) : 10f;
RenderPipelineBuffer currentBuffer = renderPipeline.getDefaultBuffer();
RenderContext renderContext = pipelineRenderingContext.getRenderContext();
renderContext.setDepthTest(0);
renderContext.setDepthMask(false);
renderContext.setBlending(false, 0, 0);
renderContext.setCullFace(GL20.GL_BACK);
shaderProgram.bind();
shaderProgram.setUniformf("u_pixelSize", 1f / currentBuffer.getWidth(), 1f / currentBuffer.getHeight());
shaderProgram.setUniformf("u_cameraClipping", camera.near, camera.far);
shaderProgram.setUniformf("u_focusDistance", focusDistance);
shaderProgram.setUniformf("u_nearDistanceBlur", nearDistanceBlur);
shaderProgram.setUniformf("u_farDistanceBlur", farDistanceBlur);
shaderProgram.setUniformi("u_vertical", 1);
RenderPipelineBuffer tempBuffer = executeBlur(shaderProgram, renderPipeline, currentBuffer, currentBuffer, pipelineRenderingContext.getRenderContext(), pipelineRenderingContext.getFullScreenRender());
shaderProgram.setUniformi("u_vertical", 0);
RenderPipelineBuffer finalBuffer = executeBlur(shaderProgram, renderPipeline, currentBuffer, tempBuffer, pipelineRenderingContext.getRenderContext(), pipelineRenderingContext.getFullScreenRender());
renderPipeline.returnFrameBuffer(tempBuffer);
renderPipeline.swapColorTextures(currentBuffer, finalBuffer);
renderPipeline.returnFrameBuffer(finalBuffer);
}
OutputValue output = outputValues.get("output");
if (output != null)
output.setValue(renderPipeline);
}
@Override
public void dispose() {
shaderProgram.dispose();
}
};
}
private String getShader(String shaderName) {
FileHandle fileHandle = Gdx.files.classpath("shader/" + shaderName);
return new String(fileHandle.readBytes(), StandardCharsets.UTF_8);
}
private RenderPipelineBuffer executeBlur(ShaderProgram shaderProgram, RenderPipeline renderPipeline, RenderPipelineBuffer depthBuffer, RenderPipelineBuffer sourceBuffer,
RenderContext renderContext, FullScreenRender fullScreenRender) {
RenderPipelineBuffer resultBuffer = renderPipeline.getNewFrameBuffer(sourceBuffer);
resultBuffer.beginColor();
shaderProgram.setUniformi("u_sourceTexture", renderContext.textureBinder.bind(sourceBuffer.getColorBufferTexture()));
shaderProgram.setUniformi("u_depthTexture", renderContext.textureBinder.bind(depthBuffer.getDepthBufferTexture()));
fullScreenRender.renderFullScreen(shaderProgram);
resultBuffer.endColor();
return resultBuffer;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy