Instant legacy code

- Respect fog shape and type
  - Add uFogShape uniform
  - Add macro for current FogType
- Respect dimension constant ambient light when calculating diffuse
  - Add uConstantAmbientLight uniform
  - Redirect diffuse calculation to FLWDiffuse
  - Do not automatically include diffuse.glsl
- Fill CoreShaderInfoMap with info for vanilla and Forge core shaders
- Use try-with-resources when querying ResourceManager
- Move WorldProgram uniform uploading from bind to uploadUniforms
- Use correct layer when rendering bells (cutout -> solid)
- Update Starlight
This commit is contained in:
PepperCode1 2022-05-13 23:58:24 -07:00
parent 958188fc77
commit 4c7b035f5d
27 changed files with 319 additions and 152 deletions

View file

@ -36,7 +36,6 @@ println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getPro
minecraft {
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
runs {
client {
workingDirectory project.file('run')
@ -107,7 +106,7 @@ repositories {
dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
compileOnly fg.deobf("curse.maven:starlight-526854:3599856")
compileOnly fg.deobf("curse.maven:starlight-526854:3706539")
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings

View file

@ -5,7 +5,7 @@ org.gradle.daemon = false
mod_version = 0.7.0
mc_update_version = 1.18
minecraft_version = 1.18.2
forge_version = 40.0.15
forge_version = 40.1.0
# build dependency versions
forgegradle_version = 5.1.+

View file

@ -96,9 +96,7 @@ public class Loader implements ResourceManagerReloadListener {
Collection<ResourceLocation> programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json"));
for (ResourceLocation location : programSpecs) {
try {
Resource file = manager.getResource(location);
try (Resource file = manager.getResource(location)) {
String s = StringUtil.readToString(file.getInputStream());
ResourceLocation specName = ResourceUtil.trim(location, PROGRAM_DIR, ".json");

View file

@ -21,8 +21,8 @@ public class GlShader extends GlObject {
GlCompat.safeShaderSource(handle, source);
GL20.glCompileShader(handle);
String log = GL20.glGetShaderInfoLog(handle);
// String log = GL20.glGetShaderInfoLog(handle);
//
// if (!log.isEmpty()) {
// env.printShaderInfoLog(source, log, this.name);
// }

View file

@ -16,16 +16,20 @@ import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.jozufozu.flywheel.backend.model.MeshPool;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.RenderTypeRegistry;
import com.jozufozu.flywheel.core.CoreShaderInfoMap;
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
import com.jozufozu.flywheel.core.compile.ProgramContext;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.util.Textures;
import com.jozufozu.flywheel.util.WeakHashSet;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.resources.ResourceLocation;
@ -73,10 +77,10 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
// don't want to mutate viewProjection
var vp = context.viewProjection().copy();
vp.multiply(Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ));
vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ);
for (RenderType renderType : toRender) {
render(renderType, camX, camY, camZ, vp);
render(renderType, camX, camY, camZ, vp, context.level());
}
toRender.clear();
}
@ -90,19 +94,20 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
// don't want to mutate viewProjection
var vp = context.viewProjection().copy();
vp.multiply(Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ));
vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ);
if (toRender.remove(type)) {
render(type, camX, camY, camZ, vp);
render(type, camX, camY, camZ, vp, context.level());
}
}
protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection) {
protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
vertexCount = 0;
instanceCount = 0;
type.setupRenderState();
Textures.bindActiveTextures();
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
InstancedMaterial<?> material = entry.getValue();
@ -113,7 +118,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
if (!toRender.isEmpty()) {
Instanced<? extends InstanceData> instanceType = entry.getKey();
setup(type, camX, camY, camZ, viewProjection, instanceType.getProgramSpec());
setup(instanceType.getProgramSpec(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
instanceCount += material.getInstanceCount();
vertexCount += material.getVertexCount();
@ -125,12 +130,33 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
type.clearRenderState();
}
protected P setup(RenderType layer, double camX, double camY, double camZ, Matrix4f viewProjection, ResourceLocation programSpec) {
P program = context.getProgram(ProgramContext.create(programSpec, Formats.POS_TEX_NORMAL, RenderTypeRegistry.getAlphaDiscard(layer)));
protected CoreShaderInfo getCoreShaderInfo() {
CoreShaderInfo coreShaderInfo;
ShaderInstance coreShader = RenderSystem.getShader();
if (coreShader != null) {
String coreShaderName = coreShader.getName();
coreShaderInfo = CoreShaderInfoMap.getInfo(coreShaderName);
} else {
coreShaderInfo = null;
}
if (coreShaderInfo == null) {
coreShaderInfo = CoreShaderInfo.DEFAULT;
}
return coreShaderInfo;
}
protected P setup(ResourceLocation programSpec, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
float alphaDiscard = coreShaderInfo.alphaDiscard();
if (alphaDiscard == 0) {
alphaDiscard = 0.0001f;
} else if (alphaDiscard < 0) {
alphaDiscard = 0;
}
P program = context.getProgram(ProgramContext.create(programSpec, Formats.POS_TEX_NORMAL, alphaDiscard, coreShaderInfo.fogType()));
program.bind();
program.uploadViewProjection(viewProjection);
program.uploadCameraPos(camX, camY, camZ);
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
return program;
}

View file

@ -28,7 +28,7 @@ public class Contexts {
}
public static class Names {
public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling");
public static final ResourceLocation WORLD = Flywheel.rl("context/world");
public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling");
}
}

View file

@ -0,0 +1,95 @@
package com.jozufozu.flywheel.core;
import static com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType.COLOR_FOG;
import static com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType.FADE_FOG;
import static com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType.NO_FOG;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.backend.OptifineHandler;
public class CoreShaderInfoMap {
private static final Map<String, CoreShaderInfo> MAP = new HashMap<>();
static {
registerInfo("block", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("new_entity", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("particle", new CoreShaderInfo(0.1f, false, COLOR_FOG));
registerInfo("position", new CoreShaderInfo(-1, false, COLOR_FOG));
registerInfo("position_color", new CoreShaderInfo(0, false, NO_FOG));
registerInfo("position_color_lightmap", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("position_color_tex", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("position_color_tex_lightmap", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("position_tex", new CoreShaderInfo(0, false, NO_FOG));
registerInfo("position_tex_color", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("position_tex_color_normal", new CoreShaderInfo(0.1f, false, COLOR_FOG));
registerInfo("position_tex_lightmap_color", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("rendertype_solid", new CoreShaderInfo(-1, false, COLOR_FOG));
registerInfo("rendertype_cutout_mipped", new CoreShaderInfo(OptifineHandler.isOptifineInstalled() ? 0.1f : 0.5f, false, COLOR_FOG));
registerInfo("rendertype_cutout", new CoreShaderInfo(0.1f, false, COLOR_FOG));
registerInfo("rendertype_translucent", new CoreShaderInfo(-1, false, COLOR_FOG));
registerInfo("rendertype_translucent_moving_block", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("rendertype_translucent_no_crumbling", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("rendertype_armor_cutout_no_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_solid", new CoreShaderInfo(-1, true, COLOR_FOG));
registerInfo("rendertype_entity_cutout", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_cutout_no_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_cutout_no_cull_z_offset", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_item_entity_translucent_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_translucent_cull", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_translucent", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_smooth_cutout", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_beacon_beam", new CoreShaderInfo(-1, false, COLOR_FOG));
registerInfo("rendertype_entity_decal", new CoreShaderInfo(0.1f, true, COLOR_FOG));
registerInfo("rendertype_entity_no_outline", new CoreShaderInfo(-1, true, COLOR_FOG));
registerInfo("rendertype_entity_shadow", new CoreShaderInfo(-1, false, COLOR_FOG));
// Special alpha discard
registerInfo("rendertype_entity_alpha", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("rendertype_eyes", new CoreShaderInfo(-1, false, FADE_FOG));
registerInfo("rendertype_energy_swirl", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_leash", new CoreShaderInfo(-1, false, COLOR_FOG));
registerInfo("rendertype_water_mask", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("rendertype_outline", new CoreShaderInfo(0, false, NO_FOG));
registerInfo("rendertype_armor_glint", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_armor_entity_glint", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_glint_translucent", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_glint", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_glint_direct", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_entity_glint", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_entity_glint_direct", new CoreShaderInfo(0.1f, false, FADE_FOG));
registerInfo("rendertype_text", new CoreShaderInfo(0.1f, false, COLOR_FOG));
registerInfo("rendertype_text_intensity", new CoreShaderInfo(0.1f, false, COLOR_FOG));
registerInfo("rendertype_text_see_through", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("rendertype_text_intensity_see_through", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("rendertype_lightning", new CoreShaderInfo(-1, false, FADE_FOG));
registerInfo("rendertype_tripwire", new CoreShaderInfo(0.1f, false, COLOR_FOG));
registerInfo("rendertype_end_portal", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("rendertype_end_gateway", new CoreShaderInfo(-1, false, NO_FOG));
registerInfo("rendertype_lines", new CoreShaderInfo(-1, false, COLOR_FOG));
registerInfo("rendertype_crumbling", new CoreShaderInfo(0.1f, false, NO_FOG));
registerInfo("forge:rendertype_entity_unlit_translucent", new CoreShaderInfo(0.1f, false, COLOR_FOG));
}
public static void registerInfo(String name, CoreShaderInfo info) {
MAP.put(name, info);
}
@Nullable
public static CoreShaderInfo getInfo(String name) {
return MAP.get(name);
}
public record CoreShaderInfo(float alphaDiscard, boolean appliesDiffuse, FogType fogType) {
public static final CoreShaderInfo DEFAULT = new CoreShaderInfo(-1, false, NO_FOG);
public enum FogType {
NO_FOG,
COLOR_FOG,
FADE_FOG;
}
}
}

View file

@ -1,19 +0,0 @@
package com.jozufozu.flywheel.core;
import org.jetbrains.annotations.Nullable;
import net.minecraft.client.renderer.RenderType;
public class RenderTypeRegistry {
/**
* Gets the alpha discard threshold for the given render layer.
*
* @param layer The render layer to get the alpha discard threshold for.
* @return The alpha discard threshold.
*/
public static float getAlphaDiscard(@Nullable RenderType layer) {
return layer == RenderType.cutoutMipped() ? 0.1f : 0f;
}
}

View file

@ -1,18 +1,12 @@
package com.jozufozu.flywheel.core;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
import com.jozufozu.flywheel.core.compile.FragmentTemplateData;
import com.jozufozu.flywheel.core.compile.InstancingTemplateData;
import com.jozufozu.flywheel.core.compile.OneShotTemplateData;
import com.jozufozu.flywheel.core.compile.Template;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.core.source.Resolver;
public class Templates {
public static final FileResolution DIFFUSE_FILE = Resolver.INSTANCE.get(Flywheel.rl("core/diffuse.glsl"));
public static final Template<InstancingTemplateData> INSTANCING = new Template<>(GLSLVersion.V330, InstancingTemplateData::new);
public static final Template<OneShotTemplateData> ONE_SHOT = new Template<>(GLSLVersion.V150, OneShotTemplateData::new);
public static final Template<FragmentTemplateData> FRAGMENT = new Template<>(GLSLVersion.V150, FragmentTemplateData::new);

View file

@ -4,6 +4,7 @@ import java.util.Objects;
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType;
import com.jozufozu.flywheel.core.shader.ShaderConstants;
import com.jozufozu.flywheel.core.shader.StateSnapshot;
import com.jozufozu.flywheel.core.source.FileIndexImpl;
@ -11,33 +12,31 @@ import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.core.source.SourceFile;
public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShader> {
private final Template<? extends FragmentData> template;
private final FileResolution header;
private final Template<FragmentTemplateData> fragment;
public FragmentCompiler(Template<FragmentTemplateData> fragment, FileResolution header) {
public FragmentCompiler(Template<? extends FragmentData> template, FileResolution header) {
this.header = header;
this.fragment = fragment;
this.template = template;
}
@Override
protected GlShader _create(Context key) {
SourceFile fragmentFile = key.file;
FragmentTemplateData appliedTemplate = fragment.apply(fragmentFile);
StringBuilder finalSource = new StringBuilder();
StringBuilder builder = new StringBuilder();
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.FRAGMENT));
builder.append(CompileUtil.generateHeader(fragment.getVersion(), ShaderType.FRAGMENT));
key.getShaderConstants().writeInto(builder);
key.getShaderConstants().writeInto(finalSource);
FileIndexImpl index = new FileIndexImpl();
header.getFile().generateFinalSource(index, builder);
fragmentFile.generateFinalSource(index, builder);
header.getFile().generateFinalSource(index, finalSource);
key.file.generateFinalSource(index, finalSource);
builder.append(appliedTemplate.generateFooter());
FragmentData appliedTemplate = template.apply(key.file);
finalSource.append(appliedTemplate.generateFooter());
return new GlShader(fragmentFile.name, ShaderType.FRAGMENT, builder.toString());
return new GlShader(key.file.name, ShaderType.FRAGMENT, finalSource.toString());
}
@Override
@ -64,10 +63,16 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
*/
private final float alphaDiscard;
public Context(SourceFile file, StateSnapshot ctx, float alphaDiscard) {
/**
* Which type of fog should be applied.
*/
private final FogType fogType;
public Context(SourceFile file, StateSnapshot ctx, float alphaDiscard, FogType fogType) {
this.file = file;
this.ctx = ctx;
this.alphaDiscard = alphaDiscard;
this.fogType = fogType;
}
public ShaderConstants getShaderConstants() {
@ -76,6 +81,7 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
if (alphaDiscard > 0) {
shaderConstants.define("ALPHA_DISCARD", alphaDiscard);
}
shaderConstants.define(fogType.name());
return shaderConstants;
}
@ -85,17 +91,17 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (Context) obj;
return this.file == that.file && Objects.equals(this.ctx, that.ctx) && Float.floatToIntBits(this.alphaDiscard) == Float.floatToIntBits(that.alphaDiscard);
return this.file == that.file && Objects.equals(this.ctx, that.ctx) && Float.floatToIntBits(this.alphaDiscard) == Float.floatToIntBits(that.alphaDiscard) && fogType == that.fogType;
}
@Override
public int hashCode() {
return Objects.hash(file, ctx, alphaDiscard);
return Objects.hash(file, ctx, alphaDiscard, fogType);
}
@Override
public String toString() {
return "Context[" + "file=" + file + ", " + "ctx=" + ctx + ", " + "alphaDiscard=" + alphaDiscard + ']';
return "Context[" + "file=" + file + ", " + "ctx=" + ctx + ", " + "alphaDiscard=" + alphaDiscard + ", " + "fogType=" + fogType + ']';
}
}

View file

@ -30,7 +30,6 @@ public class FragmentTemplateData implements FragmentData {
fragmentMain = maybeFragmentMain.get();
ImmutableList<Variable> fragmentParameters = fragmentMain.getParameters();
if (fragmentParameters.size() != 1) {
ErrorReporter.generateSpanError(fragmentMain.getArgs(), "fragment function must have exactly one argument");
throw new RuntimeException();

View file

@ -47,7 +47,6 @@ public class InstancingTemplateData implements VertexData {
.toString()
.equals("Vertex");
if (!(namedVertex && vertexParam.qualifier == Variable.Qualifier.INOUT)) {
ErrorReporter.generateSpanError(vertexParam.qualifierSpan, "first parameter must be inout Vertex");
throw new ShaderLoadingException();
@ -103,7 +102,7 @@ public class InstancingTemplateData implements VertexData {
v2f_color = v.color;
v2f_texCoords = v.texCoords;
v2f_light = v.light;
v2f_diffuse = diffuse(v.normal);
v2f_diffuse = FLWDiffuse(v.normal);
#if defined(DEBUG_NORMAL)
v2f_color = vec4(v.normal, 1.);
#endif

View file

@ -63,7 +63,7 @@ public class OneShotTemplateData implements VertexData {
v2f_color = v.color;
v2f_texCoords = v.texCoords;
v2f_light = v.light;
v2f_diffuse = diffuse(v.normal);
v2f_diffuse = FLWDiffuse(v.normal);
#if defined(DEBUG_NORMAL)
v2f_color = vec4(v.normal, 1.);
#endif

View file

@ -65,7 +65,7 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
protected P _create(ProgramContext ctx) {
return new ProgramAssembler(ctx.spec.name)
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.spec.getVertexFile(), ctx.ctx, ctx.vertexType)))
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.spec.getFragmentFile(), ctx.ctx, ctx.alphaDiscard)))
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.spec.getFragmentFile(), ctx.ctx, ctx.alphaDiscard, ctx.fogType)))
.link()
.build(this.factory);
}

View file

@ -4,6 +4,7 @@ import java.util.Objects;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType;
import com.jozufozu.flywheel.core.GameStateRegistry;
import com.jozufozu.flywheel.core.shader.ProgramSpec;
import com.jozufozu.flywheel.core.shader.StateSnapshot;
@ -22,30 +23,33 @@ public final class ProgramContext {
* @param alphaDiscard The alpha threshold below which pixels are discarded.
* @return A compilation context.
*/
public static ProgramContext create(ResourceLocation programName, VertexType vertexType, float alphaDiscard) {
public static ProgramContext create(ResourceLocation programName, VertexType vertexType, float alphaDiscard, FogType fogType) {
ProgramSpec spec = Backend.getSpec(programName);
if (spec == null) {
throw new NullPointerException("Cannot compile shader because '" + programName + "' is not recognized.");
}
return new ProgramContext(spec, alphaDiscard, vertexType, GameStateRegistry.takeSnapshot());
return new ProgramContext(spec, alphaDiscard, fogType, vertexType, GameStateRegistry.takeSnapshot());
}
public final ProgramSpec spec;
public final float alphaDiscard;
public final FogType fogType;
public final VertexType vertexType;
public final StateSnapshot ctx;
/**
* @param spec The program to use.
* @param alphaDiscard Alpha threshold below which pixels are discarded.
* @param fogType Which type of fog should be applied.
* @param vertexType The vertexType the program should be adapted for.
* @param ctx A snapshot of the game state.
*/
public ProgramContext(ProgramSpec spec, float alphaDiscard, VertexType vertexType, StateSnapshot ctx) {
public ProgramContext(ProgramSpec spec, float alphaDiscard, FogType fogType, VertexType vertexType, StateSnapshot ctx) {
this.spec = spec;
this.alphaDiscard = alphaDiscard;
this.fogType = fogType;
this.vertexType = vertexType;
this.ctx = ctx;
}
@ -55,16 +59,16 @@ public final class ProgramContext {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
var that = (ProgramContext) o;
return spec == that.spec && vertexType == that.vertexType && ctx.equals(that.ctx) && Float.floatToIntBits(alphaDiscard) == Float.floatToIntBits(that.alphaDiscard);
return spec == that.spec && vertexType == that.vertexType && ctx.equals(that.ctx) && Float.floatToIntBits(alphaDiscard) == Float.floatToIntBits(that.alphaDiscard) && fogType == that.fogType;
}
@Override
public int hashCode() {
return Objects.hash(spec, alphaDiscard, vertexType, ctx);
return Objects.hash(spec, alphaDiscard, fogType, vertexType, ctx);
}
@Override
public String toString() {
return "ProgramContext{" + "spec=" + spec + ", alphaDiscard=" + alphaDiscard + ", vertexType=" + vertexType + ", ctx=" + ctx + '}';
return "ProgramContext{" + "spec=" + spec + ", alphaDiscard=" + alphaDiscard + ", fogType=" + fogType + ", vertexType=" + vertexType + ", ctx=" + ctx + '}';
}
}

View file

@ -5,7 +5,6 @@ import java.util.Objects;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.core.Templates;
import com.jozufozu.flywheel.core.shader.StateSnapshot;
import com.jozufozu.flywheel.core.source.FileIndexImpl;
import com.jozufozu.flywheel.core.source.FileResolution;
@ -41,7 +40,6 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
FileIndexImpl index = new FileIndexImpl();
Templates.DIFFUSE_FILE.getFile().generateFinalSource(index, finalSource);
header.getFile().generateFinalSource(index, finalSource);
key.file.generateFinalSource(index, finalSource);

View file

@ -15,6 +15,7 @@ import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterial;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
import com.jozufozu.flywheel.core.Contexts;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.mixin.LevelRendererAccessor;
import com.jozufozu.flywheel.util.Lazy;
@ -161,7 +162,7 @@ public class CrumblingRenderer {
}
@Override
protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection) {
protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
type.setupRenderState();
int renderTex = RenderSystem.getShaderTexture(0);
@ -187,10 +188,10 @@ public class CrumblingRenderer {
RenderSystem.setShaderTexture(4, breakingTex);
Textures.bindActiveTextures();
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
CrumblingProgram program = setup(type, camX, camY, camZ, viewProjection, entry.getKey()
.getProgramSpec());
CrumblingProgram program = setup(entry.getKey().getProgramSpec(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
program.setAtlasSize(width, height);

View file

@ -7,16 +7,19 @@ import com.mojang.blaze3d.systems.RenderSystem;
public class WorldFog {
private final int uFogColor;
private final int uFogRange;
private final int uFogColor;
private final int uFogShape;
public WorldFog(GlProgram program) {
this.uFogColor = program.getUniformLocation("uFogColor");
this.uFogRange = program.getUniformLocation("uFogRange");
this.uFogColor = program.getUniformLocation("uFogColor");
this.uFogShape = program.getUniformLocation("uFogShape");
}
public void bind() {
public void uploadUniforms() {
GL20.glUniform2f(uFogRange, RenderSystem.getShaderFogStart(), RenderSystem.getShaderFogEnd());
GL20.glUniform4fv(uFogColor, RenderSystem.getShaderFogColor());
GL20.glUniform1i(uFogShape, RenderSystem.getShaderFogShape().getIndex());
}
}

View file

@ -1,6 +1,7 @@
package com.jozufozu.flywheel.core.shader;
import static org.lwjgl.opengl.GL20.glUniform1f;
import static org.lwjgl.opengl.GL20.glUniform1i;
import static org.lwjgl.opengl.GL20.glUniform2f;
import static org.lwjgl.opengl.GL20.glUniform3f;
@ -10,6 +11,7 @@ import com.mojang.blaze3d.platform.Window;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.resources.ResourceLocation;
public class WorldProgram extends GlProgram {
@ -17,6 +19,7 @@ public class WorldProgram extends GlProgram {
protected final int uViewProjection = getUniformLocation("uViewProjection");
protected final int uCameraPos = getUniformLocation("uCameraPos");
protected final int uWindowSize = getUniformLocation("uWindowSize");
protected final int uConstantAmbientLight = getUniformLocation("uConstantAmbientLight");
private final WorldFog fog;
protected int uBlockAtlas;
@ -27,7 +30,7 @@ public class WorldProgram extends GlProgram {
fog = new WorldFog(this);
super.bind();
bind();
registerSamplers();
unbind();
}
@ -37,13 +40,34 @@ public class WorldProgram extends GlProgram {
uLightMap = setSamplerBinding("uLightMap", 2);
}
public void uploadViewProjection(Matrix4f viewProjection) {
public void uploadUniforms(double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
fog.uploadUniforms();
uploadTime(AnimationTickHolder.getRenderTime());
uploadViewProjection(viewProjection);
uploadCameraPos(camX, camY, camZ);
uploadWindowSize();
uploadConstantAmbientLight(level);
}
protected void uploadTime(float renderTime) {
if (uTime < 0) return;
glUniform1f(uTime, renderTime);
}
protected void uploadViewProjection(Matrix4f viewProjection) {
if (uViewProjection < 0) return;
uploadMatrixUniform(uViewProjection, viewProjection);
}
public void uploadWindowSize() {
protected void uploadCameraPos(double camX, double camY, double camZ) {
if (uCameraPos < 0) return;
glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
}
protected void uploadWindowSize() {
if (uWindowSize < 0) return;
Window window = Minecraft.getInstance().getWindow();
@ -53,23 +77,9 @@ public class WorldProgram extends GlProgram {
glUniform2f(uWindowSize, width, height);
}
public void uploadCameraPos(double camX, double camY, double camZ) {
if (uCameraPos < 0) return;
protected void uploadConstantAmbientLight(ClientLevel level) {
if (uConstantAmbientLight < 0) return;
glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
}
public void uploadTime(float renderTime) {
if (uTime < 0) return;
glUniform1f(uTime, renderTime);
}
@Override
public void bind() {
super.bind();
fog.bind();
uploadWindowSize();
uploadTime(AnimationTickHolder.getRenderTime());
glUniform1i(uConstantAmbientLight, level.effects().constantAmbientLight() ? 1 : 0);
}
}

View file

@ -36,16 +36,14 @@ public class ShaderSources implements SourceFinder {
});
for (ResourceLocation location : allShaders) {
try {
Resource resource = manager.getResource(location);
try (Resource resource = manager.getResource(location)) {
String source = StringUtil.readToString(resource.getInputStream());
ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR);
shaderSources.put(name, new SourceFile(this, name, source));
} catch (IOException e) {
//
}
}

View file

@ -13,14 +13,14 @@ import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.blockentity.BellRenderer;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.entity.BellBlockEntity;
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, RenderType.cutoutMipped());
private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, Sheets.solidBlockSheet());
private final OrientedData bell;

View file

@ -3,6 +3,7 @@
uniform float uTime;
uniform mat4 uViewProjection;
uniform vec3 uCameraPos;
uniform int uConstantAmbientLight;
uniform vec2 uTextureScale;
uniform sampler2D uBlockAtlas;
@ -11,13 +12,24 @@ uniform sampler2D uCrumbling;
uniform vec2 uWindowSize;
#if defined(VERTEX_SHADER)
#ifdef VERTEX_SHADER
#use "flywheel:context/diffuse.glsl"
vec4 FLWVertex(inout Vertex v) {
FragDistance = cylindrical_distance(v.pos, uCameraPos);
fragDistance = fog_distance(v.pos, uCameraPos);
return uViewProjection * vec4(v.pos, 1.);
}
float FLWDiffuse(vec3 normal) {
if (uConstantAmbientLight == 1) {
return diffuseNether(normal);
} else {
return diffuse(normal);
}
}
#elif defined(FRAGMENT_SHADER)
out vec4 fragColor;
@ -29,23 +41,24 @@ vec4 FLWBlockTexture(vec2 texCoords) {
return cr;
}
vec4 FLWLight(vec2 lightCoords) {
return vec4(1.);
}
void FLWFinalizeColor(vec4 color) {
#if defined(USE_FOG)
float a = color.a;
float fog = clamp(FLWFogFactor(), 0., 1.);
color = mix(uFogColor, color, fog);
color.a = a;
#endif
if (color.a < 0.1) {
#ifdef ALPHA_DISCARD
if (color.a < ALPHA_DISCARD) {
discard;
}
#endif
#ifdef COLOR_FOG
color = linear_fog(color);
#elif defined(FADE_FOG)
color = linear_fog_fade(color);
#endif
fragColor = color;
}
vec4 FLWLight(vec2 lightCoords) {
return vec4(1.);
}
#endif

View file

@ -1,5 +1,9 @@
float diffuse(vec3 normal) {
vec3 n2 = normal * normal * vec3(.6, .25, .8);
return min(n2.x + n2.y * (3. + normal.y) + n2.z, 1.);
}
float diffuseNether(vec3 normal) {
vec3 n2 = normal * normal * vec3(.6, .9, .8);
return min(n2.x + n2.y + n2.z, 1.);
}

View file

@ -1,23 +1,50 @@
#if defined(VERTEX_SHADER)
out float FragDistance;
#elif defined(FRAGMENT_SHADER)
in float FragDistance;
#endif
uniform vec4 uFogColor;
uniform vec2 uFogRange;
uniform int uFogShape;
float cylindrical_distance(vec3 worldPos, vec3 cameraPos) {
float distXZ = length(worldPos.xz - cameraPos.xz);
float distY = abs(worldPos.y - cameraPos.y);
#ifdef VERTEX_SHADER
out float fragDistance;
#elif defined(FRAGMENT_SHADER)
in float fragDistance;
#endif
float spherical_distance(vec3 relativePos) {
return length(relativePos);
}
float cylindrical_distance(vec3 relativePos) {
float distXZ = length(relativePos.xz);
float distY = abs(relativePos.y);
return max(distXZ, distY);
}
float cylindrical_distance(vec3 worldPos) {
float distXZ = length(worldPos.xz);
float distY = abs(worldPos.y);
return max(distXZ, distY);
float fog_distance(vec3 relativePos) {
if (uFogShape == 0) {
return spherical_distance(relativePos);
} else {
return cylindrical_distance(relativePos);
}
}
float FLWFogFactor() {
return (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
float fog_distance(vec3 worldPos, vec3 cameraPos) {
return fog_distance(worldPos - cameraPos);
}
vec4 linear_fog(vec4 color) {
if (fragDistance <= uFogRange.x) {
return color;
}
float fogValue = fragDistance < uFogRange.y ? smoothstep(uFogRange.x, uFogRange.y, fragDistance) : 1.0;
return vec4(mix(color.rgb, uFogColor.rgb, fogValue * uFogColor.a), color.a);
}
vec4 linear_fog_fade(vec4 color) {
if (fragDistance <= uFogRange.x) {
return color;
} else if (fragDistance >= uFogRange.y) {
return vec4(0.0);
}
return color * smoothstep(uFogRange.y, uFogRange.x, fragDistance);
}

View file

@ -3,6 +3,7 @@
uniform float uTime;
uniform mat4 uViewProjection;
uniform vec3 uCameraPos;
uniform int uConstantAmbientLight;
uniform vec2 uTextureScale;
uniform sampler2D uBlockAtlas;
@ -10,19 +11,31 @@ uniform sampler2D uLightMap;
uniform vec2 uWindowSize;
#if defined(VERTEX_SHADER)
#ifdef VERTEX_SHADER
#use "flywheel:context/diffuse.glsl"
vec4 FLWVertex(inout Vertex v) {
FragDistance = cylindrical_distance(v.pos, uCameraPos);
fragDistance = fog_distance(v.pos, uCameraPos);
return uViewProjection * vec4(v.pos, 1.);
}
float FLWDiffuse(vec3 normal) {
if (uConstantAmbientLight == 1) {
return diffuseNether(normal);
} else {
return diffuse(normal);
}
}
#elif defined(FRAGMENT_SHADER)
#use "flywheel:core/lightutil.glsl"
// optimize discard usage
#if defined(ALPHA_DISCARD)
#if defined(GL_ARB_conservative_depth)
#ifdef ALPHA_DISCARD
#ifdef GL_ARB_conservative_depth
layout (depth_greater) out float gl_FragDepth;
#endif
#endif
@ -32,23 +45,24 @@ vec4 FLWBlockTexture(vec2 texCoords) {
return texture(uBlockAtlas, texCoords);
}
vec4 FLWLight(vec2 lightCoords) {
return texture(uLightMap, shiftLight(lightCoords));
}
void FLWFinalizeColor(vec4 color) {
float a = color.a;
float fog = clamp(FLWFogFactor(), 0., 1.);
color = mix(uFogColor, color, fog);
color.a = a;
#if defined(ALPHA_DISCARD)
#ifdef ALPHA_DISCARD
if (color.a < ALPHA_DISCARD) {
discard;
}
#endif
#ifdef COLOR_FOG
color = linear_fog(color);
#elif defined(FADE_FOG)
color = linear_fog_fade(color);
#endif
fragColor = color;
}
vec4 FLWLight(vec2 lightCoords) {
return texture(uLightMap, shiftLight(lightCoords));
}
#endif

View file

@ -1,4 +1,3 @@
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);

View file

@ -1,4 +1,3 @@
#define PIOVER2 1.5707963268
vec4 quat(vec3 axis, float angle) {