mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-07 12:56:31 +01:00
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:
parent
958188fc77
commit
4c7b035f5d
27 changed files with 319 additions and 152 deletions
|
@ -36,7 +36,6 @@ println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getPro
|
||||||
minecraft {
|
minecraft {
|
||||||
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
|
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
|
||||||
|
|
||||||
|
|
||||||
runs {
|
runs {
|
||||||
client {
|
client {
|
||||||
workingDirectory project.file('run')
|
workingDirectory project.file('run')
|
||||||
|
@ -107,7 +106,7 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
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
|
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||||
|
|
|
@ -5,7 +5,7 @@ org.gradle.daemon = false
|
||||||
mod_version = 0.7.0
|
mod_version = 0.7.0
|
||||||
mc_update_version = 1.18
|
mc_update_version = 1.18
|
||||||
minecraft_version = 1.18.2
|
minecraft_version = 1.18.2
|
||||||
forge_version = 40.0.15
|
forge_version = 40.1.0
|
||||||
|
|
||||||
# build dependency versions
|
# build dependency versions
|
||||||
forgegradle_version = 5.1.+
|
forgegradle_version = 5.1.+
|
||||||
|
|
|
@ -96,9 +96,7 @@ public class Loader implements ResourceManagerReloadListener {
|
||||||
Collection<ResourceLocation> programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json"));
|
Collection<ResourceLocation> programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json"));
|
||||||
|
|
||||||
for (ResourceLocation location : programSpecs) {
|
for (ResourceLocation location : programSpecs) {
|
||||||
try {
|
try (Resource file = manager.getResource(location)) {
|
||||||
Resource file = manager.getResource(location);
|
|
||||||
|
|
||||||
String s = StringUtil.readToString(file.getInputStream());
|
String s = StringUtil.readToString(file.getInputStream());
|
||||||
|
|
||||||
ResourceLocation specName = ResourceUtil.trim(location, PROGRAM_DIR, ".json");
|
ResourceLocation specName = ResourceUtil.trim(location, PROGRAM_DIR, ".json");
|
||||||
|
|
|
@ -21,8 +21,8 @@ public class GlShader extends GlObject {
|
||||||
GlCompat.safeShaderSource(handle, source);
|
GlCompat.safeShaderSource(handle, source);
|
||||||
GL20.glCompileShader(handle);
|
GL20.glCompileShader(handle);
|
||||||
|
|
||||||
String log = GL20.glGetShaderInfoLog(handle);
|
// String log = GL20.glGetShaderInfoLog(handle);
|
||||||
|
//
|
||||||
// if (!log.isEmpty()) {
|
// if (!log.isEmpty()) {
|
||||||
// env.printShaderInfoLog(source, log, this.name);
|
// env.printShaderInfoLog(source, log, this.name);
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -16,16 +16,20 @@ import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.backend.model.MeshPool;
|
import com.jozufozu.flywheel.backend.model.MeshPool;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
import com.jozufozu.flywheel.core.Formats;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
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.ProgramCompiler;
|
||||||
import com.jozufozu.flywheel.core.compile.ProgramContext;
|
import com.jozufozu.flywheel.core.compile.ProgramContext;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.util.Textures;
|
import com.jozufozu.flywheel.util.Textures;
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.ShaderInstance;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
@ -73,10 +77,10 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
|
|
||||||
// don't want to mutate viewProjection
|
// don't want to mutate viewProjection
|
||||||
var vp = context.viewProjection().copy();
|
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) {
|
for (RenderType renderType : toRender) {
|
||||||
render(renderType, camX, camY, camZ, vp);
|
render(renderType, camX, camY, camZ, vp, context.level());
|
||||||
}
|
}
|
||||||
toRender.clear();
|
toRender.clear();
|
||||||
}
|
}
|
||||||
|
@ -90,19 +94,20 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
|
|
||||||
// don't want to mutate viewProjection
|
// don't want to mutate viewProjection
|
||||||
var vp = context.viewProjection().copy();
|
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)) {
|
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;
|
vertexCount = 0;
|
||||||
instanceCount = 0;
|
instanceCount = 0;
|
||||||
|
|
||||||
type.setupRenderState();
|
type.setupRenderState();
|
||||||
Textures.bindActiveTextures();
|
Textures.bindActiveTextures();
|
||||||
|
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
||||||
|
|
||||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||||
InstancedMaterial<?> material = entry.getValue();
|
InstancedMaterial<?> material = entry.getValue();
|
||||||
|
@ -113,7 +118,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
if (!toRender.isEmpty()) {
|
if (!toRender.isEmpty()) {
|
||||||
Instanced<? extends InstanceData> instanceType = entry.getKey();
|
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();
|
instanceCount += material.getInstanceCount();
|
||||||
vertexCount += material.getVertexCount();
|
vertexCount += material.getVertexCount();
|
||||||
|
@ -125,12 +130,33 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
type.clearRenderState();
|
type.clearRenderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected P setup(RenderType layer, double camX, double camY, double camZ, Matrix4f viewProjection, ResourceLocation programSpec) {
|
protected CoreShaderInfo getCoreShaderInfo() {
|
||||||
P program = context.getProgram(ProgramContext.create(programSpec, Formats.POS_TEX_NORMAL, RenderTypeRegistry.getAlphaDiscard(layer)));
|
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.bind();
|
||||||
program.uploadViewProjection(viewProjection);
|
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
||||||
program.uploadCameraPos(camX, camY, camZ);
|
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class Contexts {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
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 WORLD = Flywheel.rl("context/world");
|
||||||
|
public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,12 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
|
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
|
||||||
import com.jozufozu.flywheel.core.compile.FragmentTemplateData;
|
import com.jozufozu.flywheel.core.compile.FragmentTemplateData;
|
||||||
import com.jozufozu.flywheel.core.compile.InstancingTemplateData;
|
import com.jozufozu.flywheel.core.compile.InstancingTemplateData;
|
||||||
import com.jozufozu.flywheel.core.compile.OneShotTemplateData;
|
import com.jozufozu.flywheel.core.compile.OneShotTemplateData;
|
||||||
import com.jozufozu.flywheel.core.compile.Template;
|
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 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<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<OneShotTemplateData> ONE_SHOT = new Template<>(GLSLVersion.V150, OneShotTemplateData::new);
|
||||||
public static final Template<FragmentTemplateData> FRAGMENT = new Template<>(GLSLVersion.V150, FragmentTemplateData::new);
|
public static final Template<FragmentTemplateData> FRAGMENT = new Template<>(GLSLVersion.V150, FragmentTemplateData::new);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Objects;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
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.ShaderConstants;
|
||||||
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
||||||
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
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;
|
import com.jozufozu.flywheel.core.source.SourceFile;
|
||||||
|
|
||||||
public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShader> {
|
public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShader> {
|
||||||
|
private final Template<? extends FragmentData> template;
|
||||||
private final FileResolution header;
|
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.header = header;
|
||||||
this.fragment = fragment;
|
this.template = template;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GlShader _create(Context key) {
|
protected GlShader _create(Context key) {
|
||||||
SourceFile fragmentFile = key.file;
|
StringBuilder finalSource = new StringBuilder();
|
||||||
FragmentTemplateData appliedTemplate = fragment.apply(fragmentFile);
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.FRAGMENT));
|
||||||
|
|
||||||
builder.append(CompileUtil.generateHeader(fragment.getVersion(), ShaderType.FRAGMENT));
|
key.getShaderConstants().writeInto(finalSource);
|
||||||
|
|
||||||
key.getShaderConstants().writeInto(builder);
|
|
||||||
|
|
||||||
FileIndexImpl index = new FileIndexImpl();
|
FileIndexImpl index = new FileIndexImpl();
|
||||||
|
|
||||||
header.getFile().generateFinalSource(index, builder);
|
header.getFile().generateFinalSource(index, finalSource);
|
||||||
fragmentFile.generateFinalSource(index, builder);
|
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
|
@Override
|
||||||
|
@ -64,10 +63,16 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
*/
|
*/
|
||||||
private final float alphaDiscard;
|
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.file = file;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.alphaDiscard = alphaDiscard;
|
this.alphaDiscard = alphaDiscard;
|
||||||
|
this.fogType = fogType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderConstants getShaderConstants() {
|
public ShaderConstants getShaderConstants() {
|
||||||
|
@ -76,6 +81,7 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
if (alphaDiscard > 0) {
|
if (alphaDiscard > 0) {
|
||||||
shaderConstants.define("ALPHA_DISCARD", alphaDiscard);
|
shaderConstants.define("ALPHA_DISCARD", alphaDiscard);
|
||||||
}
|
}
|
||||||
|
shaderConstants.define(fogType.name());
|
||||||
|
|
||||||
return shaderConstants;
|
return shaderConstants;
|
||||||
}
|
}
|
||||||
|
@ -85,17 +91,17 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
if (obj == this) return true;
|
if (obj == this) return true;
|
||||||
if (obj == null || obj.getClass() != this.getClass()) return false;
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
var that = (Context) obj;
|
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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(file, ctx, alphaDiscard);
|
return Objects.hash(file, ctx, alphaDiscard, fogType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Context[" + "file=" + file + ", " + "ctx=" + ctx + ", " + "alphaDiscard=" + alphaDiscard + ']';
|
return "Context[" + "file=" + file + ", " + "ctx=" + ctx + ", " + "alphaDiscard=" + alphaDiscard + ", " + "fogType=" + fogType + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ public class FragmentTemplateData implements FragmentData {
|
||||||
fragmentMain = maybeFragmentMain.get();
|
fragmentMain = maybeFragmentMain.get();
|
||||||
ImmutableList<Variable> fragmentParameters = fragmentMain.getParameters();
|
ImmutableList<Variable> fragmentParameters = fragmentMain.getParameters();
|
||||||
|
|
||||||
|
|
||||||
if (fragmentParameters.size() != 1) {
|
if (fragmentParameters.size() != 1) {
|
||||||
ErrorReporter.generateSpanError(fragmentMain.getArgs(), "fragment function must have exactly one argument");
|
ErrorReporter.generateSpanError(fragmentMain.getArgs(), "fragment function must have exactly one argument");
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
|
|
|
@ -47,7 +47,6 @@ public class InstancingTemplateData implements VertexData {
|
||||||
.toString()
|
.toString()
|
||||||
.equals("Vertex");
|
.equals("Vertex");
|
||||||
|
|
||||||
|
|
||||||
if (!(namedVertex && vertexParam.qualifier == Variable.Qualifier.INOUT)) {
|
if (!(namedVertex && vertexParam.qualifier == Variable.Qualifier.INOUT)) {
|
||||||
ErrorReporter.generateSpanError(vertexParam.qualifierSpan, "first parameter must be inout Vertex");
|
ErrorReporter.generateSpanError(vertexParam.qualifierSpan, "first parameter must be inout Vertex");
|
||||||
throw new ShaderLoadingException();
|
throw new ShaderLoadingException();
|
||||||
|
@ -103,7 +102,7 @@ public class InstancingTemplateData implements VertexData {
|
||||||
v2f_color = v.color;
|
v2f_color = v.color;
|
||||||
v2f_texCoords = v.texCoords;
|
v2f_texCoords = v.texCoords;
|
||||||
v2f_light = v.light;
|
v2f_light = v.light;
|
||||||
v2f_diffuse = diffuse(v.normal);
|
v2f_diffuse = FLWDiffuse(v.normal);
|
||||||
#if defined(DEBUG_NORMAL)
|
#if defined(DEBUG_NORMAL)
|
||||||
v2f_color = vec4(v.normal, 1.);
|
v2f_color = vec4(v.normal, 1.);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class OneShotTemplateData implements VertexData {
|
||||||
v2f_color = v.color;
|
v2f_color = v.color;
|
||||||
v2f_texCoords = v.texCoords;
|
v2f_texCoords = v.texCoords;
|
||||||
v2f_light = v.light;
|
v2f_light = v.light;
|
||||||
v2f_diffuse = diffuse(v.normal);
|
v2f_diffuse = FLWDiffuse(v.normal);
|
||||||
#if defined(DEBUG_NORMAL)
|
#if defined(DEBUG_NORMAL)
|
||||||
v2f_color = vec4(v.normal, 1.);
|
v2f_color = vec4(v.normal, 1.);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
|
||||||
protected P _create(ProgramContext ctx) {
|
protected P _create(ProgramContext ctx) {
|
||||||
return new ProgramAssembler(ctx.spec.name)
|
return new ProgramAssembler(ctx.spec.name)
|
||||||
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.spec.getVertexFile(), ctx.ctx, ctx.vertexType)))
|
.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()
|
.link()
|
||||||
.build(this.factory);
|
.build(this.factory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Objects;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
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.GameStateRegistry;
|
||||||
import com.jozufozu.flywheel.core.shader.ProgramSpec;
|
import com.jozufozu.flywheel.core.shader.ProgramSpec;
|
||||||
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
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.
|
* @param alphaDiscard The alpha threshold below which pixels are discarded.
|
||||||
* @return A compilation context.
|
* @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);
|
ProgramSpec spec = Backend.getSpec(programName);
|
||||||
|
|
||||||
if (spec == null) {
|
if (spec == null) {
|
||||||
throw new NullPointerException("Cannot compile shader because '" + programName + "' is not recognized.");
|
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 ProgramSpec spec;
|
||||||
public final float alphaDiscard;
|
public final float alphaDiscard;
|
||||||
|
public final FogType fogType;
|
||||||
public final VertexType vertexType;
|
public final VertexType vertexType;
|
||||||
public final StateSnapshot ctx;
|
public final StateSnapshot ctx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param spec The program to use.
|
* @param spec The program to use.
|
||||||
* @param alphaDiscard Alpha threshold below which pixels are discarded.
|
* @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 vertexType The vertexType the program should be adapted for.
|
||||||
* @param ctx A snapshot of the game state.
|
* @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.spec = spec;
|
||||||
this.alphaDiscard = alphaDiscard;
|
this.alphaDiscard = alphaDiscard;
|
||||||
|
this.fogType = fogType;
|
||||||
this.vertexType = vertexType;
|
this.vertexType = vertexType;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
@ -55,16 +59,16 @@ public final class ProgramContext {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
var that = (ProgramContext) o;
|
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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(spec, alphaDiscard, vertexType, ctx);
|
return Objects.hash(spec, alphaDiscard, fogType, vertexType, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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 + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import java.util.Objects;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
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.shader.StateSnapshot;
|
||||||
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
@ -41,7 +40,6 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
|
|
||||||
FileIndexImpl index = new FileIndexImpl();
|
FileIndexImpl index = new FileIndexImpl();
|
||||||
|
|
||||||
Templates.DIFFUSE_FILE.getFile().generateFinalSource(index, finalSource);
|
|
||||||
header.getFile().generateFinalSource(index, finalSource);
|
header.getFile().generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
key.file.generateFinalSource(index, finalSource);
|
key.file.generateFinalSource(index, finalSource);
|
||||||
|
|
|
@ -15,6 +15,7 @@ import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterial;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
|
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
import com.jozufozu.flywheel.mixin.LevelRendererAccessor;
|
import com.jozufozu.flywheel.mixin.LevelRendererAccessor;
|
||||||
import com.jozufozu.flywheel.util.Lazy;
|
import com.jozufozu.flywheel.util.Lazy;
|
||||||
|
@ -161,7 +162,7 @@ public class CrumblingRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
type.setupRenderState();
|
||||||
|
|
||||||
int renderTex = RenderSystem.getShaderTexture(0);
|
int renderTex = RenderSystem.getShaderTexture(0);
|
||||||
|
@ -187,10 +188,10 @@ public class CrumblingRenderer {
|
||||||
RenderSystem.setShaderTexture(4, breakingTex);
|
RenderSystem.setShaderTexture(4, breakingTex);
|
||||||
|
|
||||||
Textures.bindActiveTextures();
|
Textures.bindActiveTextures();
|
||||||
|
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
||||||
|
|
||||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||||
CrumblingProgram program = setup(type, camX, camY, camZ, viewProjection, entry.getKey()
|
CrumblingProgram program = setup(entry.getKey().getProgramSpec(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
||||||
.getProgramSpec());
|
|
||||||
|
|
||||||
program.setAtlasSize(width, height);
|
program.setAtlasSize(width, height);
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,19 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
public class WorldFog {
|
public class WorldFog {
|
||||||
|
|
||||||
private final int uFogColor;
|
|
||||||
private final int uFogRange;
|
private final int uFogRange;
|
||||||
|
private final int uFogColor;
|
||||||
|
private final int uFogShape;
|
||||||
|
|
||||||
public WorldFog(GlProgram program) {
|
public WorldFog(GlProgram program) {
|
||||||
this.uFogColor = program.getUniformLocation("uFogColor");
|
|
||||||
this.uFogRange = program.getUniformLocation("uFogRange");
|
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.glUniform2f(uFogRange, RenderSystem.getShaderFogStart(), RenderSystem.getShaderFogEnd());
|
||||||
GL20.glUniform4fv(uFogColor, RenderSystem.getShaderFogColor());
|
GL20.glUniform4fv(uFogColor, RenderSystem.getShaderFogColor());
|
||||||
|
GL20.glUniform1i(uFogShape, RenderSystem.getShaderFogShape().getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.jozufozu.flywheel.core.shader;
|
package com.jozufozu.flywheel.core.shader;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.glUniform1f;
|
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.glUniform2f;
|
||||||
import static org.lwjgl.opengl.GL20.glUniform3f;
|
import static org.lwjgl.opengl.GL20.glUniform3f;
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ import com.mojang.blaze3d.platform.Window;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class WorldProgram extends GlProgram {
|
public class WorldProgram extends GlProgram {
|
||||||
|
@ -17,6 +19,7 @@ public class WorldProgram extends GlProgram {
|
||||||
protected final int uViewProjection = getUniformLocation("uViewProjection");
|
protected final int uViewProjection = getUniformLocation("uViewProjection");
|
||||||
protected final int uCameraPos = getUniformLocation("uCameraPos");
|
protected final int uCameraPos = getUniformLocation("uCameraPos");
|
||||||
protected final int uWindowSize = getUniformLocation("uWindowSize");
|
protected final int uWindowSize = getUniformLocation("uWindowSize");
|
||||||
|
protected final int uConstantAmbientLight = getUniformLocation("uConstantAmbientLight");
|
||||||
private final WorldFog fog;
|
private final WorldFog fog;
|
||||||
|
|
||||||
protected int uBlockAtlas;
|
protected int uBlockAtlas;
|
||||||
|
@ -27,7 +30,7 @@ public class WorldProgram extends GlProgram {
|
||||||
|
|
||||||
fog = new WorldFog(this);
|
fog = new WorldFog(this);
|
||||||
|
|
||||||
super.bind();
|
bind();
|
||||||
registerSamplers();
|
registerSamplers();
|
||||||
unbind();
|
unbind();
|
||||||
}
|
}
|
||||||
|
@ -37,13 +40,34 @@ public class WorldProgram extends GlProgram {
|
||||||
uLightMap = setSamplerBinding("uLightMap", 2);
|
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;
|
if (uViewProjection < 0) return;
|
||||||
|
|
||||||
uploadMatrixUniform(uViewProjection, viewProjection);
|
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;
|
if (uWindowSize < 0) return;
|
||||||
|
|
||||||
Window window = Minecraft.getInstance().getWindow();
|
Window window = Minecraft.getInstance().getWindow();
|
||||||
|
@ -53,23 +77,9 @@ public class WorldProgram extends GlProgram {
|
||||||
glUniform2f(uWindowSize, width, height);
|
glUniform2f(uWindowSize, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadCameraPos(double camX, double camY, double camZ) {
|
protected void uploadConstantAmbientLight(ClientLevel level) {
|
||||||
if (uCameraPos < 0) return;
|
if (uConstantAmbientLight < 0) return;
|
||||||
|
|
||||||
glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
|
glUniform1i(uConstantAmbientLight, level.effects().constantAmbientLight() ? 1 : 0);
|
||||||
}
|
|
||||||
|
|
||||||
public void uploadTime(float renderTime) {
|
|
||||||
if (uTime < 0) return;
|
|
||||||
|
|
||||||
glUniform1f(uTime, renderTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bind() {
|
|
||||||
super.bind();
|
|
||||||
fog.bind();
|
|
||||||
uploadWindowSize();
|
|
||||||
uploadTime(AnimationTickHolder.getRenderTime());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,16 +36,14 @@ public class ShaderSources implements SourceFinder {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (ResourceLocation location : allShaders) {
|
for (ResourceLocation location : allShaders) {
|
||||||
try {
|
try (Resource resource = manager.getResource(location)) {
|
||||||
Resource resource = manager.getResource(location);
|
|
||||||
|
|
||||||
String source = StringUtil.readToString(resource.getInputStream());
|
String source = StringUtil.readToString(resource.getInputStream());
|
||||||
|
|
||||||
ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR);
|
ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR);
|
||||||
|
|
||||||
shaderSources.put(name, new SourceFile(this, name, source));
|
shaderSources.put(name, new SourceFile(this, name, source));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@ import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
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.client.renderer.blockentity.BellRenderer;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
||||||
|
|
||||||
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
|
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;
|
private final OrientedData bell;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
uniform float uTime;
|
uniform float uTime;
|
||||||
uniform mat4 uViewProjection;
|
uniform mat4 uViewProjection;
|
||||||
uniform vec3 uCameraPos;
|
uniform vec3 uCameraPos;
|
||||||
|
uniform int uConstantAmbientLight;
|
||||||
|
|
||||||
uniform vec2 uTextureScale;
|
uniform vec2 uTextureScale;
|
||||||
uniform sampler2D uBlockAtlas;
|
uniform sampler2D uBlockAtlas;
|
||||||
|
@ -11,13 +12,24 @@ uniform sampler2D uCrumbling;
|
||||||
|
|
||||||
uniform vec2 uWindowSize;
|
uniform vec2 uWindowSize;
|
||||||
|
|
||||||
#if defined(VERTEX_SHADER)
|
#ifdef VERTEX_SHADER
|
||||||
|
|
||||||
|
#use "flywheel:context/diffuse.glsl"
|
||||||
|
|
||||||
vec4 FLWVertex(inout Vertex v) {
|
vec4 FLWVertex(inout Vertex v) {
|
||||||
FragDistance = cylindrical_distance(v.pos, uCameraPos);
|
fragDistance = fog_distance(v.pos, uCameraPos);
|
||||||
|
|
||||||
return uViewProjection * vec4(v.pos, 1.);
|
return uViewProjection * vec4(v.pos, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float FLWDiffuse(vec3 normal) {
|
||||||
|
if (uConstantAmbientLight == 1) {
|
||||||
|
return diffuseNether(normal);
|
||||||
|
} else {
|
||||||
|
return diffuse(normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(FRAGMENT_SHADER)
|
#elif defined(FRAGMENT_SHADER)
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
@ -29,23 +41,24 @@ vec4 FLWBlockTexture(vec2 texCoords) {
|
||||||
return cr;
|
return cr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 FLWLight(vec2 lightCoords) {
|
||||||
|
return vec4(1.);
|
||||||
|
}
|
||||||
|
|
||||||
void FLWFinalizeColor(vec4 color) {
|
void FLWFinalizeColor(vec4 color) {
|
||||||
#if defined(USE_FOG)
|
#ifdef ALPHA_DISCARD
|
||||||
float a = color.a;
|
if (color.a < ALPHA_DISCARD) {
|
||||||
float fog = clamp(FLWFogFactor(), 0., 1.);
|
|
||||||
|
|
||||||
color = mix(uFogColor, color, fog);
|
|
||||||
color.a = a;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (color.a < 0.1) {
|
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLOR_FOG
|
||||||
|
color = linear_fog(color);
|
||||||
|
#elif defined(FADE_FOG)
|
||||||
|
color = linear_fog_fade(color);
|
||||||
|
#endif
|
||||||
|
|
||||||
fragColor = color;
|
fragColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 FLWLight(vec2 lightCoords) {
|
|
||||||
return vec4(1.);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
|
||||||
float diffuse(vec3 normal) {
|
float diffuse(vec3 normal) {
|
||||||
vec3 n2 = normal * normal * vec3(.6, .25, .8);
|
vec3 n2 = normal * normal * vec3(.6, .25, .8);
|
||||||
return min(n2.x + n2.y * (3. + normal.y) + n2.z, 1.);
|
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.);
|
||||||
|
}
|
|
@ -1,23 +1,50 @@
|
||||||
#if defined(VERTEX_SHADER)
|
|
||||||
out float FragDistance;
|
|
||||||
#elif defined(FRAGMENT_SHADER)
|
|
||||||
in float FragDistance;
|
|
||||||
#endif
|
|
||||||
uniform vec4 uFogColor;
|
uniform vec4 uFogColor;
|
||||||
uniform vec2 uFogRange;
|
uniform vec2 uFogRange;
|
||||||
|
uniform int uFogShape;
|
||||||
|
|
||||||
float cylindrical_distance(vec3 worldPos, vec3 cameraPos) {
|
#ifdef VERTEX_SHADER
|
||||||
float distXZ = length(worldPos.xz - cameraPos.xz);
|
out float fragDistance;
|
||||||
float distY = abs(worldPos.y - cameraPos.y);
|
#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);
|
return max(distXZ, distY);
|
||||||
}
|
}
|
||||||
|
|
||||||
float cylindrical_distance(vec3 worldPos) {
|
float fog_distance(vec3 relativePos) {
|
||||||
float distXZ = length(worldPos.xz);
|
if (uFogShape == 0) {
|
||||||
float distY = abs(worldPos.y);
|
return spherical_distance(relativePos);
|
||||||
return max(distXZ, distY);
|
} else {
|
||||||
|
return cylindrical_distance(relativePos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float FLWFogFactor() {
|
float fog_distance(vec3 worldPos, vec3 cameraPos) {
|
||||||
return (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
uniform float uTime;
|
uniform float uTime;
|
||||||
uniform mat4 uViewProjection;
|
uniform mat4 uViewProjection;
|
||||||
uniform vec3 uCameraPos;
|
uniform vec3 uCameraPos;
|
||||||
|
uniform int uConstantAmbientLight;
|
||||||
|
|
||||||
uniform vec2 uTextureScale;
|
uniform vec2 uTextureScale;
|
||||||
uniform sampler2D uBlockAtlas;
|
uniform sampler2D uBlockAtlas;
|
||||||
|
@ -10,19 +11,31 @@ uniform sampler2D uLightMap;
|
||||||
|
|
||||||
uniform vec2 uWindowSize;
|
uniform vec2 uWindowSize;
|
||||||
|
|
||||||
#if defined(VERTEX_SHADER)
|
#ifdef VERTEX_SHADER
|
||||||
|
|
||||||
|
#use "flywheel:context/diffuse.glsl"
|
||||||
|
|
||||||
vec4 FLWVertex(inout Vertex v) {
|
vec4 FLWVertex(inout Vertex v) {
|
||||||
FragDistance = cylindrical_distance(v.pos, uCameraPos);
|
fragDistance = fog_distance(v.pos, uCameraPos);
|
||||||
|
|
||||||
return uViewProjection * vec4(v.pos, 1.);
|
return uViewProjection * vec4(v.pos, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float FLWDiffuse(vec3 normal) {
|
||||||
|
if (uConstantAmbientLight == 1) {
|
||||||
|
return diffuseNether(normal);
|
||||||
|
} else {
|
||||||
|
return diffuse(normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(FRAGMENT_SHADER)
|
#elif defined(FRAGMENT_SHADER)
|
||||||
|
|
||||||
#use "flywheel:core/lightutil.glsl"
|
#use "flywheel:core/lightutil.glsl"
|
||||||
|
|
||||||
// optimize discard usage
|
// optimize discard usage
|
||||||
#if defined(ALPHA_DISCARD)
|
#ifdef ALPHA_DISCARD
|
||||||
#if defined(GL_ARB_conservative_depth)
|
#ifdef GL_ARB_conservative_depth
|
||||||
layout (depth_greater) out float gl_FragDepth;
|
layout (depth_greater) out float gl_FragDepth;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,23 +45,24 @@ vec4 FLWBlockTexture(vec2 texCoords) {
|
||||||
return texture(uBlockAtlas, texCoords);
|
return texture(uBlockAtlas, texCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 FLWLight(vec2 lightCoords) {
|
||||||
|
return texture(uLightMap, shiftLight(lightCoords));
|
||||||
|
}
|
||||||
|
|
||||||
void FLWFinalizeColor(vec4 color) {
|
void FLWFinalizeColor(vec4 color) {
|
||||||
float a = color.a;
|
#ifdef ALPHA_DISCARD
|
||||||
float fog = clamp(FLWFogFactor(), 0., 1.);
|
|
||||||
|
|
||||||
color = mix(uFogColor, color, fog);
|
|
||||||
color.a = a;
|
|
||||||
|
|
||||||
#if defined(ALPHA_DISCARD)
|
|
||||||
if (color.a < ALPHA_DISCARD) {
|
if (color.a < ALPHA_DISCARD) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLOR_FOG
|
||||||
|
color = linear_fog(color);
|
||||||
|
#elif defined(FADE_FOG)
|
||||||
|
color = linear_fog_fade(color);
|
||||||
|
#endif
|
||||||
|
|
||||||
fragColor = color;
|
fragColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 FLWLight(vec2 lightCoords) {
|
|
||||||
return texture(uLightMap, shiftLight(lightCoords));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
mat4 rotate(vec3 axis, float angle) {
|
mat4 rotate(vec3 axis, float angle) {
|
||||||
float s = sin(angle);
|
float s = sin(angle);
|
||||||
float c = cos(angle);
|
float c = cos(angle);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#define PIOVER2 1.5707963268
|
#define PIOVER2 1.5707963268
|
||||||
|
|
||||||
vec4 quat(vec3 axis, float angle) {
|
vec4 quat(vec3 axis, float angle) {
|
||||||
|
|
Loading…
Reference in a new issue