Color matrices and many effect spheres
This commit is contained in:
parent
db7913d91b
commit
7988fb69a7
12 changed files with 449 additions and 190 deletions
|
@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.KineticRenderer;
|
||||
|
@ -56,10 +57,6 @@ public class RenderHooksMixin {
|
|||
ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
|
||||
|
||||
GL20.glUseProgram(0);
|
||||
|
||||
if (type == RenderType.getTranslucent()) {
|
||||
Backend.effects.render(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render")
|
||||
|
@ -72,14 +69,24 @@ public class RenderHooksMixin {
|
|||
double camZ = cameraPos.getZ();
|
||||
|
||||
CreateClient.kineticRenderer.get(world)
|
||||
.beginFrame(info, camX, camY, camZ);
|
||||
.beginFrame(info, camX, camY, camZ);
|
||||
ContraptionRenderDispatcher.beginFrame(info, camX, camY, camZ);
|
||||
}
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/shader/ShaderGroup;render(F)V"))
|
||||
private void disableTransparencyShaderDepth(MatrixStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||
GlStateManager.depthMask(false);
|
||||
}
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/renderer/ActiveRenderInfo;)V"))
|
||||
private void applyFilters(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||
Backend.effects.render(stack.peek().getModel());
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "scheduleBlockRerenderIfNeeded")
|
||||
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
||||
CreateClient.kineticRenderer.get(world)
|
||||
.update(world.getTileEntity(pos));
|
||||
.update(world.getTileEntity(pos));
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "loadRenderers")
|
||||
|
|
|
@ -15,7 +15,7 @@ import com.simibubi.create.foundation.render.backend.core.BasicProgram;
|
|||
import com.simibubi.create.foundation.render.backend.core.ModelAttributes;
|
||||
import com.simibubi.create.foundation.render.backend.core.OrientedAttributes;
|
||||
import com.simibubi.create.foundation.render.backend.core.TransformAttributes;
|
||||
import com.simibubi.create.foundation.render.backend.effects.PostProcessingProgram;
|
||||
import com.simibubi.create.foundation.render.backend.effects.SphereFilterProgram;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.FogSensitiveProgram;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants;
|
||||
|
@ -28,12 +28,12 @@ public class AllProgramSpecs {
|
|||
// noop, make sure the static field are loaded.
|
||||
}
|
||||
|
||||
public static final ProgramSpec<PostProcessingProgram> CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(PostProcessingProgram::new))
|
||||
public static final ProgramSpec<SphereFilterProgram> CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(SphereFilterProgram::new))
|
||||
.addAttributes(ModelAttributes.class)
|
||||
.addAttributes(BasicAttributes.class)
|
||||
.addAttributes(TransformAttributes.class)
|
||||
.setVert(Locations.SCREEN_QUAD)
|
||||
.setFrag(Locations.CHROMATIC)
|
||||
.setVert(Locations.EFFECT_VERT)
|
||||
.setFrag(Locations.EFFECT_FRAG)
|
||||
.createProgramSpec());
|
||||
|
||||
public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new))
|
||||
|
@ -131,8 +131,8 @@ public class AllProgramSpecs {
|
|||
|
||||
|
||||
public static class Locations {
|
||||
public static final ResourceLocation SCREEN_QUAD = loc("screen_quad.vert");
|
||||
public static final ResourceLocation CHROMATIC = loc("chromatic.frag");
|
||||
public static final ResourceLocation EFFECT_VERT = loc("area_effect.vert");
|
||||
public static final ResourceLocation EFFECT_FRAG = loc("area_effect.frag");
|
||||
public static final ResourceLocation MODEL_FRAG = loc("model.frag");
|
||||
public static final ResourceLocation MODEL_VERT = loc("model.vert");
|
||||
public static final ResourceLocation ORIENTED = loc("oriented.vert");
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package com.simibubi.create.foundation.render.backend.effects;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
public class ColorMatrices {
|
||||
|
||||
public static final float lumaR = 0.3086f;
|
||||
public static final float lumaG = 0.6094f;
|
||||
public static final float lumaB = 0.0820f;
|
||||
|
||||
public static Matrix4f grayscale() {
|
||||
Matrix4f mat = new Matrix4f();
|
||||
|
||||
mat.a00 = mat.a01 = mat.a02 = lumaR;
|
||||
mat.a10 = mat.a11 = mat.a12 = lumaG;
|
||||
mat.a20 = mat.a21 = mat.a22 = lumaB;
|
||||
mat.a33 = 1;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
public static Matrix4f saturate(float s) {
|
||||
Matrix4f mat = new Matrix4f();
|
||||
|
||||
mat.a00 = (1.0f - s) * lumaR + s;
|
||||
mat.a01 = (1.0f - s) * lumaR;
|
||||
mat.a02 = (1.0f - s) * lumaR;
|
||||
mat.a10 = (1.0f - s) * lumaG;
|
||||
mat.a11 = (1.0f - s) * lumaG + s;
|
||||
mat.a12 = (1.0f - s) * lumaG;
|
||||
mat.a20 = (1.0f - s) * lumaB;
|
||||
mat.a21 = (1.0f - s) * lumaB;
|
||||
mat.a22 = (1.0f - s) * lumaB + s;
|
||||
|
||||
mat.a33 = 1;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
public static Matrix4f sepia(float amount) {
|
||||
Matrix4f mat = new Matrix4f();
|
||||
|
||||
mat.a00 = (float) (0.393 + 0.607 * (1 - amount));
|
||||
mat.a10 = (float) (0.769 - 0.769 * (1 - amount));
|
||||
mat.a20 = (float) (0.189 - 0.189 * (1 - amount));
|
||||
mat.a01 = (float) (0.349 - 0.349 * (1 - amount));
|
||||
mat.a11 = (float) (0.686 + 0.314 * (1 - amount));
|
||||
mat.a21 = (float) (0.168 - 0.168 * (1 - amount));
|
||||
mat.a02 = (float) (0.272 - 0.272 * (1 - amount));
|
||||
mat.a12 = (float) (0.534 - 0.534 * (1 - amount));
|
||||
mat.a22 = (float) (0.131 + 0.869 * (1 - amount));
|
||||
|
||||
mat.a33 = 1;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/8510751
|
||||
public static Matrix4f hueShift(float rot) {
|
||||
Matrix4f mat = new Matrix4f();
|
||||
|
||||
mat.loadIdentity();
|
||||
|
||||
float cosA = MathHelper.cos(AngleHelper.rad(rot));
|
||||
float sinA = MathHelper.sin(AngleHelper.rad(rot));
|
||||
mat.a00 = (float) (cosA + (1.0 - cosA) / 3.0);
|
||||
mat.a01 = (float) (1. / 3. * (1.0 - cosA) - MathHelper.sqrt(1. / 3.) * sinA);
|
||||
mat.a02 = (float) (1. / 3. * (1.0 - cosA) + MathHelper.sqrt(1. / 3.) * sinA);
|
||||
mat.a10 = (float) (1. / 3. * (1.0 - cosA) + MathHelper.sqrt(1. / 3.) * sinA);
|
||||
mat.a11 = (float) (cosA + 1. / 3. * (1.0 - cosA));
|
||||
mat.a12 = (float) (1. / 3. * (1.0 - cosA) - MathHelper.sqrt(1. / 3.) * sinA);
|
||||
mat.a20 = (float) (1. / 3. * (1.0 - cosA) - MathHelper.sqrt(1. / 3.) * sinA);
|
||||
mat.a21 = (float) (1. / 3. * (1.0 - cosA) + MathHelper.sqrt(1. / 3.) * sinA);
|
||||
mat.a22 = (float) (cosA + 1. / 3. * (1.0 - cosA));
|
||||
|
||||
return mat;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ public class EffectsHandler {
|
|||
}
|
||||
|
||||
public static float getFarPlane() {
|
||||
return Minecraft.getInstance().gameRenderer.getFarPlaneDistance();
|
||||
return Minecraft.getInstance().gameRenderer.getFarPlaneDistance() * 4;
|
||||
}
|
||||
|
||||
public static final float[] vertices = {
|
||||
|
@ -75,6 +75,10 @@ public class EffectsHandler {
|
|||
}
|
||||
|
||||
public void render(Matrix4f view) {
|
||||
// if (true) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
GL20.glEnable(GL20.GL_DEPTH_TEST);
|
||||
|
||||
GL20.glDepthRange(getNearPlane(), getFarPlane());
|
||||
|
@ -87,8 +91,9 @@ public class EffectsHandler {
|
|||
Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer();
|
||||
|
||||
GL30.glBindFramebuffer(FramebufferConstants.FRAME_BUFFER, framebuffer.framebufferObject);
|
||||
GL30.glClear(GL30.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
PostProcessingProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC);
|
||||
SphereFilterProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC);
|
||||
program.bind();
|
||||
|
||||
program.bindColorTexture(mainBuffer.getColorAttachment());
|
||||
|
@ -104,15 +109,37 @@ public class EffectsHandler {
|
|||
|
||||
Matrix4f inverseView = view.copy();
|
||||
inverseView.invert();
|
||||
// Matrix4f inverseView = new Matrix4f();
|
||||
// inverseView.loadIdentity();
|
||||
program.bindInverseView(inverseView);
|
||||
|
||||
Vector3d pos = new Vector3d(286, 73, -149);
|
||||
Vector3d pos1 = new Vector3d(330, 0, 110);
|
||||
// Vector3d pos1 = new Vector3d(852, 79, -204);
|
||||
// Vector3d pos2 = new Vector3d(858, 95, -260);
|
||||
// Vector3d pos3 = new Vector3d(906, 84, -207);
|
||||
Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||
|
||||
Vector3d shaderPos = pos.subtract(cameraPos).scale(1 / getFarPlane());
|
||||
program.setSphere(shaderPos, 20f / getFarPlane(), 0.01f);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
double angle = (Math.PI * AnimationTickHolder.getRenderTime() / 40) + i * Math.PI / 4;
|
||||
|
||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||
.setCenter(pos1.subtract(cameraPos).add(0, 0, i * 30))
|
||||
.setRadius(15)
|
||||
.setFeather(0.5f)
|
||||
.setFilter(ColorMatrices.hueShift((float) i / 16 * 360 + AnimationTickHolder.getRenderTime())));
|
||||
}
|
||||
|
||||
// program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||
// .setCenter(pos2.subtract(cameraPos))
|
||||
// .setRadius(50)
|
||||
// .setFeather(0.5f)
|
||||
// .setFilter(ColorMatrices.sepia(1)));
|
||||
//
|
||||
// program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||
// .setCenter(pos3.subtract(cameraPos))
|
||||
// .setRadius(20)
|
||||
// .setFeather(3f)
|
||||
// .setFilter(ColorMatrices.saturate(4)));
|
||||
|
||||
program.uploadFilters();
|
||||
|
||||
program.setFarPlane(getFarPlane());
|
||||
program.setNearPlane(getNearPlane());
|
||||
|
@ -123,7 +150,9 @@ public class EffectsHandler {
|
|||
|
||||
program.bindColorTexture(0);
|
||||
program.bindDepthTexture(0);
|
||||
GL20.glActiveTexture(GL20.GL_TEXTURE0);
|
||||
|
||||
program.clear();
|
||||
program.unbind();
|
||||
|
||||
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject);
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
package com.simibubi.create.foundation.render.backend.effects;
|
||||
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
|
||||
public class PostProcessingProgram extends GlProgram {
|
||||
|
||||
final int uDepth;
|
||||
final int uColor;
|
||||
|
||||
final int uInverseProjection;
|
||||
final int uInverseView;
|
||||
|
||||
final int uNearPlane;
|
||||
final int uFarPlane;
|
||||
final int uSphereCenter;
|
||||
final int uSphereRadius;
|
||||
final int uSphereFeather;
|
||||
|
||||
|
||||
public PostProcessingProgram(ResourceLocation name, int handle) {
|
||||
super(name, handle);
|
||||
|
||||
uInverseProjection = getUniformLocation("uInverseProjection");
|
||||
uInverseView = getUniformLocation("uInverseView");
|
||||
uNearPlane = getUniformLocation("uNearPlane");
|
||||
uFarPlane = getUniformLocation("uFarPlane");
|
||||
uSphereCenter = getUniformLocation("uSphereCenter");
|
||||
uSphereRadius = getUniformLocation("uSphereRadius");
|
||||
uSphereFeather = getUniformLocation("uSphereFeather");
|
||||
|
||||
bind();
|
||||
uDepth = setSamplerBinding("uDepth", 8);
|
||||
uColor = setSamplerBinding("uColor", 9);
|
||||
unbind();
|
||||
}
|
||||
|
||||
public void setNearPlane(float nearPlane) {
|
||||
GL20.glUniform1f(uNearPlane, nearPlane);
|
||||
}
|
||||
|
||||
public void setFarPlane(float farPlane) {
|
||||
GL20.glUniform1f(uFarPlane, farPlane);
|
||||
}
|
||||
|
||||
public void setSphere(Vector3d center, float radius, float feather) {
|
||||
GL20.glUniform3f(uSphereCenter, (float) center.x, (float) center.y, (float) center.z);
|
||||
|
||||
GL20.glUniform1f(uSphereRadius, radius);
|
||||
GL20.glUniform1f(uSphereFeather, feather);
|
||||
}
|
||||
|
||||
public void bindInverseProjection(Matrix4f mat) {
|
||||
uploadMatrixUniform(uInverseProjection, mat);
|
||||
}
|
||||
|
||||
public void bindInverseView(Matrix4f mat) {
|
||||
uploadMatrixUniform(uInverseView, mat);
|
||||
}
|
||||
|
||||
public void bindDepthTexture(int textureObject) {
|
||||
GL20.glActiveTexture(GL20.GL_TEXTURE8);
|
||||
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
|
||||
}
|
||||
|
||||
public void bindColorTexture(int textureObject) {
|
||||
GL20.glActiveTexture(GL20.GL_TEXTURE9);
|
||||
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
package com.simibubi.create.foundation.render.backend.effects;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.RenderUtil;
|
||||
import com.simibubi.create.foundation.render.backend.gl.GlBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
|
||||
public class SphereFilterProgram extends GlProgram {
|
||||
|
||||
protected static final int BLOCK_BINDING = 4;
|
||||
|
||||
protected static final int SPHERE_FILTER_SIZE = 4 * 16 + 16 + 4 * 16 * 16;
|
||||
|
||||
protected static final int MAX_FILTERS = 16;
|
||||
|
||||
protected static final int BUFFER_SIZE = 4 + MAX_FILTERS * SPHERE_FILTER_SIZE;
|
||||
|
||||
GlBuffer effectsUBO;
|
||||
|
||||
protected final ArrayList<FilterSphere> filters = new ArrayList<>(16);
|
||||
|
||||
protected final int uniformBlock;
|
||||
|
||||
protected final int uDepth;
|
||||
protected final int uColor;
|
||||
|
||||
protected final int uInverseProjection;
|
||||
protected final int uInverseView;
|
||||
|
||||
protected final int uNearPlane;
|
||||
protected final int uFarPlane;
|
||||
// protected final int uSphereCenter;
|
||||
// protected final int uSphereRadius;
|
||||
// protected final int uSphereFeather;
|
||||
// protected final int uColorFilter;
|
||||
|
||||
public SphereFilterProgram(ResourceLocation name, int handle) {
|
||||
super(name, handle);
|
||||
|
||||
effectsUBO = new GlBuffer(GL31.GL_UNIFORM_BUFFER);
|
||||
|
||||
uniformBlock = GL31.glGetUniformBlockIndex(handle, "Filters");
|
||||
|
||||
GL31.glUniformBlockBinding(handle, uniformBlock, BLOCK_BINDING);
|
||||
|
||||
effectsUBO.bind();
|
||||
effectsUBO.alloc(BUFFER_SIZE, GL20.GL_STATIC_DRAW);
|
||||
GL31.glBindBufferBase(effectsUBO.getBufferType(), BLOCK_BINDING, effectsUBO.handle());
|
||||
effectsUBO.unbind();
|
||||
|
||||
uInverseProjection = getUniformLocation("uInverseProjection");
|
||||
uInverseView = getUniformLocation("uInverseView");
|
||||
uNearPlane = getUniformLocation("uNearPlane");
|
||||
uFarPlane = getUniformLocation("uFarPlane");
|
||||
//
|
||||
// uSphereCenter = getUniformLocation("uSphereCenter");
|
||||
// uSphereRadius = getUniformLocation("uSphereRadius");
|
||||
// uSphereFeather = getUniformLocation("uSphereFeather");
|
||||
// uColorFilter = getUniformLocation("uColorFilter");
|
||||
|
||||
bind();
|
||||
uDepth = setSamplerBinding("uDepth", 8);
|
||||
uColor = setSamplerBinding("uColor", 9);
|
||||
unbind();
|
||||
}
|
||||
|
||||
public void setNearPlane(float nearPlane) {
|
||||
GL20.glUniform1f(uNearPlane, nearPlane);
|
||||
}
|
||||
|
||||
public void setFarPlane(float farPlane) {
|
||||
GL20.glUniform1f(uFarPlane, farPlane);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
filters.clear();
|
||||
}
|
||||
|
||||
public void addSphere(FilterSphere filterSphere) {
|
||||
filters.add(filterSphere);
|
||||
}
|
||||
|
||||
public void uploadFilters() {
|
||||
effectsUBO.bind(GL20.GL_ARRAY_BUFFER);
|
||||
effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, this::uploadUBO);
|
||||
effectsUBO.unbind(GL20.GL_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
// public void setSphere(FilterSphere sphere) {
|
||||
// GL20.glUniform3f(uSphereCenter, (float) sphere.center.x, (float) sphere.center.y, (float) sphere.center.z);
|
||||
//
|
||||
// GL20.glUniform1f(uSphereRadius, sphere.radius);
|
||||
// GL20.glUniform1f(uSphereFeather, sphere.feather);
|
||||
//
|
||||
// uploadMatrixUniform(uColorFilter, sphere.filter);
|
||||
// }
|
||||
|
||||
public void bindInverseProjection(Matrix4f mat) {
|
||||
uploadMatrixUniform(uInverseProjection, mat);
|
||||
}
|
||||
|
||||
public void bindInverseView(Matrix4f mat) {
|
||||
uploadMatrixUniform(uInverseView, mat);
|
||||
}
|
||||
|
||||
public void bindDepthTexture(int textureObject) {
|
||||
GL20.glActiveTexture(GL20.GL_TEXTURE8);
|
||||
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
|
||||
}
|
||||
|
||||
public void bindColorTexture(int textureObject) {
|
||||
GL20.glActiveTexture(GL20.GL_TEXTURE9);
|
||||
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
|
||||
}
|
||||
|
||||
private void uploadUBO(ByteBuffer buf) {
|
||||
buf.putInt(filters.size());
|
||||
buf.position(16);
|
||||
FloatBuffer floatBuffer = buf.asFloatBuffer();
|
||||
|
||||
//floatBuffer.position(4);
|
||||
filters.forEach(it -> it.write(floatBuffer));
|
||||
}
|
||||
|
||||
public static class FilterSphere {
|
||||
public Vector3d center;
|
||||
public float radius;
|
||||
public float feather;
|
||||
|
||||
public Matrix4f filter;
|
||||
|
||||
public FilterSphere setCenter(Vector3d center) {
|
||||
this.center = center;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilterSphere setRadius(float radius) {
|
||||
this.radius = radius;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilterSphere setFeather(float feather) {
|
||||
this.feather = feather;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilterSphere setFilter(Matrix4f filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void write(FloatBuffer buf) {
|
||||
buf.put(new float[]{
|
||||
(float) center.x,
|
||||
(float) center.y,
|
||||
(float) center.z,
|
||||
radius,
|
||||
feather,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
});
|
||||
|
||||
buf.put(RenderUtil.writeMatrix(filter));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,20 +12,28 @@ public class GlBuffer extends GlObject {
|
|||
|
||||
protected final int bufferType;
|
||||
|
||||
public GlBuffer(int bufferType) {
|
||||
setHandle(GL20.glGenBuffers());
|
||||
this.bufferType = bufferType;
|
||||
}
|
||||
public GlBuffer(int bufferType) {
|
||||
setHandle(GL20.glGenBuffers());
|
||||
this.bufferType = bufferType;
|
||||
}
|
||||
|
||||
public int getBufferType() {
|
||||
return bufferType;
|
||||
public int getBufferType() {
|
||||
return bufferType;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
GL20.glBindBuffer(bufferType, handle());
|
||||
bind(bufferType);
|
||||
}
|
||||
|
||||
public void bind(int type) {
|
||||
GL20.glBindBuffer(type, handle());
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
unbind(bufferType);
|
||||
}
|
||||
|
||||
public void unbind(int bufferType) {
|
||||
GL20.glBindBuffer(bufferType, 0);
|
||||
}
|
||||
|
||||
|
@ -43,11 +51,15 @@ public class GlBuffer extends GlObject {
|
|||
Backend.compat.mapBuffer(bufferType, 0, length, upload);
|
||||
}
|
||||
|
||||
public void map(int offset, int length, Consumer<ByteBuffer> upload) {
|
||||
Backend.compat.mapBuffer(bufferType, offset, length, upload);
|
||||
}
|
||||
public void map(int offset, int length, Consumer<ByteBuffer> upload) {
|
||||
Backend.compat.mapBuffer(bufferType, offset, length, upload);
|
||||
}
|
||||
|
||||
protected void deleteInternal(int handle) {
|
||||
GL20.glDeleteBuffers(handle);
|
||||
}
|
||||
public void map(int type, int offset, int length, Consumer<ByteBuffer> upload) {
|
||||
Backend.compat.mapBuffer(type, offset, length, upload);
|
||||
}
|
||||
|
||||
protected void deleteInternal(int handle) {
|
||||
GL20.glDeleteBuffers(handle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
#version 140
|
||||
|
||||
#flwinclude <"create:core/color.glsl">
|
||||
|
||||
in vec2 ScreenCoord;
|
||||
in vec3 WorldDir;
|
||||
|
||||
out vec4 Color;
|
||||
|
||||
// constants
|
||||
uniform sampler2D uDepth;
|
||||
uniform sampler2D uColor;
|
||||
uniform float uNearPlane = 0.15;
|
||||
uniform float uFarPlane = 1.;
|
||||
|
||||
struct SphereFilter {
|
||||
vec4 sphere;// <vec3 position, float radius>
|
||||
float feather;
|
||||
mat4 colorOp;
|
||||
};
|
||||
|
||||
#define N 16
|
||||
layout (std140) uniform Filters {
|
||||
int uCount;
|
||||
SphereFilter uSpheres[N];
|
||||
};
|
||||
|
||||
float linearizeDepth(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));
|
||||
}
|
||||
|
||||
vec4 filterColor(mat4 colorOp, vec4 frag) {
|
||||
// preserve alpha while transforming color
|
||||
vec4 i = vec4(frag.rgb, 1.);
|
||||
i *= colorOp;
|
||||
return vec4(i.rgb, frag.a);
|
||||
}
|
||||
|
||||
float getDepth() {
|
||||
float depth = texture2D(uDepth, ScreenCoord).r;
|
||||
|
||||
depth = linearizeDepth(depth, uNearPlane, uFarPlane);
|
||||
//depth = ( - uNearPlane) / (uFarPlane - uNearPlane);
|
||||
//depth = depth / uFarPlane;
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float depth = getDepth();
|
||||
vec3 worldPos = WorldDir * depth;
|
||||
|
||||
vec4 accum = texture2D(uColor, ScreenCoord);
|
||||
|
||||
for (int i = 0; i < uCount; i++) {
|
||||
SphereFilter s = uSpheres[i];
|
||||
|
||||
float distance = distance(s.sphere.xyz, worldPos);
|
||||
float strength = 1 - smoothstep(s.sphere.w - s.feather, s.sphere.w + s.feather, distance);
|
||||
|
||||
accum = mix(accum, filterColor(s.colorOp, accum), strength);
|
||||
}
|
||||
|
||||
Color = accum;
|
||||
//Color = vec4(vec3(distance / uFarPlane), 1.);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#version 140
|
||||
|
||||
in vec4 aVertex;// <vec2 position, vec2 texCoords>
|
||||
|
||||
out vec2 ScreenCoord;
|
||||
out vec3 WorldDir;
|
||||
|
||||
uniform mat4 uInverseProjection;
|
||||
uniform mat4 uInverseView;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aVertex.xy, 0., 1.);
|
||||
ScreenCoord = aVertex.zw;
|
||||
|
||||
vec4 clip = vec4(aVertex.xy, 0., 1.);
|
||||
|
||||
clip *= uInverseProjection;
|
||||
|
||||
vec3 cameraDir = clip.xyz / clip.w;
|
||||
WorldDir = (uInverseView * vec4(cameraDir, 1.)).xyz;
|
||||
//worldDirection = (uInverseProjection * vec4(aVertex.xy, 0, 1.)).xyz;
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
#version 120
|
||||
|
||||
varying vec4 Vertex;
|
||||
varying vec3 CameraDir;
|
||||
|
||||
//layout (std140) struct Sphere {
|
||||
// vec4 positionRadius;
|
||||
// vec4 color;
|
||||
//} uSphere;
|
||||
|
||||
uniform sampler2D uDepth;
|
||||
uniform sampler2D uColor;
|
||||
uniform mat4 uInverseProjection;
|
||||
uniform mat4 uInverseView;
|
||||
|
||||
uniform float uNearPlane = 0.15;
|
||||
uniform float uFarPlane = 1;
|
||||
uniform vec3 uSphereCenter = vec3(0, 0, 0);
|
||||
uniform float uSphereRadius = 1;
|
||||
uniform float uSphereFeather = 0.05;
|
||||
|
||||
float linearizeDepth(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));
|
||||
}
|
||||
|
||||
vec4 filterColor(vec4 frag) {
|
||||
const vec3 lum = vec3(0.21, 0.71, 0.07);
|
||||
float grey = dot(frag.rgb, lum.rgb);
|
||||
return vec4(grey, grey, grey, frag.a);
|
||||
}
|
||||
|
||||
vec3 getWorldPos(float depth) {
|
||||
vec3 cameraPos = CameraDir * depth;
|
||||
|
||||
vec3 worldPos = (uInverseView * vec4(cameraPos, 1)).xyz;
|
||||
|
||||
return worldPos;
|
||||
}
|
||||
|
||||
float getDepth() {
|
||||
float depth = texture2D(uDepth, Vertex.zw).r;
|
||||
|
||||
depth = linearizeDepth(depth, uNearPlane, uFarPlane);
|
||||
//depth = ( - uNearPlane) / (uFarPlane - uNearPlane);
|
||||
depth = depth / uFarPlane;
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float depth = getDepth();
|
||||
vec3 worldPos = getWorldPos(depth);
|
||||
|
||||
float distance = distance(uSphereCenter, worldPos);
|
||||
float strength = smoothstep(uSphereRadius - uSphereFeather, uSphereRadius + uSphereFeather, distance);
|
||||
|
||||
vec4 fragColor = texture2D(uColor, Vertex.zw);
|
||||
|
||||
gl_FragColor = mix(fragColor, filterColor(fragColor), strength);
|
||||
//gl_FragColor = vec4(worldPos, 1);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// All components are in the range [0…1], including hue.
|
||||
vec3 rgb2hsv(vec3 c) {
|
||||
const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
// All components are in the range [0…1], including hue.
|
||||
vec3 hsv2rgb(vec3 hsv) {
|
||||
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(hsv.xxx + K.xyz) * 6.0 - K.www);
|
||||
return hsv.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hsv.y);
|
||||
}
|
||||
|
||||
vec3 hsv2rgbWrapped(vec3 hsv) {
|
||||
hsv.x = fract(hsv.x);
|
||||
return hsv2rgb(hsv);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#version 120
|
||||
|
||||
attribute vec4 aVertex;// <vec2 position, vec2 texCoords>
|
||||
|
||||
varying vec4 Vertex;
|
||||
varying vec3 CameraDir;
|
||||
|
||||
uniform mat4 uInverseProjection;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aVertex.xy, 0.0f, 1.0f);
|
||||
Vertex = aVertex;
|
||||
|
||||
vec4 clip = vec4(aVertex.xy, 0, 1);
|
||||
|
||||
clip *= uInverseProjection;
|
||||
|
||||
CameraDir = clip.xyz / clip.w;
|
||||
//worldDirection = (uInverseProjection * vec4(aVertex.xy, 0, 1.)).xyz;
|
||||
}
|
Loading…
Reference in a new issue