More versatile ui/settings

- The channel mask still needs work
 - Add contrast filter
This commit is contained in:
JozsefA 2021-04-28 00:01:26 -07:00
parent 70188889be
commit 54f5783489
17 changed files with 336 additions and 144 deletions

View file

@ -1154,8 +1154,17 @@
"create.gui.chromatic_projector.filter.saturate": "Saturate",
"create.gui.chromatic_projector.filter.hue_shift": "Hue shift",
"create.gui.chromatic_projector.filter.darken": "Darken",
"create.gui.chromatic_projector.filter.contrast": "Contrast",
"create.gui.chromatic_projector.filter.end": "End",
"create.gui.chromatic_projector.filter": "Filter",
"create.gui.chromatic_projector.surface": "Surface",
"create.gui.chromatic_projector.field": "Field",
"create.gui.chromatic_projector.strength": "Strength",
"create.gui.chromatic_projector.radius": "Radius",
"create.gui.chromatic_projector.feather": "Feather",
"create.gui.chromatic_projector.density": "Density",
"create.gui.chromatic_projector.fade": "Fade",
"create.gui.chromatic_projector.blend": "Blend",
"_": "->------------------------] Subtitles [------------------------<-",
"create.subtitle.cogs": "Cogwheels rumble",
"create.subtitle.slime_added": "Slime squishes",
@ -1163,8 +1172,8 @@
"create.subtitle.mechanical_press_activation_belt": "Mechanical Press bonks",
"create.subtitle.blockzapper_confirm": "Affirmative ding",
"create.subtitle.depot_slide": "Item slides",
"create.subtitle.blockzapper_place": "Blockzapper zaps",
"create.subtitle.blaze_munch": "Blaze Burner munches",
"create.subtitle.blockzapper_place": "Blockzapper zaps",
"create.subtitle.blaze_munch": "Blaze Burner munches",
"create.subtitle.schematicannon_launch_block": "Schematicannon fires",
"create.subtitle.funnel_flap": "Funnel Flaps",
"create.subtitle.schematicannon_finish": "Schematicannon dings",

View file

@ -13,7 +13,7 @@ public class ChromaticProjectorInstance extends TileEntityInstance<ChromaticProj
@Override
public void beginFrame() {
Backend.effects.addSphere(tile.makeFilter());
Backend.effects.addSphere(tile.getFilter());
}
@Override

View file

@ -25,10 +25,12 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
private final ItemStack renderedItem = AllBlocks.CHROMATIC_PROJECTOR.asStack();
private final AllGuiTextures background = AllGuiTextures.PROJECTOR;
private final int guiBottom = guiTop + background.height;
private final int guiRight = guiLeft + background.width;
private IconButton confirmButton;
private final ITextComponent title = Lang.translate("gui.chromatic_projector.title");
private Vector<FilterStep> stages;
private final Vector<FilterStep> stages;
private Vector<Vector<ScrollInput>> inputs;
@ -39,6 +41,15 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
private ScrollInput feather;
private ScrollInput fade;
private IconButton blend;
private ScrollInput strength;
private IconButton fieldEffect;
private IconButton rChannel;
private IconButton gChannel;
private IconButton bChannel;
public ChromaticProjectorScreen(ChromaticProjectorTileEntity te) {
this.tile = te;
this.stages = te.stages;
@ -62,35 +73,73 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
for (int row = 0; row < stages.size(); row++)
initInputsOfRow(row);
int guiBottom = guiTop + background.height;
int guiRight = guiLeft + background.width;
confirmButton =
new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM);
new IconButton(guiRight - 33, guiBottom - 26, AllIcons.I_CONFIRM);
widgets.add(confirmButton);
int xRight = guiLeft + 53;
int xLeft = guiLeft + 93;
int yTop = guiTop + 117;
int yBottom = guiTop + 139;
initEffectSettings();
initMetaSettings();
}
radius = new ScrollInput(xRight, yTop, 28, 18)
.titled(new StringTextComponent("Radius"))
private void initMetaSettings() {
int guiBottom = guiTop + background.height;
int y = guiBottom - 23;
blend = new IconButton(guiLeft + 16, y, AllIcons.I_FX_BLEND);
blend.setToolTip(Lang.translate("gui.chromatic_projector.blend"));
int channelX = guiLeft + 39;
rChannel = new IconButton(channelX, y, AllIcons.I_FX_BLEND);
rChannel.setToolTip(new StringTextComponent("R"));
channelX += 18;
gChannel = new IconButton(channelX, y, AllIcons.I_FX_BLEND);
gChannel.setToolTip(new StringTextComponent("G"));
channelX += 18;
bChannel = new IconButton(channelX, y, AllIcons.I_FX_BLEND);
bChannel.setToolTip(new StringTextComponent("B"));
fieldEffect = new IconButton(guiLeft + 135, y, tile.field ? AllIcons.I_FX_FIELD_ON : AllIcons.I_FX_FIELD_OFF);
fieldEffect.setToolTip(Lang.translate("gui.chromatic_projector.field"));
strength = new ScrollInput(guiLeft + 159, y, 25, 18)
.titled(Lang.translate("gui.chromatic_projector.strength"))
.withStepFunction(ctx -> step(ctx, 5))
.calling(tile::setStrength)
.withRange(0, 101)
.setState((int) (tile.strength * 100));
Collections.addAll(widgets, blend, rChannel, gChannel, bChannel, fieldEffect, strength);
}
private void initEffectSettings() {
int x = guiLeft + 188;
int y = guiTop + 40;
radius = new ScrollInput(x, y, 28, 18)
.titled(Lang.translate("gui.chromatic_projector.radius"))
.withStepFunction(ctx -> step(ctx, 2))
.calling(tile::setRadius)
.withRange(0, 201)
.setState((int) (tile.radius * 2));
feather = new ScrollInput(xRight, yBottom, 28, 18)
.titled(new StringTextComponent("Feather"))
y += 22;
feather = new ScrollInput(x, y, 28, 18)
.titled(Lang.translate("gui.chromatic_projector.feather"))
.withStepFunction(ctx -> step(ctx, 5))
.calling(tile::setFeather)
.withRange(0, 201)
.setState((int) (tile.feather * 10));
density = new ScrollInput(xLeft, yTop, 28, 18)
.titled(new StringTextComponent("Density"))
y += 22;
density = new ScrollInput(x, y, 28, 18)
.titled(Lang.translate("gui.chromatic_projector.density"))
.withStepFunction(ctx -> step(ctx, 10))
.calling(tile::setDensity)
.withRange(0, 401)
.setState((int) (tile.density * 100));
fade = new ScrollInput(xLeft, yBottom, 28, 18)
.titled(new StringTextComponent("Fade"))
y += 22;
fade = new ScrollInput(x, y, 28, 18)
.titled(Lang.translate("gui.chromatic_projector.fade"))
.withStepFunction(ctx -> step(ctx, 1))
.calling(tile::setFade)
.withRange(0, 51)
@ -112,7 +161,7 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
ScrollInput type =
new SelectionScrollInput(x, y + rowHeight * row, 86, 18)
.forOptions(ColorEffect.getOptions())
.calling(state -> instructionUpdated(row, state))
.calling(state -> stageUpdated(row, state))
.setState(filter.filter.id)
.titled(Lang.translate("gui.chromatic_projector.filter"));
ScrollInput value =
@ -174,6 +223,8 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
renderScroll(matrixStack, feather, 10f);
renderScroll(matrixStack, fade, 10f);
renderScroll(matrixStack, strength, 100f);
textRenderer.drawWithShadow(matrixStack, title, guiLeft - 3 + (background.width - textRenderer.getWidth(title)) / 2, guiTop + 3,
0xffffff);
@ -188,7 +239,7 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
String text = String.valueOf(input.getState() / divisor);
int stringWidth = textRenderer.getStringWidth(text);
textRenderer.drawWithShadow(matrixStack, text, input.x + (12 - stringWidth / 2), input.y + 5, 0xFFFFEE);
textRenderer.drawWithShadow(matrixStack, text, input.x + 2, input.y + 5, 0xFFFFEE);
}
private void label(MatrixStack matrixStack, int x, int y, ITextComponent text) {
@ -204,7 +255,7 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
sendPacket();
}
private void instructionUpdated(int index, int state) {
private void stageUpdated(int index, int state) {
ColorEffect newValue = ColorEffect.all.get(state);
stages.get(index).filter = newValue;
stages.get(index).value = newValue.defaultValue;
@ -231,6 +282,33 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
return true;
}
if (blend.isHovered()) {
tile.blend = !tile.blend;
return true;
}
if (fieldEffect.isHovered()) {
tile.field = !tile.field;
fieldEffect.setIcon(tile.field ? AllIcons.I_FX_FIELD_ON : AllIcons.I_FX_FIELD_OFF);
return fieldEffect.mouseClicked(x, y, button);
}
if (rChannel.isHovered()) {
tile.rMask = !tile.rMask;
return true;
}
if (gChannel.isHovered()) {
tile.gMask = !tile.gMask;
return true;
}
if (bChannel.isHovered()) {
tile.bMask = !tile.bMask;
return true;
}
return super.mouseClicked(x, y, button);
}

View file

@ -10,7 +10,6 @@ import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraftforge.common.util.Constants;
public class ChromaticProjectorTileEntity extends SyncedTileEntity implements IInstanceRendered {
@ -18,27 +17,49 @@ public class ChromaticProjectorTileEntity extends SyncedTileEntity implements II
Vector<FilterStep> stages = FilterStep.createDefault();
float radius = 3f;
float density = 1;
float feather = 1;
float density = 1;
float fade = 1;
boolean blend = true;
public boolean surface = true;
public boolean field = true;
public float strength = 1;
public boolean rMask = true;
public boolean gMask = true;
public boolean bMask = true;
public ChromaticProjectorTileEntity(TileEntityType<?> te) {
super(te);
}
public FilterSphere makeFilter() {
Matrix4f filter = FilterStep.fold(stages);
public FilterSphere getFilter() {
BlockPos pos = getPos();
return new FilterSphere()
.setFilter(filter)
.setCenter(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5)
.setRadius(radius)
.setDensity(density)
.setFeather(feather)
.setBlendOver(true)
.setFade(fade);
FilterSphere sphere = new FilterSphere();
sphere.x = (float) (pos.getX() + 0.5);
sphere.y = (float) (pos.getY() + 0.5);
sphere.z = (float) (pos.getZ() + 0.5);
sphere.radius = radius;
sphere.feather = feather;
sphere.density = density;
sphere.fade = fade;
sphere.blend = blend;
sphere.surface = surface;
sphere.field = field;
sphere.strength = strength;
sphere.rMask = rMask;
sphere.gMask = gMask;
sphere.bMask = bMask;
sphere.filter = FilterStep.fold(stages);
return sphere;
}
public ChromaticProjectorTileEntity setRadius(int radius) {
@ -66,6 +87,11 @@ public class ChromaticProjectorTileEntity extends SyncedTileEntity implements II
return this;
}
public ChromaticProjectorTileEntity setStrength(int strength) {
this.strength = strength / 100f;
return this;
}
@Override
public CompoundNBT write(CompoundNBT tag) {
super.write(tag);
@ -73,9 +99,19 @@ public class ChromaticProjectorTileEntity extends SyncedTileEntity implements II
tag.put("filters", FilterStep.writeAll(stages));
tag.putFloat("radius", radius);
tag.putFloat("density", density);
tag.putFloat("feather", feather);
tag.putFloat("density", density);
tag.putFloat("fade", fade);
tag.putBoolean("blend", blend);
tag.putBoolean("surface", surface);
tag.putBoolean("field", field);
tag.putFloat("strength", strength);
tag.putBoolean("rMask", rMask);
tag.putBoolean("gMask", gMask);
tag.putBoolean("bMask", bMask);
return tag;
}
@ -87,8 +123,18 @@ public class ChromaticProjectorTileEntity extends SyncedTileEntity implements II
stages = FilterStep.readAll(tag.getList("filters", Constants.NBT.TAG_COMPOUND));
radius = tag.getFloat("radius");
density = tag.getFloat("density");
feather = tag.getFloat("feather");
density = tag.getFloat("density");
fade = tag.getFloat("fade");
blend = tag.getBoolean("blend");
surface = tag.getBoolean("surface");
field = tag.getBoolean("field");
strength = tag.getFloat("strength");
rMask = tag.getBoolean("rMask");
gMask = tag.getBoolean("gMask");
bMask = tag.getBoolean("bMask");
}
}

View file

@ -19,12 +19,13 @@ public class ColorEffect {
static final HashMap<String, ColorEffect> lookup = new HashMap<>();
private static int nextId = 0;
public static final ColorEffect INVERT = create("invert", ColorMatrices::invert);
public static final ColorEffect SEPIA = create("sepia", ColorMatrices::sepia);
public static final ColorEffect GRAYSCALE = create("grayscale", ColorMatrices::grayscale);
public static final ColorEffect DARKEN = create("darken", ColorMatrices::darken).setDefaultValue(20);
public static final ColorEffect CONTRAST = create("contrast", ColorMatrices::contrast).setRange(0, 200).setDefaultValue(100);
public static final ColorEffect SATURATE = create("saturate", ColorMatrices::saturate).setRange(0, 200);
public static final ColorEffect HUE_SHIFT = create("hue_shift", ColorMatrices::hueShift).setRange(0, 360).setDivisor(1f).setDefaultValue(120);
public static final ColorEffect INVERT = create("invert", ColorMatrices::invert);
public static final ColorEffect END = create("end", ColorMatrices::identity).setBackground(AllGuiTextures.PROJECTOR_END);
boolean hasParameter;

View file

@ -12,9 +12,19 @@ public class ConfigureProjectorPacket extends TileEntityConfigurationPacket<Chro
Vector<CompoundNBT> stages;
float radius;
float density;
float feather;
float density;
float fade;
boolean blend;
public boolean surface;
public boolean field;
public float strength;
public boolean rMask;
public boolean gMask;
public boolean bMask;
public ConfigureProjectorPacket(PacketBuffer buffer) {
super(buffer);
@ -26,18 +36,38 @@ public class ConfigureProjectorPacket extends TileEntityConfigurationPacket<Chro
stages = tile.stages.stream()
.map(FilterStep::write)
.collect(Collectors.toCollection(Vector::new));
this.radius = tile.radius;
this.density = tile.density;
this.feather = tile.feather;
this.fade = tile.fade;
radius = tile.radius;
feather = tile.feather;
density = tile.density;
fade = tile.fade;
blend = tile.blend;
surface = tile.surface;
field = tile.field;
strength = tile.strength;
rMask = tile.rMask;
gMask = tile.gMask;
bMask = tile.bMask;
}
@Override
protected void writeSettings(PacketBuffer buffer) {
buffer.writeFloat(radius);
buffer.writeFloat(density);
buffer.writeFloat(feather);
buffer.writeFloat(density);
buffer.writeFloat(fade);
buffer.writeBoolean(blend);
buffer.writeBoolean(surface);
buffer.writeBoolean(field);
buffer.writeFloat(strength);
buffer.writeBoolean(rMask);
buffer.writeBoolean(gMask);
buffer.writeBoolean(bMask);
buffer.writeInt(stages.size());
for (CompoundNBT stage : stages) {
@ -48,9 +78,19 @@ public class ConfigureProjectorPacket extends TileEntityConfigurationPacket<Chro
@Override
protected void readSettings(PacketBuffer buffer) {
radius = buffer.readFloat();
density = buffer.readFloat();
feather = buffer.readFloat();
density = buffer.readFloat();
fade = buffer.readFloat();
blend = buffer.readBoolean();
surface = buffer.readBoolean();
field = buffer.readBoolean();
strength = buffer.readFloat();
rMask = buffer.readBoolean();
gMask = buffer.readBoolean();
bMask = buffer.readBoolean();
int count = buffer.readInt();
stages = new Vector<>(FilterStep.MAX_STEPS);
@ -66,10 +106,20 @@ public class ConfigureProjectorPacket extends TileEntityConfigurationPacket<Chro
.map(FilterStep::new)
.collect(Collectors.toCollection(Vector::new));
tile.radius = this.radius;
tile.density = this.density;
tile.feather = this.feather;
tile.fade = this.fade;
tile.radius = radius;
tile.feather = feather;
tile.density = density;
tile.fade = fade;
tile.blend = blend;
tile.surface = surface;
tile.field = field;
tile.strength = strength;
tile.rMask = rMask;
tile.gMask = gMask;
tile.bMask = bMask;
tile.sendData();
}

View file

@ -11,7 +11,7 @@ import net.minecraft.util.math.vector.Matrix4f;
public class FilterStep {
public static final int MAX_STEPS = 4;
public static final int MAX_STEPS = 6;
ColorEffect filter;
int value;

View file

@ -56,7 +56,7 @@ public enum AllGuiTextures implements IScreenRenderable {
SEQUENCER_EMPTY("sequencer.png", 0, 102, 162, 22),
SEQUENCER_AWAIT("sequencer.png", 0, 160, 162, 22),
PROJECTOR("projector.png", 173, 194),
PROJECTOR("projector.png", 235, 185),
PROJECTOR_FILTER_STRENGTH("projector.png", 0, 14, 162, 22),
PROJECTOR_FILTER("projector.png", 0, 36, 162, 22),
PROJECTOR_END("projector.png", 0, 58, 162, 22),

View file

@ -51,16 +51,19 @@ public class AllIcons implements IScreenRenderable {
I_PLAY = newRow(), I_PAUSE = next(), I_STOP = next(), I_PLACEMENT_SETTINGS = next(), I_ROTATE_CCW = next(),
I_HOUR_HAND_FIRST = next(), I_MINUTE_HAND_FIRST = next(), I_HOUR_HAND_FIRST_24 = next(),
I_PATTERN_SOLID = newRow(), I_PATTERN_CHECKERED = next(), I_PATTERN_CHECKERED_INVERSED = next(),
I_PATTERN_CHANCE_25 = next(),
I_PATTERN_SOLID = newRow(), I_PATTERN_CHECKERED = next(), I_PATTERN_CHECKERED_INVERSED = next(),
I_PATTERN_CHANCE_25 = next(),
I_PATTERN_CHANCE_50 = newRow(), I_PATTERN_CHANCE_75 = next(), I_FOLLOW_DIAGONAL = next(),
I_FOLLOW_MATERIAL = next(),
I_PATTERN_CHANCE_50 = newRow(), I_PATTERN_CHANCE_75 = next(), I_FOLLOW_DIAGONAL = next(),
I_FOLLOW_MATERIAL = next(),
I_SCHEMATIC = newRow(),
I_SCHEMATIC = newRow(),
I_MTD_LEFT = newRow(), I_MTD_CLOSE = next(), I_MTD_RIGHT = next(), I_MTD_SCAN = next(), I_MTD_REPLAY = next(),
I_MTD_USER_MODE = next(), I_MTD_SLOW_MODE = next();
I_MTD_LEFT = newRow(), I_MTD_CLOSE = next(), I_MTD_RIGHT = next(), I_MTD_SCAN = next(), I_MTD_REPLAY = next(),
I_MTD_USER_MODE = next(), I_MTD_SLOW_MODE = next(),
I_FX_SURFACE_OFF = newRow(), I_FX_SURFACE_ON = next(), I_FX_FIELD_OFF = next(), I_FX_FIELD_ON = next(),
I_FX_BLEND = next(), I_FX_BLEND_OFF = next();
public AllIcons(int x, int y) {
iconX = x * 16;

View file

@ -50,4 +50,7 @@ public class IconButton extends AbstractSimiWidget {
toolTip.add(text);
}
public void setIcon(AllIcons icon) {
this.icon = icon;
}
}

View file

@ -6,7 +6,7 @@ import net.minecraft.util.math.vector.Matrix3f;
import net.minecraft.util.math.vector.Matrix4f;
public class RenderUtil {
public static int nextPowerOf2(int a) {
public static int nextPowerOf2(int a) {
int h = Integer.highestOneBit(a);
return (h == a) ? h : (h << 1);
}
@ -16,13 +16,21 @@ public class RenderUtil {
return b == 0 && n != 0;
}
public static double lengthSqr(double x, double y, double z) {
return x * x + y * y + z * z;
}
public static double length(double x, double y, double z) {
return Math.sqrt(lengthSqr(x, y, z));
}
public static float[] writeMatrixStack(MatrixStack stack) {
return writeMatrixStack(stack.peek().getModel(), stack.peek().getNormal());
}
// GPUs want matrices in column major order.
public static float[] writeMatrixStack(Matrix4f model, Matrix3f normal) {
return new float[] {
return new float[]{
model.a00,
model.a10,
model.a20,

View file

@ -93,13 +93,32 @@ public class ColorMatrices {
}
public static Matrix4f darken(float amount) {
Matrix4f darken = new Matrix4f();
darken.loadIdentity();
darken.multiply(1f - amount);
darken.a03 = amount;
darken.a13 = amount;
darken.a23 = amount;
return darken;
Matrix4f mat = new Matrix4f();
mat.loadIdentity();
mat.multiply(1f - amount);
return mat;
}
public static Matrix4f brightness(float amount) {
Matrix4f mat = new Matrix4f();
mat.loadIdentity();
mat.a03 = amount;
mat.a13 = amount;
mat.a23 = amount;
return mat;
}
public static Matrix4f contrast(float amount) {
Matrix4f sub = new Matrix4f();
sub.a00 = amount;
sub.a11 = amount;
sub.a22 = amount;
sub.a33 = 1;
sub.a30 = 0.5f - amount * 0.5f;
sub.a31 = 0.5f - amount * 0.5f;
sub.a32 = 0.5f - amount * 0.5f;
return sub;
}
public static Matrix4f identity() {

View file

@ -9,6 +9,7 @@ import org.lwjgl.opengl.GL30;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.backend.Backend;
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.GlPrimitiveType;
import com.simibubi.create.foundation.render.backend.gl.GlVertexArray;
@ -116,10 +117,16 @@ public class EffectsHandler {
program.setCameraPos(cameraPos.inverse());
for (FilterSphere sphere : spheres) {
sphere.center = sphere.center.subtract(cameraPos);
sphere.x -= cameraPos.x;
sphere.y -= cameraPos.y;
sphere.z -= cameraPos.z;
}
spheres.sort((o1, o2) -> (int) Math.signum(o2.center.length() - o1.center.length()));
spheres.sort((o1, o2) -> {
double l1 = RenderUtil.length(o1.x, o1.y, o1.z);
double l2 = RenderUtil.length(o2.x, o2.y, o2.z);
return (int) Math.signum(l2 - l1);
});
program.uploadFilters(spheres);

View file

@ -5,87 +5,49 @@ import java.nio.FloatBuffer;
import com.simibubi.create.foundation.render.backend.RenderUtil;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
public class FilterSphere {
public Vector3d center;
public float x;
public float y;
public float z;
public float radius;
public float feather;
public float fade;
public float density = 2;
public float strength = 1;
public boolean blendOver = false;
public boolean blend = false;
public float r;
public float g;
public float b;
public float colorFeather;
public boolean surface = true;
public boolean field = true;
public float strength = 1;
public boolean rMask;
public boolean gMask;
public boolean bMask;
public Matrix4f filter;
public FilterSphere setCenter(Vector3d center) {
this.center = center;
return this;
}
public FilterSphere setCenter(double x, double y, double z) {
this.center = new Vector3d(x, y, z);
return this;
}
public FilterSphere setRadius(float radius) {
this.radius = radius;
return this;
}
public FilterSphere setFeather(float feather) {
this.feather = feather;
return this;
}
public FilterSphere setFade(float fade) {
this.fade = fade;
return this;
}
public FilterSphere setDensity(float density) {
this.density = density;
return this;
}
public FilterSphere setStrength(float strength) {
this.strength = strength;
return this;
}
public FilterSphere setFilter(Matrix4f filter) {
this.filter = filter;
return this;
}
public FilterSphere setBlendOver(boolean blendOver) {
this.blendOver = blendOver;
return this;
}
public void write(FloatBuffer buf) {
buf.put(new float[]{
(float) center.x,
(float) center.y,
(float) center.z,
x,
y,
z,
radius,
feather,
fade,
density,
blendOver ? 1f : 0f,
1f,
1f,
0f,
0f,
0.5f, //r,
0.1f, //g,
0.1f, //b,
0f, //colorFeather,
blend ? 1 : 0,
surface ? 1 : 0,
field ? 1 : 0,
strength,
0, // padding
rMask ? 1 : 0,
gMask ? 1 : 0,
bMask ? 1 : 0,
0, // padding
});
buf.put(RenderUtil.writeMatrix(filter));

View file

@ -17,8 +17,8 @@ uniform vec3 uCameraPos;
struct SphereFilter {
vec4 sphere;// <vec3 position, float radius>
vec4 d1;// <float feather, float fade, float density, float blend mode>
vec4 d2;// <float surfaceStrength, float bubbleStrength>
vec4 colorMask;// <vec3 rgb, float feather>
vec4 strength;// <float surfaceStrength, float bubbleStrength, float strength>
vec4 channelMask;// <vec3 rgb>
mat4 colorOp;
};
@ -69,6 +69,12 @@ vec2 raySphere(vec3 worldDir, vec3 position, float radius) {
return vec2(discriminant, hitDepth);
}
// if i == 0 return s
// if i == 1 return 1 - s
float invert(float s, float i) {
return i - 2*i*s + s;
}
float bubbleFilterStrength(vec3 worldDir, float depth, vec4 sphere, float feather, float density) {
vec3 position = sphere.xyz;
@ -96,18 +102,18 @@ float filterStrength(vec3 worldDir, float depth, inout SphereFilter f) {
vec4 data = f.d1;
float feather = data.x;
float strength = 0.;
float strength;
// transition effect
float transitionRadius = sphere.w + feather;
strength += 1. - smoothstep(transitionRadius, transitionRadius + data.y, length(sphere.xyz));
strength = 1. - smoothstep(transitionRadius, transitionRadius + max(0.5, data.y), length(sphere.xyz));
// bubble effect
strength += bubbleFilterStrength(worldDir, depth, sphere, feather, data.z);
strength = max(strength, bubbleFilterStrength(worldDir, depth, sphere, feather, data.z));
strength *= f.d2.y;
strength *= f.strength.y;
// surface effect
strength += surfaceFilterStrength(worldDir * depth, sphere, feather) * f.d2.x;
strength = max(strength, surfaceFilterStrength(worldDir * depth, sphere, feather) * f.strength.x);
return strength;
return strength * f.strength.z;
}
vec3 applyFilters(vec3 worldDir, float depth, vec3 diffuse) {
@ -127,13 +133,13 @@ vec3 applyFilters(vec3 worldDir, float depth, vec3 diffuse) {
vec3 filtered = filterColor(s.colorOp, baseColor);
vec3 baseHsv = rgb2hsv(baseColor);
vec3 maskHsv = rgb2hsv(s.colorMask.rgb);
vec3 diff = abs(baseHsv - maskHsv) * vec3(1., 1.1, 0.1);
float colorMask = step(s.colorMask.w, length(diff));
// vec3 baseHsv = rgb2hsv(baseColor);
// vec3 maskHsv = rgb2hsv(s.colorMask.rgb);
// float diff = dot(abs(baseHsv - maskHsv), vec3(1., 1.1, 0.1));
// float colorMask = step(s.colorMask.w, diff);
float mixing = clamp(strength, 0., 1.);
accum = mix(accum, filtered, mixing * colorMask);
accum = mix(accum, filtered, mixing * s.channelMask.xyz);
//accum = vec3(colorMask);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB