mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 22:11:50 +01:00
Better projector gui
This commit is contained in:
parent
fc919c4ac4
commit
3879d55517
14 changed files with 300 additions and 171 deletions
|
@ -1153,6 +1153,7 @@
|
||||||
"create.gui.chromatic_projector.filter.grayscale": "Grayscale",
|
"create.gui.chromatic_projector.filter.grayscale": "Grayscale",
|
||||||
"create.gui.chromatic_projector.filter.saturate": "Saturate",
|
"create.gui.chromatic_projector.filter.saturate": "Saturate",
|
||||||
"create.gui.chromatic_projector.filter.hue_shift": "Hue shift",
|
"create.gui.chromatic_projector.filter.hue_shift": "Hue shift",
|
||||||
|
"create.gui.chromatic_projector.filter.darken": "Darken",
|
||||||
"create.gui.chromatic_projector.filter.end": "End",
|
"create.gui.chromatic_projector.filter.end": "End",
|
||||||
"create.gui.chromatic_projector.filter": "Filter",
|
"create.gui.chromatic_projector.filter": "Filter",
|
||||||
"_": "->------------------------] Subtitles [------------------------<-",
|
"_": "->------------------------] Subtitles [------------------------<-",
|
||||||
|
|
|
@ -116,6 +116,7 @@ import com.simibubi.create.content.contraptions.relays.gearbox.GearboxInstance;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxRenderer;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxRenderer;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEntity;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEntity;
|
||||||
|
import com.simibubi.create.content.curiosities.projector.ChromaticProjectorInstance;
|
||||||
import com.simibubi.create.content.curiosities.projector.ChromaticProjectorTileEntity;
|
import com.simibubi.create.content.curiosities.projector.ChromaticProjectorTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
||||||
|
@ -646,21 +647,23 @@ public class AllTileEntities {
|
||||||
.instance(() -> AdjustableRepeaterInstance::new)
|
.instance(() -> AdjustableRepeaterInstance::new)
|
||||||
.validBlocks(AllBlocks.ADJUSTABLE_REPEATER)
|
.validBlocks(AllBlocks.ADJUSTABLE_REPEATER)
|
||||||
.renderer(() -> AdjustableRepeaterRenderer::new)
|
.renderer(() -> AdjustableRepeaterRenderer::new)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final TileEntityEntry<AdjustablePulseRepeaterTileEntity> ADJUSTABLE_PULSE_REPEATER =
|
public static final TileEntityEntry<AdjustablePulseRepeaterTileEntity> ADJUSTABLE_PULSE_REPEATER =
|
||||||
Create.registrate()
|
Create.registrate()
|
||||||
.tileEntity("adjustable_pulse_repeater", AdjustablePulseRepeaterTileEntity::new)
|
.tileEntity("adjustable_pulse_repeater", AdjustablePulseRepeaterTileEntity::new)
|
||||||
.instance(() -> AdjustableRepeaterInstance::new)
|
.instance(() -> AdjustableRepeaterInstance::new)
|
||||||
.validBlocks(AllBlocks.ADJUSTABLE_PULSE_REPEATER)
|
.validBlocks(AllBlocks.ADJUSTABLE_PULSE_REPEATER)
|
||||||
.renderer(() -> AdjustableRepeaterRenderer::new)
|
.renderer(() -> AdjustableRepeaterRenderer::new)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final TileEntityEntry<ChromaticProjectorTileEntity> TESTFX =
|
public static final TileEntityEntry<ChromaticProjectorTileEntity> CHROMATIC_PROJECTOR =
|
||||||
Create.registrate()
|
Create.registrate()
|
||||||
.tileEntity("chromatic_projector", ChromaticProjectorTileEntity::new)
|
.tileEntity("chromatic_projector", ChromaticProjectorTileEntity::new)
|
||||||
.validBlocks(AllBlocks.CHROMATIC_PROJECTOR)
|
.instance(() -> ChromaticProjectorInstance::new)
|
||||||
.register();
|
.validBlocks(AllBlocks.CHROMATIC_PROJECTOR)
|
||||||
|
.register();
|
||||||
|
|
||||||
public static void register() {}
|
public static void register() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class ChromaticProjectorBlock extends Block implements ITE<ChromaticProje
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
return AllTileEntities.TESTFX.create();
|
return AllTileEntities.CHROMATIC_PROJECTOR.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.simibubi.create.content.curiosities.projector;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance;
|
||||||
|
|
||||||
|
public class ChromaticProjectorInstance extends TileEntityInstance<ChromaticProjectorTileEntity> implements IDynamicInstance {
|
||||||
|
|
||||||
|
public ChromaticProjectorInstance(InstancedTileRenderer<?> renderer, ChromaticProjectorTileEntity tile) {
|
||||||
|
super(renderer, tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame() {
|
||||||
|
Backend.effects.addSphere(tile.makeFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean decreaseFramerateWithDistance() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.content.curiosities.projector;
|
package com.simibubi.create.content.curiosities.projector;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
@ -11,6 +12,7 @@ import com.simibubi.create.foundation.gui.GuiGameElement;
|
||||||
import com.simibubi.create.foundation.gui.widgets.IconButton;
|
import com.simibubi.create.foundation.gui.widgets.IconButton;
|
||||||
import com.simibubi.create.foundation.gui.widgets.ScrollInput;
|
import com.simibubi.create.foundation.gui.widgets.ScrollInput;
|
||||||
import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput;
|
import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -35,12 +37,24 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
|
||||||
|
|
||||||
private Vector<Vector<ScrollInput>> inputs;
|
private Vector<Vector<ScrollInput>> inputs;
|
||||||
|
|
||||||
|
ChromaticProjectorTileEntity tile;
|
||||||
|
|
||||||
|
private ScrollInput radius;
|
||||||
|
private ScrollInput density;
|
||||||
|
private ScrollInput feather;
|
||||||
|
private ScrollInput fade;
|
||||||
|
|
||||||
public ChromaticProjectorScreen(ChromaticProjectorTileEntity te) {
|
public ChromaticProjectorScreen(ChromaticProjectorTileEntity te) {
|
||||||
|
this.tile = te;
|
||||||
this.stages = te.stages;
|
this.stages = te.stages;
|
||||||
this.pos = te.getPos();
|
this.pos = te.getPos();
|
||||||
//compareTag = Instruction.serializeAll(stages);
|
//compareTag = Instruction.serializeAll(stages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Integer step(ScrollValueBehaviour.StepContext ctx, int base) {
|
||||||
|
return ctx.control ? 1 : base * (ctx.shift ? 5 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init() {
|
protected void init() {
|
||||||
setWindowSize(background.width + 50, background.height);
|
setWindowSize(background.width + 50, background.height);
|
||||||
|
@ -57,6 +71,32 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
|
||||||
confirmButton =
|
confirmButton =
|
||||||
new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM);
|
new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM);
|
||||||
widgets.add(confirmButton);
|
widgets.add(confirmButton);
|
||||||
|
radius = new ScrollInput(guiLeft + 46, guiTop + 117, 28, 18)
|
||||||
|
.titled(new StringTextComponent("Radius"))
|
||||||
|
.withStepFunction(ctx -> step(ctx, 2))
|
||||||
|
.calling(tile::setRadius)
|
||||||
|
.withRange(0, 201)
|
||||||
|
.setState((int) (tile.radius * 2));
|
||||||
|
feather = new ScrollInput(guiLeft + 46, guiTop + 139, 28, 18)
|
||||||
|
.titled(new StringTextComponent("Feather"))
|
||||||
|
.withStepFunction(ctx -> step(ctx, 5))
|
||||||
|
.calling(tile::setFeather)
|
||||||
|
.withRange(0, 201)
|
||||||
|
.setState((int) (tile.feather * 4));
|
||||||
|
fade = new ScrollInput(guiLeft + 117, guiTop + 139, 28, 18)
|
||||||
|
.titled(new StringTextComponent("Fade"))
|
||||||
|
.withStepFunction(ctx -> step(ctx, 1))
|
||||||
|
.calling(tile::setFade)
|
||||||
|
.withRange(0, 51)
|
||||||
|
.setState((int) (tile.fade * 10));
|
||||||
|
density = new ScrollInput(guiLeft + 117, guiTop + 117, 28, 18)
|
||||||
|
.titled(new StringTextComponent("Density"))
|
||||||
|
.withStepFunction(ctx -> step(ctx, 10))
|
||||||
|
.calling(tile::setDensity)
|
||||||
|
.withRange(0, 401)
|
||||||
|
.setState((int) (tile.density * 100));
|
||||||
|
|
||||||
|
Collections.addAll(widgets, radius, density, feather, fade);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initInputsOfRow(int row) {
|
public void initInputsOfRow(int row) {
|
||||||
|
@ -73,10 +113,11 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
|
||||||
ScrollInput type =
|
ScrollInput type =
|
||||||
new SelectionScrollInput(x, y + rowHeight * row, 86, 18).forOptions(ColorEffects.getOptions())
|
new SelectionScrollInput(x, y + rowHeight * row, 86, 18).forOptions(ColorEffects.getOptions())
|
||||||
.calling(state -> instructionUpdated(index, state))
|
.calling(state -> instructionUpdated(index, state))
|
||||||
.setState(instruction.instruction.ordinal())
|
.setState(instruction.filter.ordinal())
|
||||||
.titled(Lang.translate("gui.chromatic_projector.filter"));
|
.titled(Lang.translate("gui.chromatic_projector.filter"));
|
||||||
ScrollInput value =
|
ScrollInput value =
|
||||||
new ScrollInput(x + 86 + 2, y + rowHeight * row, 28, 18).calling(state -> instruction.value = state);
|
new ScrollInput(x + 86 + 2, y + rowHeight * row, 28, 18)
|
||||||
|
.calling(state -> instruction.value = state);
|
||||||
|
|
||||||
rowInputs.add(type);
|
rowInputs.add(type);
|
||||||
rowInputs.add(value);
|
rowInputs.add(value);
|
||||||
|
@ -88,15 +129,15 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
|
||||||
public void updateParamsOfRow(int row) {
|
public void updateParamsOfRow(int row) {
|
||||||
FilterStep instruction = stages.get(row);
|
FilterStep instruction = stages.get(row);
|
||||||
Vector<ScrollInput> rowInputs = inputs.get(row);
|
Vector<ScrollInput> rowInputs = inputs.get(row);
|
||||||
ColorEffects def = instruction.instruction;
|
ColorEffects def = instruction.filter;
|
||||||
boolean hasValue = def.hasParameter;
|
boolean hasValue = def.hasParameter;
|
||||||
|
|
||||||
ScrollInput value = rowInputs.get(1);
|
ScrollInput value = rowInputs.get(1);
|
||||||
value.active = value.visible = hasValue;
|
value.active = value.visible = hasValue;
|
||||||
if (hasValue)
|
if (hasValue)
|
||||||
value.withRange(0, 100)
|
value.withRange(def.minValue, def.maxValue + 1)
|
||||||
//.titled(Lang.translate(def.parameterKey))
|
//.titled(Lang.translate(def.parameterKey))
|
||||||
//.withShiftStep(def.shiftStep)
|
.withShiftStep(5)
|
||||||
.setState(instruction.value)
|
.setState(instruction.value)
|
||||||
.onChanged();
|
.onChanged();
|
||||||
|
|
||||||
|
@ -116,36 +157,47 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterStep instruction = stages.get(row);
|
FilterStep step = stages.get(row);
|
||||||
ColorEffects def = instruction.instruction;
|
ColorEffects def = step.filter;
|
||||||
def.background.draw(matrixStack, guiLeft, guiTop + 14 + yOffset);
|
def.background.draw(matrixStack, guiLeft, guiTop + 14 + yOffset);
|
||||||
|
|
||||||
label(matrixStack, 36, yOffset - 3, Lang.translate(def.translationKey));
|
if (def != ColorEffects.END)
|
||||||
|
label(matrixStack, 36, yOffset - 3, Lang.translate(def.translationKey));
|
||||||
if (def.hasParameter) {
|
if (def.hasParameter) {
|
||||||
String text = instruction.value + " %";
|
String text = step.filter.formatValue(step.value);
|
||||||
int stringWidth = textRenderer.getStringWidth(text);
|
int stringWidth = textRenderer.getStringWidth(text);
|
||||||
label(matrixStack, 118 + (12 - stringWidth / 2), yOffset - 3, new StringTextComponent(text));
|
label(matrixStack, 118 + (12 - stringWidth / 2), yOffset - 3, new StringTextComponent(text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderScroll(matrixStack, radius, 2f);
|
||||||
|
renderScroll(matrixStack, density, 100f);
|
||||||
|
renderScroll(matrixStack, feather, 4f);
|
||||||
|
renderScroll(matrixStack, fade, 10f);
|
||||||
|
|
||||||
textRenderer.drawWithShadow(matrixStack, title, guiLeft - 3 + (background.width - textRenderer.getWidth(title)) / 2, guiTop + 3,
|
textRenderer.drawWithShadow(matrixStack, title, guiLeft - 3 + (background.width - textRenderer.getWidth(title)) / 2, guiTop + 3,
|
||||||
0xffffff);
|
0xffffff);
|
||||||
|
|
||||||
GuiGameElement.of(renderedItem)
|
GuiGameElement.of(renderedItem)
|
||||||
.at(guiLeft + background.width + 10, guiTop + 100, -150)
|
.at(guiLeft + background.width + 10, guiTop + 140, -150)
|
||||||
.scale(5)
|
.scale(5)
|
||||||
.render(matrixStack);
|
.render(matrixStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderScroll(MatrixStack matrixStack, ScrollInput input, float divisor) {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
private void label(MatrixStack matrixStack, int x, int y, ITextComponent text) {
|
private void label(MatrixStack matrixStack, int x, int y, ITextComponent text) {
|
||||||
textRenderer.drawWithShadow(matrixStack, text, guiLeft + x, guiTop + 26 + y, 0xFFFFEE);
|
textRenderer.drawWithShadow(matrixStack, text, guiLeft + x, guiTop + 26 + y, 0xFFFFEE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendPacket() {
|
public void sendPacket() {
|
||||||
// ListNBT serialized = Instruction.serializeAll(stages);
|
|
||||||
// if (serialized.equals(compareTag))
|
|
||||||
// return;
|
|
||||||
// AllPackets.channel.sendToServer(new ConfigureSequencedGearshiftPacket(pos, serialized));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -155,7 +207,7 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen {
|
||||||
|
|
||||||
private void instructionUpdated(int index, int state) {
|
private void instructionUpdated(int index, int state) {
|
||||||
ColorEffects newValue = ColorEffects.values()[state];
|
ColorEffects newValue = ColorEffects.values()[state];
|
||||||
stages.get(index).instruction = newValue;
|
stages.get(index).filter = newValue;
|
||||||
stages.get(index).value = 100;
|
stages.get(index).value = 100;
|
||||||
updateParamsOfRow(index);
|
updateParamsOfRow(index);
|
||||||
if (newValue == ColorEffects.END) {
|
if (newValue == ColorEffects.END) {
|
||||||
|
|
|
@ -2,14 +2,64 @@ package com.simibubi.create.content.curiosities.projector;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.effects.SphereFilterProgram;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
public class ChromaticProjectorTileEntity extends TileEntity {
|
public class ChromaticProjectorTileEntity extends TileEntity implements IInstanceRendered {
|
||||||
|
|
||||||
Vector<FilterStep> stages = FilterStep.createDefault();
|
Vector<FilterStep> stages = FilterStep.createDefault();
|
||||||
|
|
||||||
|
float radius = 10f;
|
||||||
|
float density = 1f;
|
||||||
|
float feather = 3;
|
||||||
|
float fade = 1.3f;
|
||||||
|
boolean blend = true;
|
||||||
|
|
||||||
public ChromaticProjectorTileEntity(TileEntityType<?> te) {
|
public ChromaticProjectorTileEntity(TileEntityType<?> te) {
|
||||||
super(te);
|
super(te);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SphereFilterProgram.FilterSphere makeFilter() {
|
||||||
|
Matrix4f filter = FilterStep.fold(stages);
|
||||||
|
|
||||||
|
BlockPos pos = getPos();
|
||||||
|
return new SphereFilterProgram.FilterSphere()
|
||||||
|
.setFilter(filter)
|
||||||
|
.setCenter(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5)
|
||||||
|
.setRadius(radius)
|
||||||
|
.setDensity(density)
|
||||||
|
.setFeather(feather)
|
||||||
|
.setBlendOver(false)
|
||||||
|
.setFade(fade);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChromaticProjectorTileEntity setRadius(int radius) {
|
||||||
|
this.radius = radius / 2f;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChromaticProjectorTileEntity setDensity(int density) {
|
||||||
|
this.density = density / 100f;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChromaticProjectorTileEntity setFeather(int feather) {
|
||||||
|
this.feather = feather / 4f;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChromaticProjectorTileEntity setFade(int fade) {
|
||||||
|
this.fade = feather / 10f;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChromaticProjectorTileEntity setBlend(boolean blend) {
|
||||||
|
this.blend = blend;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,9 @@ public enum ColorEffects {
|
||||||
INVERT(ColorMatrices::invert),
|
INVERT(ColorMatrices::invert),
|
||||||
SEPIA(ColorMatrices::sepia),
|
SEPIA(ColorMatrices::sepia),
|
||||||
GRAYSCALE(ColorMatrices::grayscale),
|
GRAYSCALE(ColorMatrices::grayscale),
|
||||||
SATURATE(ColorMatrices::saturate),
|
DARKEN(ColorMatrices::darken),
|
||||||
HUE_SHIFT(ColorMatrices::hueShift),
|
SATURATE(ColorMatrices::saturate, 0, 200),
|
||||||
|
HUE_SHIFT(ColorMatrices::hueShift, 0, 360, 1f),
|
||||||
END(ColorMatrices::identity, AllGuiTextures.PROJECTOR_END),
|
END(ColorMatrices::identity, AllGuiTextures.PROJECTOR_END),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
@ -26,6 +27,10 @@ public enum ColorEffects {
|
||||||
String translationKey;
|
String translationKey;
|
||||||
AllGuiTextures background;
|
AllGuiTextures background;
|
||||||
|
|
||||||
|
int minValue = 0;
|
||||||
|
int maxValue = 100;
|
||||||
|
float divisor = 100f;
|
||||||
|
|
||||||
ColorEffects(Supplier<Matrix4f> filter, AllGuiTextures background) {
|
ColorEffects(Supplier<Matrix4f> filter, AllGuiTextures background) {
|
||||||
this($ -> filter.get(), false, background);
|
this($ -> filter.get(), false, background);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +40,18 @@ public enum ColorEffects {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorEffects(FilterFactory filter) {
|
ColorEffects(FilterFactory filter) {
|
||||||
|
this(filter, 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorEffects(FilterFactory filter, int minValue, int maxValue) {
|
||||||
|
this(filter, minValue, maxValue, 100f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorEffects(FilterFactory filter, int minValue, int maxValue, float divisor) {
|
||||||
this(filter, true, AllGuiTextures.PROJECTOR_FILTER_STRENGTH);
|
this(filter, true, AllGuiTextures.PROJECTOR_FILTER_STRENGTH);
|
||||||
|
this.minValue = minValue;
|
||||||
|
this.maxValue = maxValue;
|
||||||
|
this.divisor = divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorEffects(FilterFactory filter, boolean hasParameter, AllGuiTextures background) {
|
ColorEffects(FilterFactory filter, boolean hasParameter, AllGuiTextures background) {
|
||||||
|
@ -45,6 +61,12 @@ public enum ColorEffects {
|
||||||
translationKey = "gui.chromatic_projector.filter." + Lang.asId(name());
|
translationKey = "gui.chromatic_projector.filter." + Lang.asId(name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String formatValue(int value) {
|
||||||
|
if (this == HUE_SHIFT)
|
||||||
|
return value + Lang.translate("generic.unit.degrees").getString();
|
||||||
|
return "" + value;
|
||||||
|
}
|
||||||
|
|
||||||
static List<ITextComponent> getOptions() {
|
static List<ITextComponent> getOptions() {
|
||||||
List<ITextComponent> options = new ArrayList<>();
|
List<ITextComponent> options = new ArrayList<>();
|
||||||
for (ColorEffects entry : values())
|
for (ColorEffects entry : values())
|
||||||
|
|
|
@ -1,21 +1,44 @@
|
||||||
package com.simibubi.create.content.curiosities.projector;
|
package com.simibubi.create.content.curiosities.projector;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.effects.ColorMatrices;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
public class FilterStep {
|
public class FilterStep {
|
||||||
|
|
||||||
ColorEffects instruction;
|
ColorEffects filter;
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
public FilterStep(ColorEffects instruction) {
|
public FilterStep(ColorEffects filter) {
|
||||||
this.instruction = instruction;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilterStep(ColorEffects instruction, int value) {
|
public FilterStep(ColorEffects filter, int value) {
|
||||||
this.instruction = instruction;
|
this.filter = filter;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Matrix4f createFilter() {
|
||||||
|
return filter.filter.create(value / filter.divisor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Matrix4f fold(Vector<FilterStep> filters) {
|
||||||
|
Iterator<FilterStep> stepIterator = filters.stream().filter(it -> it != null && it.filter != ColorEffects.END).iterator();
|
||||||
|
|
||||||
|
if (stepIterator.hasNext()) {
|
||||||
|
Matrix4f accum = stepIterator.next().createFilter();
|
||||||
|
|
||||||
|
stepIterator.forEachRemaining(filterStep -> accum.multiply(filterStep.createFilter()));
|
||||||
|
|
||||||
|
return accum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ColorMatrices.identity();
|
||||||
|
}
|
||||||
|
|
||||||
public static Vector<FilterStep> createDefault() {
|
public static Vector<FilterStep> createDefault() {
|
||||||
Vector<FilterStep> instructions = new Vector<>(ChromaticProjectorScreen.MAX_STEPS);
|
Vector<FilterStep> instructions = new Vector<>(ChromaticProjectorScreen.MAX_STEPS);
|
||||||
instructions.add(new FilterStep(ColorEffects.SEPIA, 100));
|
instructions.add(new FilterStep(ColorEffects.SEPIA, 100));
|
||||||
|
|
|
@ -92,6 +92,16 @@ public class ColorMatrices {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
public static Matrix4f identity() {
|
public static Matrix4f identity() {
|
||||||
Matrix4f mat = new Matrix4f();
|
Matrix4f mat = new Matrix4f();
|
||||||
mat.loadIdentity();
|
mat.loadIdentity();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.simibubi.create.foundation.render.backend.effects;
|
package com.simibubi.create.foundation.render.backend.effects;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.lwjgl.opengl.GL15;
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
|
@ -14,6 +16,7 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
|
||||||
import net.minecraft.client.MainWindow;
|
import net.minecraft.client.MainWindow;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
import net.minecraft.client.shader.Framebuffer;
|
import net.minecraft.client.shader.Framebuffer;
|
||||||
import net.minecraft.client.shader.FramebufferConstants;
|
import net.minecraft.client.shader.FramebufferConstants;
|
||||||
|
@ -48,7 +51,11 @@ public class EffectsHandler {
|
||||||
|
|
||||||
private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER);
|
private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
private final ArrayList<SphereFilterProgram.FilterSphere> spheres;
|
||||||
|
|
||||||
public EffectsHandler() {
|
public EffectsHandler() {
|
||||||
|
spheres = new ArrayList<>();
|
||||||
|
|
||||||
Framebuffer render = Minecraft.getInstance().getFramebuffer();
|
Framebuffer render = Minecraft.getInstance().getFramebuffer();
|
||||||
framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC);
|
framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC);
|
||||||
|
|
||||||
|
@ -64,21 +71,17 @@ public class EffectsHandler {
|
||||||
|
|
||||||
vao.unbind();
|
vao.unbind();
|
||||||
vbo.unbind();
|
vbo.unbind();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepFramebufferSize() {
|
public void addSphere(SphereFilterProgram.FilterSphere sphere) {
|
||||||
MainWindow window = Minecraft.getInstance().getWindow();
|
this.spheres.add(sphere);
|
||||||
if (framebuffer.framebufferWidth != window.getFramebufferWidth()
|
|
||||||
|| framebuffer.framebufferHeight != window.getFramebufferHeight()) {
|
|
||||||
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(),
|
|
||||||
Minecraft.IS_RUNNING_ON_MAC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(Matrix4f view) {
|
public void render(Matrix4f view) {
|
||||||
// if (true) {
|
if (spheres.size() == 0) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
GL20.glEnable(GL20.GL_DEPTH_TEST);
|
GL20.glEnable(GL20.GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
@ -98,7 +101,8 @@ public class EffectsHandler {
|
||||||
program.bindDepthTexture(mainBuffer.getDepthAttachment());
|
program.bindDepthTexture(mainBuffer.getDepthAttachment());
|
||||||
|
|
||||||
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
||||||
Matrix4f projection = gameRenderer.getBasicProjectionMatrix(gameRenderer.getActiveRenderInfo(), AnimationTickHolder.getPartialTicks(), true);
|
ActiveRenderInfo activeRenderInfo = gameRenderer.getActiveRenderInfo();
|
||||||
|
Matrix4f projection = gameRenderer.getBasicProjectionMatrix(activeRenderInfo, AnimationTickHolder.getPartialTicks(), true);
|
||||||
projection.a33 = 1;
|
projection.a33 = 1;
|
||||||
projection.invert();
|
projection.invert();
|
||||||
program.bindInverseProjection(projection);
|
program.bindInverseProjection(projection);
|
||||||
|
@ -107,76 +111,17 @@ public class EffectsHandler {
|
||||||
inverseView.invert();
|
inverseView.invert();
|
||||||
program.bindInverseView(inverseView);
|
program.bindInverseView(inverseView);
|
||||||
|
|
||||||
Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView();
|
Vector3d cameraPos = activeRenderInfo.getProjectedView();
|
||||||
|
|
||||||
program.setCameraPos(cameraPos.inverse());
|
program.setCameraPos(cameraPos.inverse());
|
||||||
|
|
||||||
// int n = 64;
|
for (SphereFilterProgram.FilterSphere sphere : spheres) {
|
||||||
// double rad = 15;
|
sphere.center = sphere.center.subtract(cameraPos);
|
||||||
// for (int i = 0; i < n; i++) {
|
}
|
||||||
// double angle = ((double) i) / n * Math.PI * 2;
|
|
||||||
// program.addSphere(new SphereFilterProgram.FilterSphere()
|
|
||||||
// .setCenter(new Vector3d(852, 77, -204).subtract(cameraPos).add(Math.sin(angle) * rad, 0, Math.cos(angle) * rad))
|
|
||||||
// .setRadius(15)
|
|
||||||
// .setFeather(3f)
|
|
||||||
// .setFade(1f)
|
|
||||||
// .setDensity(0.5f)
|
|
||||||
// .setFilter(ColorMatrices.hueShiftRGB((float) i / n * 360 + i / 2f)));
|
|
||||||
// }
|
|
||||||
|
|
||||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
spheres.sort((o1, o2) -> (int) Math.signum(o2.center.length() - o1.center.length()));
|
||||||
.setCenter(new Vector3d(865.5, 79, -240.5).subtract(cameraPos))
|
|
||||||
.setRadius(10f)
|
|
||||||
.setFeather(3f)
|
|
||||||
.setFade(1.8f)
|
|
||||||
.setDensity(1.3f)
|
|
||||||
.setFilter(ColorMatrices.grayscale()));
|
|
||||||
|
|
||||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
program.uploadFilters(spheres);
|
||||||
.setCenter(new Vector3d(852.5, 70, -203.5).subtract(cameraPos))
|
|
||||||
.setRadius(20f)
|
|
||||||
.setFeather(3f)
|
|
||||||
.setFade(1f)
|
|
||||||
.setDensity(1.3f)
|
|
||||||
.setFilter(ColorMatrices.sepia(1f)));
|
|
||||||
|
|
||||||
// Matrix4f test = ColorMatrices.sepia(1f);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// test.multiply(ColorMatrices.invert());
|
|
||||||
//
|
|
||||||
// Matrix4f darken = new Matrix4f();
|
|
||||||
// darken.loadIdentity();
|
|
||||||
// darken.multiply(0.7f);
|
|
||||||
// darken.a03 = 0.7f;
|
|
||||||
// darken.a13 = 0.7f;
|
|
||||||
// darken.a23 = 0.7f;
|
|
||||||
// test.multiply(darken);
|
|
||||||
|
|
||||||
Matrix4f test = ColorMatrices.saturate(2f);
|
|
||||||
|
|
||||||
test.multiply(ColorMatrices.hueShift(120f));
|
|
||||||
|
|
||||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
|
||||||
.setCenter(new Vector3d(858.5, 88, -259.5).subtract(cameraPos))
|
|
||||||
.setRadius(10f)
|
|
||||||
.setFeather(3f)
|
|
||||||
.setFade(1.8f)
|
|
||||||
.setDensity(0.5f)
|
|
||||||
.setStrength(1f)
|
|
||||||
.setFilter(test));
|
|
||||||
|
|
||||||
|
|
||||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
|
||||||
.setCenter(new Vector3d(2310, 60, -954).subtract(cameraPos))
|
|
||||||
.setRadius(8f)
|
|
||||||
.setFeather(3f)
|
|
||||||
.setFade(0.8f)
|
|
||||||
.setDensity(1.3f)
|
|
||||||
.setStrength(1f)
|
|
||||||
.setFilter(ColorMatrices.grayscale()));
|
|
||||||
|
|
||||||
program.uploadFilters();
|
|
||||||
|
|
||||||
program.setFarPlane(getFarPlane());
|
program.setFarPlane(getFarPlane());
|
||||||
program.setNearPlane(getNearPlane());
|
program.setNearPlane(getNearPlane());
|
||||||
|
@ -189,8 +134,8 @@ public class EffectsHandler {
|
||||||
program.bindDepthTexture(0);
|
program.bindDepthTexture(0);
|
||||||
GL20.glActiveTexture(GL20.GL_TEXTURE0);
|
GL20.glActiveTexture(GL20.GL_TEXTURE0);
|
||||||
|
|
||||||
program.clear();
|
|
||||||
program.unbind();
|
program.unbind();
|
||||||
|
spheres.clear();
|
||||||
|
|
||||||
Backend.compat.fbo.bindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject);
|
Backend.compat.fbo.bindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject);
|
||||||
Backend.compat.fbo.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject);
|
Backend.compat.fbo.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject);
|
||||||
|
@ -204,4 +149,13 @@ public class EffectsHandler {
|
||||||
vao.delete();
|
vao.delete();
|
||||||
vbo.delete();
|
vbo.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepFramebufferSize() {
|
||||||
|
MainWindow window = Minecraft.getInstance().getWindow();
|
||||||
|
if (framebuffer.framebufferWidth != window.getFramebufferWidth()
|
||||||
|
|| framebuffer.framebufferHeight != window.getFramebufferHeight()) {
|
||||||
|
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(),
|
||||||
|
Minecraft.IS_RUNNING_ON_MAC);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.simibubi.create.foundation.render.backend.effects;
|
package com.simibubi.create.foundation.render.backend.effects;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -29,8 +28,6 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
|
|
||||||
public final GlBuffer effectsUBO;
|
public final GlBuffer effectsUBO;
|
||||||
|
|
||||||
protected final ArrayList<FilterSphere> filters = new ArrayList<>(16);
|
|
||||||
|
|
||||||
protected final int uniformBlock;
|
protected final int uniformBlock;
|
||||||
|
|
||||||
protected final int uDepth;
|
protected final int uDepth;
|
||||||
|
@ -82,17 +79,15 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
GL20.glUniform3f(uCameraPos, (float) pos.x, (float) pos.y, (float) pos.z);
|
GL20.glUniform3f(uCameraPos, (float) pos.x, (float) pos.y, (float) pos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void uploadFilters(ArrayList<FilterSphere> filters) {
|
||||||
filters.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSphere(FilterSphere filterSphere) {
|
|
||||||
filters.add(filterSphere);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void uploadFilters() {
|
|
||||||
effectsUBO.bind(GL20.GL_ARRAY_BUFFER);
|
effectsUBO.bind(GL20.GL_ARRAY_BUFFER);
|
||||||
effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, this::uploadUBO);
|
effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, buf -> {
|
||||||
|
buf.putInt(filters.size());
|
||||||
|
buf.position(16);
|
||||||
|
FloatBuffer floatBuffer = buf.asFloatBuffer();
|
||||||
|
|
||||||
|
filters.forEach(it -> it.write(floatBuffer));
|
||||||
|
});
|
||||||
effectsUBO.unbind(GL20.GL_ARRAY_BUFFER);
|
effectsUBO.unbind(GL20.GL_ARRAY_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,14 +109,6 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
|
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadUBO(ByteBuffer buf) {
|
|
||||||
buf.putInt(filters.size());
|
|
||||||
buf.position(16);
|
|
||||||
FloatBuffer floatBuffer = buf.asFloatBuffer();
|
|
||||||
|
|
||||||
filters.forEach(it -> it.write(floatBuffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FilterSphere {
|
public static class FilterSphere {
|
||||||
public Vector3d center;
|
public Vector3d center;
|
||||||
public float radius;
|
public float radius;
|
||||||
|
@ -129,6 +116,7 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
public float fade;
|
public float fade;
|
||||||
public float density = 2;
|
public float density = 2;
|
||||||
public float strength = 1;
|
public float strength = 1;
|
||||||
|
public boolean blendOver = false;
|
||||||
|
|
||||||
public Matrix4f filter;
|
public Matrix4f filter;
|
||||||
|
|
||||||
|
@ -137,6 +125,11 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
return this;
|
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) {
|
public FilterSphere setRadius(float radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
return this;
|
return this;
|
||||||
|
@ -167,6 +160,11 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FilterSphere setBlendOver(boolean blendOver) {
|
||||||
|
this.blendOver = blendOver;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public void write(FloatBuffer buf) {
|
public void write(FloatBuffer buf) {
|
||||||
buf.put(new float[]{
|
buf.put(new float[]{
|
||||||
(float) center.x,
|
(float) center.x,
|
||||||
|
@ -176,7 +174,11 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
feather,
|
feather,
|
||||||
fade,
|
fade,
|
||||||
density,
|
density,
|
||||||
strength,
|
blendOver ? 1f : 0f,
|
||||||
|
1f,
|
||||||
|
1f,
|
||||||
|
0f,
|
||||||
|
0f,
|
||||||
});
|
});
|
||||||
|
|
||||||
buf.put(RenderUtil.writeMatrix(filter));
|
buf.put(RenderUtil.writeMatrix(filter));
|
||||||
|
|
|
@ -16,34 +16,11 @@ uniform vec3 uCameraPos;
|
||||||
|
|
||||||
struct SphereFilter {
|
struct SphereFilter {
|
||||||
vec4 sphere;// <vec3 position, float radius>
|
vec4 sphere;// <vec3 position, float radius>
|
||||||
vec4 data;// <float feather, float fade, float density, float strength>
|
vec4 d1;// <float feather, float fade, float density, float blend mode>
|
||||||
|
vec4 d2;// <float surfaceStrength, float bubbleStrength>
|
||||||
mat4 colorOp;
|
mat4 colorOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
vec3 getPosition(SphereFilter f) {
|
|
||||||
return f.sphere.xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getRadius(SphereFilter f) {
|
|
||||||
return f.sphere.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getFeather(SphereFilter f) {
|
|
||||||
return f.data.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getFade(SphereFilter f) {
|
|
||||||
return f.data.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getDensity(SphereFilter f) {
|
|
||||||
return f.data.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getStrength(SphereFilter f) {
|
|
||||||
return f.data.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define N 256
|
#define N 256
|
||||||
layout (std140) uniform Filters {
|
layout (std140) uniform Filters {
|
||||||
int uCount;
|
int uCount;
|
||||||
|
@ -113,18 +90,22 @@ float bubbleFilterStrength(vec3 worldDir, float depth, vec4 sphere, float feathe
|
||||||
return clamp(strength, 0., 1.);// * boo;
|
return clamp(strength, 0., 1.);// * boo;
|
||||||
}
|
}
|
||||||
|
|
||||||
float filterStrength(vec3 worldDir, float depth, vec4 sphere, vec4 data) {
|
float filterStrength(vec3 worldDir, float depth, inout SphereFilter f) {
|
||||||
|
vec4 sphere = f.sphere;
|
||||||
|
vec4 data = f.d1;
|
||||||
float feather = data.x;
|
float feather = data.x;
|
||||||
|
|
||||||
float strength = 0.;
|
float strength = 0.;
|
||||||
// transition effect
|
// transition effect
|
||||||
float transitionRadius = sphere.w + feather;
|
float transitionRadius = sphere.w + feather;
|
||||||
strength += 1. - smoothstep(transitionRadius, transitionRadius + data.y, length(sphere.xyz));
|
strength += 1. - smoothstep(transitionRadius, transitionRadius + data.y, length(sphere.xyz));
|
||||||
// surface effect
|
|
||||||
strength += surfaceFilterStrength(worldDir * depth, sphere, feather);
|
|
||||||
// bubble effect
|
// bubble effect
|
||||||
strength += bubbleFilterStrength(worldDir, depth, sphere, feather, data.z);
|
strength += bubbleFilterStrength(worldDir, depth, sphere, feather, data.z);
|
||||||
|
|
||||||
|
strength *= f.d2.y;
|
||||||
|
// surface effect
|
||||||
|
strength += surfaceFilterStrength(worldDir * depth, sphere, feather) * f.d2.x;
|
||||||
|
|
||||||
return strength;
|
return strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,16 +118,16 @@ vec3 applyFilters(vec3 worldDir, float depth, vec3 diffuse) {
|
||||||
for (int i = 0; i < uCount; i++) {
|
for (int i = 0; i < uCount; i++) {
|
||||||
SphereFilter s = uSpheres[i];
|
SphereFilter s = uSpheres[i];
|
||||||
|
|
||||||
float strength = filterStrength(worldDir, depth, s.sphere, s.data);
|
float strength = filterStrength(worldDir, depth, s);
|
||||||
|
|
||||||
if (strength > 0) {
|
if (strength > 0) {
|
||||||
const float fcon = 0.;
|
const float fcon = 0.;
|
||||||
|
|
||||||
vec3 formatted = mix(diffuse, hsv, fcon);
|
//vec3 formatted = mix(diffuse, hsv, fcon);
|
||||||
vec3 filtered = filterColor(s.colorOp, formatted);
|
vec3 filtered = filterColor(s.colorOp, mix(diffuse, accum, s.d1.w));
|
||||||
filtered = mix(filtered, hsv2rgbWrapped(filtered), fcon);
|
//filtered = mix(filtered, hsv2rgbWrapped(filtered), fcon);
|
||||||
|
|
||||||
float mixing = clamp(strength * s.data.w, 0., 1.);
|
float mixing = clamp(strength, 0., 1.);
|
||||||
accum = mix(accum, filtered, mixing);
|
accum = mix(accum, filtered, mixing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#version 140
|
#version 140
|
||||||
|
|
||||||
// scaling constants
|
// scaling constants
|
||||||
#define SXY 1.7282818// e - 0.99, this works too well
|
// e - 0.99, this works well, no idea why
|
||||||
#define SZ 1.905// who knows, but it works
|
#define SXY 1.7282818
|
||||||
|
// 1.90 -> highp close, mediump far
|
||||||
|
// 1.91 -> mediump close, highp far
|
||||||
|
#define SZ 1.905
|
||||||
|
|
||||||
in vec4 aVertex;// <vec2 position, vec2 texCoords>
|
in vec4 aVertex;// <vec2 position, vec2 texCoords>
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
Loading…
Reference in a new issue