Skip to content

Commit

Permalink
Merge branch 'trunk' into shadows
Browse files Browse the repository at this point in the history
# Conflicts:
#	gradle.properties
  • Loading branch information
coderbot16 committed May 25, 2021
2 parents 9bfaaf0 + efaee35 commit 632c895
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 18 deletions.
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,45 @@ That being said... **If you want to test out compiled alpha builds of the mod, p

Iris is an experiment in loading shaderpacks on Fabric. After making minimal progress trying to hack karyonix's ShadersMod codebase on to newer versions, I finally asked: *How hard is it to load a basic shaderpack on Fabric from scratch?* As it turns out, nowhere near as hard as I expected! Thus, Iris was born.

Iris is completely free and open source, and you are free to read, distribute, and modify the code as long as you abide by the (fairly reasonable) terms of the [GNU LGPLv3 license](https://github.com/IrisShaders/Iris/blob/master/LICENSE). This should be a quite nice change of pace from the closed-source nature of OptiFine.
Iris is completely free and open source, and you are free to read, distribute, and modify the code as long as you abide by the (fairly reasonable) terms of the [GNU LGPLv3 license](https://github.com/IrisShaders/Iris/blob/master/LICENSE). This should be a quite nice change of pace from the closed-source nature of OptiFine. That being said, I will ask that you talk to me before publicly posting compiled builds of the mod currently. This is out of necessity - Iris just is not yet complete enough to become widely used right now, and I don't have a support team capable of handling all potential user support requests.

For the most part, I am creating Iris in order to have fun and get more experience in rendering. However, I am also frustrated by the constant incompatibilities and issues that players have reported when using OptiFine, and I also know that I am far from the only person with this experience. By developing a compatible and open source shaders mod, I hope to work towards a community where players and developers no longer have to worry about OptiFine incompatibilities.


## Current State

Iris has been progressing quite rapidly recently. The following shaderpacks mostly work, though with a few bugs of course:

* [XorDev's shaderpacks](https://github.com/XorDev/Minecraft-Shaderpacks), aside from Ominous
* [Sildur's Vibrant Shaders](https://sildurs-shaders.github.io/)
* [Sildur's Enhanced Default](https://sildurs-shaders.github.io/)
* Enchantment glints are broken
* Fog is broken
* [Complementary Shaders](https://www.curseforge.com/minecraft/customization/complementary-shaders)
* Reflections are all black, weather doesn't look quite right.
* Underwater and nether fog is broken
* [BSL Shaders](https://www.bitslablab.com/bslshaders/)
* Reflections currently do not work at all, and rain doesn't show up.
* [AstraLex Shaders](https://www.curseforge.com/minecraft/customization/astralex-shader-bsl-edit)
* Water looks weird in general, though reflections do work. Weather doesn't work, rain does not show up and the sky does not darken.
* [SEUS v11](https://sonicether.com/shaders/download/v11-0/) from 2016
* General issues with weather
* You need to disable clouds manually
* Note that SEUS v11 does not work on some platforms and might fail to compile.
* [Skylec Shader](https://www.curseforge.com/minecraft/customization/skylec-shader) - a very lightweight shaderpack that pulls off some neat effects
* Underwater is broken
* Weather is broken

Other shaderpacks aren't supported.

A major feature missing from the public source code is shadow mapping. Many packs rely on shadow mapping quite heavily, and its absence causes a variety of issues:

* Nothing casts a shadow (obviously)
* You might see the sun glowing through solid blocks and similar issues on shader packs making use of volumetric lighting (like BSL & Sildurs Vibrant Shaders Extreme-VL)
* The sides of blocks facing the sun will be very bright while the sides facing away will be very dark, creating a weird effect.

---

* Sildur's Vibrant Shaders and XorDev's shaderpacks work for the most part under Iris, and have been the focus of my development. However, most other shaderpacks either have severe rendering issues, or do not work at all. My current focus is to get Sildur's Vibrant Shaders and XorDev's shaderpacks to the point where they are 100% working before shifting focus to other shaderpacks. As I fix issues in these shaderpacks, other shaderpacks will very likely begin to work properly as well.
* I am working with JellySquid to make Sodium and Iris compatible. There is a proof-of-concept for Iris/Sodium compatibility available on a [custom fork of Sodium](https://github.com/IrisShaders/sodium-fabric). While this proof of concept is being used as a reference for compatibility work, it will likely be replaced with more solid and stable code in the future.

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ minecraft_version=1.16.5
yarn_mappings=1.16.5+build.5
loader_version=0.11.3
# Mod Properties
mod_version=0.4.0-shadow1.2
mod_version=0.4.0+shadow2
maven_group=net.coderbot.iris
archives_base_name=iris

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/net/coderbot/iris/Iris.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,19 @@ private static void loadInternalShaderpack() {

public static boolean isValidShaderpack(Path pack) {
if (Files.isDirectory(pack)) {
// Sometimes the shaderpack directory itself can be
// identified as a shader pack due to it containing
// folders which contain "shaders" folders, this is
// necessary to check against that
if (pack.equals(SHADERPACKS_DIRECTORY)) {
return false;
}
try {
return Files.walk(pack)
.filter(Files::isDirectory)
// Prevent a pack simply named "shaders" from being
// identified as a valid pack
.filter(path -> !path.equals(pack))
.anyMatch(path -> path.endsWith("shaders"));
} catch (IOException ignored) {
// ignored, not a valid shader pack.
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/net/coderbot/iris/config/IrisConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,6 @@ public void setShaderPackName(String name) {
} else {
this.shaderPackName = name;
}

try {
save();
} catch (IOException e) {
Iris.logger.error("Error saving configuration file, unable to set shader pack name");
Iris.logger.catching(e);
}
}

/**
Expand All @@ -94,6 +87,13 @@ public boolean areShadersEnabled() {
return enableShaders;
}

/**
* Sets whether shaders should be used for rendering.
*/
public void setShadersEnabled(boolean enabled) {
this.enableShaders = enabled;
}

/**
* loads the config file and then populates the string, int, and boolean entries with the parsed entries
*
Expand Down
85 changes: 85 additions & 0 deletions src/main/java/net/coderbot/iris/gui/GuiUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package net.coderbot.iris.gui;

import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;

/**
* Class serving as abstraction and
* centralization for common GUI
* rendering/other code calls.
*
* Helps allow for easier portability
* to Minecraft 1.17 by abstracting
* some code that will be changed.
*/
public final class GuiUtil {
private static final Identifier IRIS_WIDGETS_TEX = new Identifier("iris", "textures/gui/widgets.png");

private GuiUtil() {}

private static MinecraftClient client() {
return MinecraftClient.getInstance();
}

/**
* Binds Iris's widgets texture to be
* used for succeeding draw calls.
*/
public static void bindIrisWidgetsTexture() {
client().getTextureManager().bindTexture(IRIS_WIDGETS_TEX);
}

/**
* Draws a button. Button textures must be mapped with the
* same coordinates as those on the vanilla widgets texture.
*
* @param x X position of the left of the button
* @param y Y position of the top of the button
* @param width Width of the button, maximum 398
* @param height Height of the button, maximum 20
* @param hovered Whether the button is being hovered over with the mouse
* @param disabled Whether the button should use the "disabled" texture
*/
public static void drawButton(MatrixStack matrices, int x, int y, int width, int height, boolean hovered, boolean disabled) {
// Create variables for half of the width and height.
// Will not be exact when width and height are odd, but
// that case is handled within the draw calls.
int halfWidth = width / 2;
int halfHeight = height / 2;

// V offset for which button texture to use
int vOffset = disabled ? 46 : hovered ? 86 : 66;

// Sets RenderSystem to use solid white as the tint color for blend mode, and enables blend mode
RenderSystem.blendColor(1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.enableBlend();

// Sets RenderSystem to be able to use textures when drawing
RenderSystem.enableTexture();

// Top left section
DrawableHelper.drawTexture(matrices, x, y, 0, vOffset, halfWidth, halfHeight, 256, 256);
// Top right section
DrawableHelper.drawTexture(matrices, x + halfWidth, y, 200 - (width - halfWidth), vOffset, width - halfWidth, halfHeight, 256, 256);
// Bottom left section
DrawableHelper.drawTexture(matrices, x, y + halfHeight, 0, vOffset + (20 - (height - halfHeight)), halfWidth, height - halfHeight, 256, 256);
// Bottom right section
DrawableHelper.drawTexture(matrices, x + halfWidth, y + halfHeight, 200 - (width - halfWidth), vOffset + (20 - (height - halfHeight)), width - halfWidth, height - halfHeight, 256, 256);
}

/**
* Plays the {@code UI_BUTTON_CLICK} sound event as a
* master sound effect.
*
* Used in non-{@code ButtonWidget} UI elements upon click
* or other action.
*/
public static void playButtonClickSound() {
client().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package net.coderbot.iris.gui.element;

import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.systems.RenderSystem;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gui.GuiUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
Expand All @@ -20,7 +22,12 @@

public class ShaderPackListWidget extends IrisScreenEntryListWidget<ShaderPackListWidget.BaseEntry> {
public static final List<String> BUILTIN_PACKS = ImmutableList.of("(internal)");

private static final Text PACK_LIST_LABEL = new TranslatableText("pack.iris.list.label").formatted(Formatting.ITALIC, Formatting.GRAY);
private static final Text SHADERS_DISABLED_LABEL = new TranslatableText("options.iris.shaders.disabled");
private static final Text SHADERS_ENABLED_LABEL = new TranslatableText("options.iris.shaders.enabled");

private final EnableShadersButtonEntry enableShadersButton = new EnableShadersButtonEntry(Iris.getIrisConfig().areShadersEnabled());

public ShaderPackListWidget(MinecraftClient client, int width, int height, int top, int bottom, int left, int right) {
super(client, width, height, top, bottom, left, right, 20);
Expand All @@ -30,10 +37,10 @@ public ShaderPackListWidget(MinecraftClient client, int width, int height, int t

@Override
public int getRowWidth() {
// Allow the list widget to expand to take up most of the width of the screen, or shrink as needed.
// This is important both because shader pack names can be quite long, and it also helps if this list widget
// is side-by-side with another widget, such as a config GUI.
return width - 50;
// Temporarily set to only reach a width of up to 312 in order to fit in with
// the width of the array of buttons at the bottom of the GUI. May be changed
// in the future if this widget is made to occupy half the screen.
return Math.min(308, width - 50);
}

@Override
Expand All @@ -45,15 +52,17 @@ public void refresh() {
this.clearEntries();

try {
this.addEntry(enableShadersButton);

Path path = Iris.SHADERPACKS_DIRECTORY;
int index = -1;
int index = 0;

for (String pack : BUILTIN_PACKS) {
index++;
addEntry(index, pack);
}

Collection<Path> folders = Files.walk(path, 1).filter(Iris::isValidShaderpack).collect(Collectors.toList());
Collection<Path> folders = Files.list(path).filter(Iris::isValidShaderpack).collect(Collectors.toList());

for (Path folder : folders) {
String name = folder.getFileName().toString();
Expand Down Expand Up @@ -93,6 +102,10 @@ public void select(String name) {
}
}

public EnableShadersButtonEntry getEnableShadersButton() {
return enableShadersButton;
}

public static abstract class BaseEntry extends AlwaysSelectedEntryListWidget.Entry<BaseEntry> {
protected BaseEntry() {}
}
Expand Down Expand Up @@ -122,27 +135,34 @@ public void render(MatrixStack matrices, int index, int y, int x, int entryWidth
int color = 0xFFFFFF;
String name = packName;

boolean shadersEnabled = list.getEnableShadersButton().enabled;

if (textRenderer.getWidth(new LiteralText(name).formatted(Formatting.BOLD)) > this.list.getRowWidth() - 3) {
name = textRenderer.trimToWidth(name, this.list.getRowWidth() - 8) + "...";
}

MutableText text = new LiteralText(name);

if (this.isMouseOver(mouseX, mouseY)) {
if (shadersEnabled && this.isMouseOver(mouseX, mouseY)) {
text = text.formatted(Formatting.BOLD);
}

if (this.isSelected()) {
color = 0xFFF263;
}

if (!shadersEnabled) {
color = 0xA2A2A2;
}

drawCenteredText(matrices, textRenderer, text, (x + entryWidth / 2) - 2, y + (entryHeight - 11) / 2, color);
}

@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (!this.isSelected() && button == 0) {
if (list.getEnableShadersButton().enabled && !this.isSelected() && button == 0) {
this.list.select(this.index);

return true;
}

Expand All @@ -162,4 +182,35 @@ public void render(MatrixStack matrices, int index, int y, int x, int entryWidth
drawCenteredText(matrices, MinecraftClient.getInstance().textRenderer, label, (x + entryWidth / 2) - 2, y + (entryHeight - 11) / 2, 0xC2C2C2);
}
}

public static class EnableShadersButtonEntry extends BaseEntry {
public boolean enabled;

public EnableShadersButtonEntry(boolean enabled) {
this.enabled = enabled;
}

@Override
public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
GuiUtil.bindIrisWidgetsTexture();

GuiUtil.drawButton(matrices, x - 2, y - 3, entryWidth, 18, hovered, false);

Text label = this.enabled ? SHADERS_ENABLED_LABEL : SHADERS_DISABLED_LABEL;

drawCenteredText(matrices, MinecraftClient.getInstance().textRenderer, label, (x + entryWidth / 2) - 2, y + (entryHeight - 11) / 2, 0xFFFFFF);
}

@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 0) {
this.enabled = !this.enabled;
GuiUtil.playButtonClickSound();

return true;
}

return super.mouseClicked(mouseX, mouseY, button);
}
}
}
Loading

0 comments on commit 632c895

Please sign in to comment.