diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index b266bf403..b43e08e8e 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -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", diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorInstance.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorInstance.java index 3394a08c3..ea7aa760a 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorInstance.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorInstance.java @@ -13,7 +13,7 @@ public class ChromaticProjectorInstance extends TileEntityInstance stages; + private final Vector stages; private Vector> 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); } diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java index 338c2fd20..0bb20e983 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java @@ -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 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"); } } diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffect.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffect.java index 12c0a0822..0d072b419 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffect.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffect.java @@ -19,12 +19,13 @@ public class ColorEffect { static final HashMap 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; diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ConfigureProjectorPacket.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ConfigureProjectorPacket.java index be616532b..89eb463b3 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ConfigureProjectorPacket.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ConfigureProjectorPacket.java @@ -12,9 +12,19 @@ public class ConfigureProjectorPacket extends TileEntityConfigurationPacket 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(FilterStep.MAX_STEPS); @@ -66,10 +106,20 @@ public class ConfigureProjectorPacket extends TileEntityConfigurationPacket (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); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/FilterSphere.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/FilterSphere.java index 6cf354755..0b6d4f881 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/effects/FilterSphere.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/FilterSphere.java @@ -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)); diff --git a/src/main/resources/assets/create/flywheel/shaders/area_effect.frag b/src/main/resources/assets/create/flywheel/shaders/area_effect.frag index 3a43ac7a4..86e987ecc 100644 --- a/src/main/resources/assets/create/flywheel/shaders/area_effect.frag +++ b/src/main/resources/assets/create/flywheel/shaders/area_effect.frag @@ -17,8 +17,8 @@ uniform vec3 uCameraPos; struct SphereFilter { vec4 sphere;// vec4 d1;// - vec4 d2;// - vec4 colorMask;// + vec4 strength;// + vec4 channelMask;// 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); } } diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 1dff79b36..2fbdf43bb 100644 Binary files a/src/main/resources/assets/create/textures/gui/icons.png and b/src/main/resources/assets/create/textures/gui/icons.png differ diff --git a/src/main/resources/assets/create/textures/gui/projector.png b/src/main/resources/assets/create/textures/gui/projector.png index 968618e94..6638b2b2f 100644 Binary files a/src/main/resources/assets/create/textures/gui/projector.png and b/src/main/resources/assets/create/textures/gui/projector.png differ