mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-07 02:34:58 +01:00
Reduced to fragments
- Overhaul shader pipeline - Remove VertexType#getShaderHeader in favor of vertex-only "layout shaders" - Remove program specs in favor of vertex-only "instance shaders" - Add API GLSL headers for vertex and fragment shaders that store common values - Separate context shaders into vertex and fragment shader files - Improve import handling - Ensure imports are not added more than once - Change regex for import directives to be more in line with C-style directives - Move some classes and GLSL files
This commit is contained in:
parent
4c7b035f5d
commit
a11bf3537b
73 changed files with 476 additions and 700 deletions
|
@ -13,6 +13,8 @@ import com.jozufozu.flywheel.core.Models;
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
import com.jozufozu.flywheel.core.StitchedSprite;
|
import com.jozufozu.flywheel.core.StitchedSprite;
|
||||||
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
||||||
|
import com.jozufozu.flywheel.core.materials.InstanceShaders;
|
||||||
|
import com.jozufozu.flywheel.core.vertex.LayoutShaders;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
||||||
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
||||||
|
@ -73,6 +75,8 @@ public class Flywheel {
|
||||||
forgeEventBus.<ReloadRenderersEvent>addListener(ProgramCompiler::invalidateAll);
|
forgeEventBus.<ReloadRenderersEvent>addListener(ProgramCompiler::invalidateAll);
|
||||||
forgeEventBus.addListener(Models::onReload);
|
forgeEventBus.addListener(Models::onReload);
|
||||||
|
|
||||||
|
modEventBus.addListener(LayoutShaders::flwInit);
|
||||||
|
modEventBus.addListener(InstanceShaders::flwInit);
|
||||||
modEventBus.addListener(Contexts::flwInit);
|
modEventBus.addListener(Contexts::flwInit);
|
||||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||||
modEventBus.addListener(PartialModel::onModelBake);
|
modEventBus.addListener(PartialModel::onModelBake);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package com.jozufozu.flywheel.api.struct;
|
package com.jozufozu.flywheel.api.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public interface Instanced<S> extends StructType<S> {
|
public interface Instanced<S> extends StructType<S> {
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +11,5 @@ public interface Instanced<S> extends StructType<S> {
|
||||||
*/
|
*/
|
||||||
StructWriter<S> getWriter(VecBuffer backing);
|
StructWriter<S> getWriter(VecBuffer backing);
|
||||||
|
|
||||||
ResourceLocation getProgramSpec();
|
FileResolution getInstanceShader();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.jozufozu.flywheel.api.vertex;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A vertex type containing metadata about a specific vertex layout.
|
* A vertex type containing metadata about a specific vertex layout.
|
||||||
|
@ -32,7 +33,7 @@ public interface VertexType {
|
||||||
*/
|
*/
|
||||||
VertexList createReader(ByteBuffer buffer, int vertexCount);
|
VertexList createReader(ByteBuffer buffer, int vertexCount);
|
||||||
|
|
||||||
String getShaderHeader();
|
FileResolution getLayoutShader();
|
||||||
|
|
||||||
default int getStride() {
|
default int getStride() {
|
||||||
return getLayout().getStride();
|
return getLayout().getStride();
|
||||||
|
|
|
@ -8,11 +8,9 @@ import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine;
|
||||||
import com.jozufozu.flywheel.config.BackendType;
|
import com.jozufozu.flywheel.config.BackendType;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.core.shader.ProgramSpec;
|
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
|
||||||
|
@ -53,11 +51,6 @@ public class Backend {
|
||||||
return backendType == null ? "Uninitialized" : backendType.getProperName();
|
return backendType == null ? "Uninitialized" : backendType.getProperName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static ProgramSpec getSpec(ResourceLocation name) {
|
|
||||||
return loader.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void refresh() {
|
public static void refresh() {
|
||||||
backendType = chooseEngine();
|
backendType = chooseEngine();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,15 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.core.GameStateRegistry;
|
import com.jozufozu.flywheel.core.GameStateRegistry;
|
||||||
import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer;
|
import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer;
|
||||||
import com.jozufozu.flywheel.core.shader.ProgramSpec;
|
|
||||||
import com.jozufozu.flywheel.core.source.Resolver;
|
import com.jozufozu.flywheel.core.source.Resolver;
|
||||||
import com.jozufozu.flywheel.core.source.ShaderSources;
|
import com.jozufozu.flywheel.core.source.ShaderSources;
|
||||||
import com.jozufozu.flywheel.event.GatherContextEvent;
|
import com.jozufozu.flywheel.event.GatherContextEvent;
|
||||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
import com.mojang.serialization.DataResult;
|
|
||||||
import com.mojang.serialization.JsonOps;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||||
import net.minecraft.server.packs.resources.Resource;
|
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
||||||
import net.minecraftforge.fml.ModLoader;
|
import net.minecraftforge.fml.ModLoader;
|
||||||
|
@ -39,11 +22,6 @@ import net.minecraftforge.fml.ModLoader;
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class Loader implements ResourceManagerReloadListener {
|
public class Loader implements ResourceManagerReloadListener {
|
||||||
public static final String PROGRAM_DIR = "flywheel/programs/";
|
|
||||||
private static final Gson GSON = new GsonBuilder().create();
|
|
||||||
|
|
||||||
private final Map<ResourceLocation, ProgramSpec> programs = new HashMap<>();
|
|
||||||
|
|
||||||
private boolean firstLoad = true;
|
private boolean firstLoad = true;
|
||||||
|
|
||||||
Loader() {
|
Loader() {
|
||||||
|
@ -57,11 +35,6 @@ public class Loader implements ResourceManagerReloadListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public ProgramSpec get(ResourceLocation name) {
|
|
||||||
return programs.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResourceManagerReload(ResourceManager manager) {
|
public void onResourceManagerReload(ResourceManager manager) {
|
||||||
Backend.refresh();
|
Backend.refresh();
|
||||||
|
@ -74,8 +47,6 @@ public class Loader implements ResourceManagerReloadListener {
|
||||||
|
|
||||||
ShaderSources sources = new ShaderSources(manager);
|
ShaderSources sources = new ShaderSources(manager);
|
||||||
|
|
||||||
loadProgramSpecs(manager);
|
|
||||||
|
|
||||||
Resolver.INSTANCE.run(sources);
|
Resolver.INSTANCE.run(sources);
|
||||||
|
|
||||||
Backend.LOGGER.info("Loaded all shader sources.");
|
Backend.LOGGER.info("Loaded all shader sources.");
|
||||||
|
@ -89,35 +60,4 @@ public class Loader implements ResourceManagerReloadListener {
|
||||||
|
|
||||||
firstLoad = false;
|
firstLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadProgramSpecs(ResourceManager manager) {
|
|
||||||
programs.clear();
|
|
||||||
|
|
||||||
Collection<ResourceLocation> programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json"));
|
|
||||||
|
|
||||||
for (ResourceLocation location : programSpecs) {
|
|
||||||
try (Resource file = manager.getResource(location)) {
|
|
||||||
String s = StringUtil.readToString(file.getInputStream());
|
|
||||||
|
|
||||||
ResourceLocation specName = ResourceUtil.trim(location, PROGRAM_DIR, ".json");
|
|
||||||
|
|
||||||
DataResult<Pair<ProgramSpec, JsonElement>> result = ProgramSpec.CODEC.decode(JsonOps.INSTANCE, GSON.fromJson(s, JsonElement.class));
|
|
||||||
|
|
||||||
ProgramSpec spec = result.get()
|
|
||||||
.orThrow()
|
|
||||||
.getFirst();
|
|
||||||
|
|
||||||
spec.setName(specName);
|
|
||||||
|
|
||||||
if (programs.containsKey(specName)) {
|
|
||||||
throw new IllegalStateException("Program spec '" + specName + "' already registered.");
|
|
||||||
}
|
|
||||||
programs.put(specName, spec);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Backend.LOGGER.error("Could not load program " + location, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,20 @@ public class GlShader extends GlObject {
|
||||||
GlCompat.safeShaderSource(handle, source);
|
GlCompat.safeShaderSource(handle, source);
|
||||||
GL20.glCompileShader(handle);
|
GL20.glCompileShader(handle);
|
||||||
|
|
||||||
|
// File dir = new File(Minecraft.getInstance().gameDirectory, "flywheel_sources");
|
||||||
|
// dir.mkdirs();
|
||||||
|
// File file = new File(dir, name.toString().replaceAll("[:/]", "_"));
|
||||||
|
// try (FileWriter writer = new FileWriter(file)) {
|
||||||
|
// writer.write(source);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
// String log = GL20.glGetShaderInfoLog(handle);
|
// String log = GL20.glGetShaderInfoLog(handle);
|
||||||
//
|
//
|
||||||
// if (!log.isEmpty()) {
|
// if (!log.isEmpty()) {
|
||||||
// env.printShaderInfoLog(source, log, this.name);
|
// System.out.println(log);
|
||||||
|
//// env.printShaderInfoLog(source, log, this.name);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS) != GL20.GL_TRUE) {
|
if (GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS) != GL20.GL_TRUE) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.materials.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||||
|
|
|
@ -14,13 +14,14 @@ import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
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.RenderContext;
|
|
||||||
import com.jozufozu.flywheel.core.CoreShaderInfoMap;
|
import com.jozufozu.flywheel.core.CoreShaderInfoMap;
|
||||||
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
||||||
|
import com.jozufozu.flywheel.core.GameStateRegistry;
|
||||||
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
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.core.vertex.Formats;
|
||||||
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.blaze3d.systems.RenderSystem;
|
||||||
|
@ -32,7 +33,6 @@ import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.ShaderInstance;
|
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.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
|
|
||||||
public class InstancingEngine<P extends WorldProgram> implements Engine {
|
public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
|
@ -118,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(instanceType.getProgramSpec(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
setup(instanceType, coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
||||||
|
|
||||||
instanceCount += material.getInstanceCount();
|
instanceCount += material.getInstanceCount();
|
||||||
vertexCount += material.getVertexCount();
|
vertexCount += material.getVertexCount();
|
||||||
|
@ -145,7 +145,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
return coreShaderInfo;
|
return coreShaderInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected P setup(ResourceLocation programSpec, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
|
protected P setup(Instanced<?> instanceType, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
|
||||||
float alphaDiscard = coreShaderInfo.alphaDiscard();
|
float alphaDiscard = coreShaderInfo.alphaDiscard();
|
||||||
if (alphaDiscard == 0) {
|
if (alphaDiscard == 0) {
|
||||||
alphaDiscard = 0.0001f;
|
alphaDiscard = 0.0001f;
|
||||||
|
@ -153,7 +153,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
alphaDiscard = 0;
|
alphaDiscard = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
P program = context.getProgram(ProgramContext.create(programSpec, Formats.POS_TEX_NORMAL, alphaDiscard, coreShaderInfo.fogType()));
|
P program = context.getProgram(new ProgramContext(Formats.POS_TEX_NORMAL, instanceType.getInstanceShader(), alphaDiscard, coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
||||||
|
|
|
@ -20,11 +20,13 @@ public class Contexts {
|
||||||
public static void flwInit(GatherContextEvent event) {
|
public static void flwInit(GatherContextEvent event) {
|
||||||
GameStateRegistry.register(NormalDebugStateProvider.INSTANCE);
|
GameStateRegistry.register(NormalDebugStateProvider.INSTANCE);
|
||||||
|
|
||||||
FileResolution worldBuiltins = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.WORLD, ".glsl"));
|
FileResolution worldVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.WORLD, ".vert"));
|
||||||
FileResolution crumblingBuiltins = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".glsl"));
|
FileResolution worldFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.WORLD, ".frag"));
|
||||||
|
FileResolution crumblingVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".vert"));
|
||||||
|
FileResolution crumblingFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".frag"));
|
||||||
|
|
||||||
WORLD = ProgramCompiler.create(Templates.INSTANCING, WorldProgram::new, worldBuiltins);
|
WORLD = ProgramCompiler.create(WorldProgram::new, Templates.INSTANCING, Templates.FRAGMENT, worldVertex, worldFragment);
|
||||||
CRUMBLING = ProgramCompiler.create(Templates.INSTANCING, CrumblingProgram::new, crumblingBuiltins);
|
CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, Templates.INSTANCING, Templates.FRAGMENT, crumblingVertex, crumblingFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static class Names {
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class Programs {
|
|
||||||
public static final ResourceLocation TRANSFORMED = Flywheel.rl("model");
|
|
||||||
public static final ResourceLocation ORIENTED = Flywheel.rl("oriented");
|
|
||||||
}
|
|
|
@ -12,12 +12,11 @@ public class CompileUtil {
|
||||||
public static final Pattern matType = Pattern.compile("^mat([234])(?:x([234]))?$");
|
public static final Pattern matType = Pattern.compile("^mat([234])(?:x([234]))?$");
|
||||||
|
|
||||||
protected static String generateHeader(GLSLVersion version, ShaderType type) {
|
protected static String generateHeader(GLSLVersion version, ShaderType type) {
|
||||||
return "#version "
|
return "#version " + version + '\n'
|
||||||
+ version
|
|
||||||
+ '\n'
|
|
||||||
+ "#extension GL_ARB_explicit_attrib_location : enable\n"
|
+ "#extension GL_ARB_explicit_attrib_location : enable\n"
|
||||||
+ "#extension GL_ARB_conservative_depth : enable\n"
|
+ "#extension GL_ARB_conservative_depth : enable\n"
|
||||||
+ type.getDefineStatement();
|
+ type.getDefineStatement()
|
||||||
|
+ '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getElementCount(String type) {
|
public static int getElementCount(String type) {
|
||||||
|
|
|
@ -9,15 +9,14 @@ 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;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
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 Template<? extends FragmentData> template;
|
||||||
private final FileResolution header;
|
private final FileResolution contextShader;
|
||||||
|
|
||||||
public FragmentCompiler(Template<? extends FragmentData> template, FileResolution header) {
|
public FragmentCompiler(Template<? extends FragmentData> template, FileResolution contextShader) {
|
||||||
this.header = header;
|
|
||||||
this.template = template;
|
this.template = template;
|
||||||
|
this.contextShader = contextShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,16 +26,16 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.FRAGMENT));
|
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.FRAGMENT));
|
||||||
|
|
||||||
key.getShaderConstants().writeInto(finalSource);
|
key.getShaderConstants().writeInto(finalSource);
|
||||||
|
finalSource.append('\n');
|
||||||
|
|
||||||
FileIndexImpl index = new FileIndexImpl();
|
FileIndexImpl index = new FileIndexImpl();
|
||||||
|
|
||||||
header.getFile().generateFinalSource(index, finalSource);
|
contextShader.getFile().generateFinalSource(index, finalSource);
|
||||||
key.file.generateFinalSource(index, finalSource);
|
|
||||||
|
|
||||||
FragmentData appliedTemplate = template.apply(key.file);
|
FragmentData appliedTemplate = template.apply(contextShader.getFile());
|
||||||
finalSource.append(appliedTemplate.generateFooter());
|
finalSource.append(appliedTemplate.generateFooter());
|
||||||
|
|
||||||
return new GlShader(key.file.name, ShaderType.FRAGMENT, finalSource.toString());
|
return new GlShader(contextShader.getFile().name, ShaderType.FRAGMENT, finalSource.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,11 +47,6 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
* Represents the conditions under which a shader is compiled.
|
* Represents the conditions under which a shader is compiled.
|
||||||
*/
|
*/
|
||||||
public static final class Context {
|
public static final class Context {
|
||||||
/**
|
|
||||||
* The file to compile.
|
|
||||||
*/
|
|
||||||
private final SourceFile file;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The shader constants to apply.
|
* The shader constants to apply.
|
||||||
*/
|
*/
|
||||||
|
@ -68,11 +62,10 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
*/
|
*/
|
||||||
private final FogType fogType;
|
private final FogType fogType;
|
||||||
|
|
||||||
public Context(SourceFile file, StateSnapshot ctx, float alphaDiscard, FogType fogType) {
|
public Context(float alphaDiscard, FogType fogType, StateSnapshot ctx) {
|
||||||
this.file = file;
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.alphaDiscard = alphaDiscard;
|
this.alphaDiscard = alphaDiscard;
|
||||||
this.fogType = fogType;
|
this.fogType = fogType;
|
||||||
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderConstants getShaderConstants() {
|
public ShaderConstants getShaderConstants() {
|
||||||
|
@ -91,17 +84,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) && fogType == that.fogType;
|
return 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, fogType);
|
return Objects.hash(alphaDiscard, fogType, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Context[" + "file=" + file + ", " + "ctx=" + ctx + ", " + "alphaDiscard=" + alphaDiscard + ", " + "fogType=" + fogType + ']';
|
return "Context[" + "alphaDiscard=" + alphaDiscard + ", " + "fogType=" + fogType + ", " + "ctx=" + ctx + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,85 +3,46 @@ package com.jozufozu.flywheel.core.compile;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.jozufozu.flywheel.core.source.ShaderLoadingException;
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
import com.jozufozu.flywheel.core.source.SourceFile;
|
||||||
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
||||||
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
||||||
import com.jozufozu.flywheel.core.source.parse.ShaderStruct;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.StructField;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.Variable;
|
import com.jozufozu.flywheel.core.source.parse.Variable;
|
||||||
import com.jozufozu.flywheel.core.source.span.Span;
|
|
||||||
|
|
||||||
public class FragmentTemplateData implements FragmentData {
|
public class FragmentTemplateData implements FragmentData {
|
||||||
public final SourceFile file;
|
public final SourceFile file;
|
||||||
public final Span interpolantName;
|
public final ShaderFunction contextFragment;
|
||||||
public final ShaderStruct interpolant;
|
|
||||||
public final ShaderFunction fragmentMain;
|
|
||||||
|
|
||||||
public FragmentTemplateData(SourceFile file) {
|
public FragmentTemplateData(SourceFile file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
|
||||||
Optional<ShaderFunction> maybeFragmentMain = file.findFunction("fragment");
|
Optional<ShaderFunction> maybeContextFragment = file.findFunction("flw_contextFragment");
|
||||||
|
|
||||||
if (maybeFragmentMain.isEmpty()) {
|
if (maybeContextFragment.isEmpty()) {
|
||||||
ErrorReporter.generateMissingFunction(file, "fragment", "\"fragment\" function not defined");
|
ErrorReporter.generateMissingFunction(file, "flw_contextFragment", "\"flw_contextFragment\" function not defined");
|
||||||
throw new RuntimeException();
|
throw new ShaderLoadingException();
|
||||||
}
|
}
|
||||||
|
|
||||||
fragmentMain = maybeFragmentMain.get();
|
contextFragment = maybeContextFragment.get();
|
||||||
ImmutableList<Variable> fragmentParameters = fragmentMain.getParameters();
|
ImmutableList<Variable> params = contextFragment.getParameters();
|
||||||
|
|
||||||
if (fragmentParameters.size() != 1) {
|
if (params.size() != 0) {
|
||||||
ErrorReporter.generateSpanError(fragmentMain.getArgs(), "fragment function must have exactly one argument");
|
ErrorReporter.generateSpanError(contextFragment.getArgs(), "\"flw_contextFragment\" function must not have any arguments");
|
||||||
throw new RuntimeException();
|
throw new ShaderLoadingException();
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolantName = fragmentMain.getParameters().get(0).type;
|
|
||||||
|
|
||||||
Optional<ShaderStruct> maybeInterpolant = file.findStruct(interpolantName);
|
|
||||||
|
|
||||||
if (maybeInterpolant.isEmpty()) {
|
|
||||||
ErrorReporter.generateMissingStruct(file, interpolantName, "struct not defined");
|
|
||||||
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
interpolant = maybeInterpolant.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateFooter() {
|
public String generateFooter() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
prefixFields(builder, interpolant, "in", "v2f_");
|
|
||||||
|
|
||||||
builder.append(String.format("""
|
builder.append("""
|
||||||
void main() {
|
void main() {
|
||||||
Fragment o;
|
flw_contextFragment();
|
||||||
o.color = v2f_color;
|
|
||||||
o.texCoords = v2f_texCoords;
|
|
||||||
o.light = v2f_light;
|
|
||||||
o.diffuse = v2f_diffuse;
|
|
||||||
|
|
||||||
vec4 color = %s;
|
|
||||||
FLWFinalizeColor(color);
|
|
||||||
}
|
}
|
||||||
""",
|
"""
|
||||||
fragmentMain.call("o")
|
);
|
||||||
));
|
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void prefixFields(StringBuilder builder, ShaderStruct struct, String qualifier, String prefix) {
|
|
||||||
ImmutableList<StructField> fields = struct.getFields();
|
|
||||||
|
|
||||||
for (StructField field : fields) {
|
|
||||||
builder.append(qualifier)
|
|
||||||
.append(' ')
|
|
||||||
.append(field.type)
|
|
||||||
.append(' ')
|
|
||||||
.append(prefix)
|
|
||||||
.append(field.name)
|
|
||||||
.append(";\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,45 +15,30 @@ import com.jozufozu.flywheel.core.source.parse.Variable;
|
||||||
import com.jozufozu.flywheel.core.source.span.Span;
|
import com.jozufozu.flywheel.core.source.span.Span;
|
||||||
|
|
||||||
public class InstancingTemplateData implements VertexData {
|
public class InstancingTemplateData implements VertexData {
|
||||||
|
|
||||||
public final SourceFile file;
|
public final SourceFile file;
|
||||||
public final ShaderFunction vertexMain;
|
public final ShaderFunction instanceVertex;
|
||||||
public final Span vertexName;
|
|
||||||
public final Span instanceName;
|
public final Span instanceName;
|
||||||
public final ShaderStruct instance;
|
public final ShaderStruct instance;
|
||||||
|
|
||||||
public InstancingTemplateData(SourceFile file) {
|
public InstancingTemplateData(SourceFile file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
|
||||||
Optional<ShaderFunction> vertexFunc = file.findFunction("vertex");
|
Optional<ShaderFunction> maybeInstanceVertex = file.findFunction("flw_instanceVertex");
|
||||||
|
|
||||||
if (vertexFunc.isEmpty()) {
|
if (maybeInstanceVertex.isEmpty()) {
|
||||||
ErrorReporter.generateFileError(file, "could not find \"vertex\" function");
|
ErrorReporter.generateMissingFunction(file, "flw_instanceVertex", "\"flw_instanceVertex\" function not defined");
|
||||||
throw new ShaderLoadingException();
|
throw new ShaderLoadingException();
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexMain = vertexFunc.get();
|
instanceVertex = maybeInstanceVertex.get();
|
||||||
ImmutableList<Variable> vertexParams = vertexMain.getParameters();
|
ImmutableList<Variable> params = instanceVertex.getParameters();
|
||||||
|
|
||||||
if (vertexParams.size() != 2) {
|
if (params.size() != 1) {
|
||||||
ErrorReporter.generateSpanError(vertexMain.getArgs(), "instancing requires vertex function to have 2 arguments");
|
ErrorReporter.generateSpanError(instanceVertex.getArgs(), "\"flw_contextFragment\" function must have exactly 1 argument");
|
||||||
throw new ShaderLoadingException();
|
throw new ShaderLoadingException();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable vertexParam = vertexParams.get(0);
|
instanceName = params.get(0).type;
|
||||||
vertexName = vertexParam.type;
|
|
||||||
|
|
||||||
boolean namedVertex = vertexParam.type
|
|
||||||
.toString()
|
|
||||||
.equals("Vertex");
|
|
||||||
|
|
||||||
if (!(namedVertex && vertexParam.qualifier == Variable.Qualifier.INOUT)) {
|
|
||||||
ErrorReporter.generateSpanError(vertexParam.qualifierSpan, "first parameter must be inout Vertex");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceName = vertexParams.get(1).type;
|
|
||||||
|
|
||||||
Optional<ShaderStruct> maybeInstance = file.findStruct(instanceName);
|
Optional<ShaderStruct> maybeInstance = file.findStruct(instanceName);
|
||||||
|
|
||||||
if (maybeInstance.isEmpty()) {
|
if (maybeInstance.isEmpty()) {
|
||||||
|
@ -80,36 +65,26 @@ public class InstancingTemplateData implements VertexData {
|
||||||
.append(' ')
|
.append(' ')
|
||||||
.append(field.type)
|
.append(field.type)
|
||||||
.append(' ')
|
.append(' ')
|
||||||
.append("a_i_")
|
.append("_flw_a_i_")
|
||||||
.append(field.name)
|
.append(field.name)
|
||||||
.append(";\n");
|
.append(";\n");
|
||||||
attributeBinding += CompileUtil.getAttributeCount(field.type);
|
attributeBinding += CompileUtil.getAttributeCount(field.type);
|
||||||
}
|
}
|
||||||
|
template.append('\n');
|
||||||
|
|
||||||
template.append(String.format("""
|
template.append(String.format("""
|
||||||
out vec4 v2f_color;
|
|
||||||
out vec2 v2f_texCoords;
|
|
||||||
out vec2 v2f_light;
|
|
||||||
out float v2f_diffuse;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
Vertex v = FLWCreateVertex();
|
flw_layoutVertex();
|
||||||
%s i;
|
|
||||||
%s
|
|
||||||
vertex(v, i);
|
|
||||||
gl_Position = FLWVertex(v);
|
|
||||||
v.normal = normalize(v.normal);
|
|
||||||
|
|
||||||
v2f_color = v.color;
|
%s instance;
|
||||||
v2f_texCoords = v.texCoords;
|
%s
|
||||||
v2f_light = v.light;
|
flw_instanceVertex(instance);
|
||||||
v2f_diffuse = FLWDiffuse(v.normal);
|
|
||||||
#if defined(DEBUG_NORMAL)
|
flw_contextVertex();
|
||||||
v2f_color = vec4(v.normal, 1.);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
instanceName,
|
instanceName,
|
||||||
assignFields(instance, "i.", "a_i_")
|
assignFields(instance, "instance.", "_flw_a_i_")
|
||||||
));
|
));
|
||||||
|
|
||||||
return template.toString();
|
return template.toString();
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.core.Templates;
|
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
|
||||||
|
@ -33,15 +32,17 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a program compiler using this template.
|
* Creates a program compiler using provided templates and headers.
|
||||||
* @param template The vertex template to use.
|
|
||||||
* @param factory A factory to add meaning to compiled programs.
|
* @param factory A factory to add meaning to compiled programs.
|
||||||
* @param header The header file to use for the program.
|
* @param vertexTemplate The vertex template to use.
|
||||||
|
* @param fragmentTemplate The fragment template to use.
|
||||||
|
* @param vertexContextShader The context shader to use when compiling vertex shaders.
|
||||||
|
* @param fragmentContextShader The context shader to use when compiling fragment shaders.
|
||||||
* @param <P> The type of program to compile.
|
* @param <P> The type of program to compile.
|
||||||
* @return A program compiler.
|
* @return A program compiler.
|
||||||
*/
|
*/
|
||||||
public static <T extends VertexData, P extends GlProgram> ProgramCompiler<P> create(Template<T> template, GlProgram.Factory<P> factory, FileResolution header) {
|
public static <V extends VertexData, F extends FragmentData, P extends GlProgram> ProgramCompiler<P> create(GlProgram.Factory<P> factory, Template<V> vertexTemplate, Template<F> fragmentTemplate, FileResolution vertexContextShader, FileResolution fragmentContextShader) {
|
||||||
return new ProgramCompiler<>(factory, new VertexCompiler(template, header), new FragmentCompiler(Templates.FRAGMENT, header));
|
return new ProgramCompiler<>(factory, new VertexCompiler(vertexTemplate, vertexContextShader), new FragmentCompiler(fragmentTemplate, fragmentContextShader));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,9 +64,9 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected P _create(ProgramContext ctx) {
|
protected P _create(ProgramContext ctx) {
|
||||||
return new ProgramAssembler(ctx.spec.name)
|
return new ProgramAssembler(ctx.instanceShader.getFileLoc())
|
||||||
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.spec.getVertexFile(), ctx.ctx, ctx.vertexType)))
|
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.vertexType, ctx.instanceShader.getFile(), ctx.ctx)))
|
||||||
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.spec.getFragmentFile(), ctx.ctx, ctx.alphaDiscard, ctx.fogType)))
|
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.alphaDiscard, ctx.fogType, ctx.ctx)))
|
||||||
.link()
|
.link()
|
||||||
.build(this.factory);
|
.build(this.factory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,54 +3,33 @@ package com.jozufozu.flywheel.core.compile;
|
||||||
import java.util.Objects;
|
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.core.CoreShaderInfoMap.CoreShaderInfo.FogType;
|
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;
|
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the entire context of a program's usage.
|
* Represents the entire context of a program's usage.
|
||||||
*/
|
*/
|
||||||
public final class ProgramContext {
|
public final class ProgramContext {
|
||||||
/**
|
|
||||||
* Creates a compilation context for the given program, vertex type and render layer.
|
|
||||||
*
|
|
||||||
* @param programName The name of the program to use.
|
|
||||||
* @param vertexType The vertex type to use.
|
|
||||||
* @param alphaDiscard The alpha threshold below which pixels are discarded.
|
|
||||||
* @return A compilation context.
|
|
||||||
*/
|
|
||||||
public static ProgramContext create(ResourceLocation programName, VertexType vertexType, float alphaDiscard, FogType fogType) {
|
|
||||||
ProgramSpec spec = Backend.getSpec(programName);
|
|
||||||
|
|
||||||
if (spec == null) {
|
public final VertexType vertexType;
|
||||||
throw new NullPointerException("Cannot compile shader because '" + programName + "' is not recognized.");
|
public final FileResolution instanceShader;
|
||||||
}
|
|
||||||
|
|
||||||
return new ProgramContext(spec, alphaDiscard, fogType, vertexType, GameStateRegistry.takeSnapshot());
|
|
||||||
}
|
|
||||||
|
|
||||||
public final ProgramSpec spec;
|
|
||||||
public final float alphaDiscard;
|
public final float alphaDiscard;
|
||||||
public final FogType fogType;
|
public final FogType fogType;
|
||||||
public final VertexType vertexType;
|
|
||||||
public final StateSnapshot ctx;
|
public final StateSnapshot ctx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param vertexType The vertexType the program should be adapted for.
|
||||||
* @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 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.
|
* @param ctx A snapshot of the game state.
|
||||||
*/
|
*/
|
||||||
public ProgramContext(ProgramSpec spec, float alphaDiscard, FogType fogType, VertexType vertexType, StateSnapshot ctx) {
|
public ProgramContext(VertexType vertexType, FileResolution instanceShader, float alphaDiscard, FogType fogType, StateSnapshot ctx) {
|
||||||
this.spec = spec;
|
this.vertexType = vertexType;
|
||||||
|
this.instanceShader = instanceShader;
|
||||||
this.alphaDiscard = alphaDiscard;
|
this.alphaDiscard = alphaDiscard;
|
||||||
this.fogType = fogType;
|
this.fogType = fogType;
|
||||||
this.vertexType = vertexType;
|
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,16 +38,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) && fogType == that.fogType;
|
return instanceShader == that.instanceShader && 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, fogType, vertexType, ctx);
|
return Objects.hash(vertexType, instanceShader, alphaDiscard, fogType, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ProgramContext{" + "spec=" + spec + ", alphaDiscard=" + alphaDiscard + ", fogType=" + fogType + ", vertexType=" + vertexType + ", ctx=" + ctx + '}';
|
return "ProgramContext{" + "vertexType=" + vertexType + ", instanceShader=" + instanceShader + ", alphaDiscard=" + alphaDiscard + ", fogType=" + fogType + ", ctx=" + ctx + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,11 @@ import com.jozufozu.flywheel.core.source.SourceFile;
|
||||||
|
|
||||||
public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
private final Template<? extends VertexData> template;
|
private final Template<? extends VertexData> template;
|
||||||
private final FileResolution header;
|
private final FileResolution contextShader;
|
||||||
|
|
||||||
public VertexCompiler(Template<? extends VertexData> template, FileResolution header) {
|
public VertexCompiler(Template<? extends VertexData> template, FileResolution contextShader) {
|
||||||
this.template = template;
|
this.template = template;
|
||||||
this.header = header;
|
this.contextShader = contextShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,28 +26,21 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.VERTEX));
|
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.VERTEX));
|
||||||
|
|
||||||
key.ctx.getShaderConstants().writeInto(finalSource);
|
key.ctx.getShaderConstants().writeInto(finalSource);
|
||||||
|
finalSource.append('\n');
|
||||||
finalSource.append("""
|
|
||||||
struct Vertex {
|
|
||||||
vec3 pos;
|
|
||||||
vec4 color;
|
|
||||||
vec2 texCoords;
|
|
||||||
vec2 light;
|
|
||||||
vec3 normal;
|
|
||||||
};
|
|
||||||
""");
|
|
||||||
finalSource.append(key.vertexType.getShaderHeader());
|
|
||||||
|
|
||||||
FileIndexImpl index = new FileIndexImpl();
|
FileIndexImpl index = new FileIndexImpl();
|
||||||
|
|
||||||
header.getFile().generateFinalSource(index, finalSource);
|
FileResolution layoutShader = key.vertexType.getLayoutShader();
|
||||||
|
layoutShader.getFile().generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
key.file.generateFinalSource(index, finalSource);
|
contextShader.getFile().generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
VertexData appliedTemplate = template.apply(key.file);
|
key.instanceShader.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
VertexData appliedTemplate = template.apply(key.instanceShader);
|
||||||
finalSource.append(appliedTemplate.generateFooter(index, key.vertexType));
|
finalSource.append(appliedTemplate.generateFooter(index, key.vertexType));
|
||||||
|
|
||||||
return new GlShader(key.file.name, ShaderType.VERTEX, finalSource.toString());
|
return new GlShader(key.instanceShader.name, ShaderType.VERTEX, finalSource.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,24 +50,24 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
|
|
||||||
public static class Context {
|
public static class Context {
|
||||||
/**
|
/**
|
||||||
* The file to compile.
|
* The vertex type to use.
|
||||||
*/
|
*/
|
||||||
private final SourceFile file;
|
private final VertexType vertexType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The instance shader source.
|
||||||
|
*/
|
||||||
|
private final SourceFile instanceShader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The shader constants to apply.
|
* The shader constants to apply.
|
||||||
*/
|
*/
|
||||||
private final StateSnapshot ctx;
|
private final StateSnapshot ctx;
|
||||||
|
|
||||||
/**
|
public Context(VertexType vertexType, SourceFile instanceShader, StateSnapshot ctx) {
|
||||||
* The vertex type to use.
|
|
||||||
*/
|
|
||||||
private final VertexType vertexType;
|
|
||||||
|
|
||||||
public Context(SourceFile file, StateSnapshot ctx, VertexType vertexType) {
|
|
||||||
this.file = file;
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.vertexType = vertexType;
|
this.vertexType = vertexType;
|
||||||
|
this.instanceShader = instanceShader;
|
||||||
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -82,12 +75,12 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
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 = (Context) o;
|
var that = (Context) o;
|
||||||
return file == that.file && vertexType == that.vertexType && ctx.equals(that.ctx);
|
return vertexType == that.vertexType && instanceShader == that.instanceShader && ctx.equals(that.ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(file, ctx, vertexType);
|
return Objects.hash(vertexType, instanceShader, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@ import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterial;
|
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.CoreShaderInfoMap.CoreShaderInfo;
|
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
||||||
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
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;
|
||||||
|
@ -191,7 +191,7 @@ public class CrumblingRenderer {
|
||||||
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
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(entry.getKey().getProgramSpec(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
CrumblingProgram program = setup(entry.getKey(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
||||||
|
|
||||||
program.setAtlasSize(width, height);
|
program.setAtlasSize(width, height);
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.jozufozu.flywheel.core.hardcoded;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
|
import com.jozufozu.flywheel.core.vertex.Formats;
|
||||||
import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex;
|
import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex;
|
||||||
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
|
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
|
||||||
import com.mojang.blaze3d.platform.MemoryTracker;
|
import com.mojang.blaze3d.platform.MemoryTracker;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.jozufozu.flywheel.core.materials;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.source.Resolver;
|
||||||
|
import com.jozufozu.flywheel.event.GatherContextEvent;
|
||||||
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
public class InstanceShaders {
|
||||||
|
public static FileResolution MODEL;
|
||||||
|
public static FileResolution ORIENTED;
|
||||||
|
|
||||||
|
public static void flwInit(GatherContextEvent event) {
|
||||||
|
MODEL = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.MODEL, ".vert"));
|
||||||
|
ORIENTED = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.ORIENTED, ".vert"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Names {
|
||||||
|
public static final ResourceLocation MODEL = Flywheel.rl("instance/model");
|
||||||
|
public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,12 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core.materials;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelType;
|
import com.jozufozu.flywheel.core.materials.model.ModelType;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedType;
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedType;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class Materials {
|
public class Materials {
|
||||||
|
|
||||||
public static final StructType<OrientedData> ORIENTED = new OrientedType();
|
|
||||||
public static final StructType<ModelData> TRANSFORMED = new ModelType();
|
public static final StructType<ModelData> TRANSFORMED = new ModelType();
|
||||||
|
public static final StructType<OrientedData> ORIENTED = new OrientedType();
|
||||||
public static class Names {
|
|
||||||
public static final ResourceLocation MODEL = Flywheel.rl("model");
|
|
||||||
public static final ResourceLocation ORIENTED = Flywheel.rl("oriented");
|
|
||||||
public static final ResourceLocation PASSTHRU = Flywheel.rl("passthru");
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -4,12 +4,11 @@ import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.Programs;
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
|
import com.jozufozu.flywheel.core.materials.InstanceShaders;
|
||||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
|
public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
|
||||||
|
|
||||||
|
@ -34,8 +33,8 @@ public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation getProgramSpec() {
|
public FileResolution getInstanceShader() {
|
||||||
return Programs.TRANSFORMED;
|
return InstanceShaders.MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,14 +4,13 @@ import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.Programs;
|
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
|
import com.jozufozu.flywheel.core.materials.InstanceShaders;
|
||||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class OrientedType implements Instanced<OrientedData>, Batched<OrientedData> {
|
public class OrientedType implements Instanced<OrientedData>, Batched<OrientedData> {
|
||||||
|
|
||||||
public static final BufferLayout FORMAT = BufferLayout.builder()
|
public static final BufferLayout FORMAT = BufferLayout.builder()
|
||||||
|
@ -35,8 +34,8 @@ public class OrientedType implements Instanced<OrientedData>, Batched<OrientedDa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation getProgramSpec() {
|
public FileResolution getInstanceShader() {
|
||||||
return Programs.ORIENTED;
|
return InstanceShaders.ORIENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.jozufozu.flywheel.core.model;
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
|
import com.jozufozu.flywheel.core.vertex.Formats;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.Random;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
import com.jozufozu.flywheel.core.vertex.Formats;
|
||||||
import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter;
|
import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.shader;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
|
||||||
import com.jozufozu.flywheel.core.source.Resolver;
|
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
|
||||||
import com.mojang.serialization.Codec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An object describing a shader program that can be loaded by flywheel.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* These are defined through json. All ProgramSpecs in {@code assets/modid/flywheel/programs} are parsed and
|
|
||||||
* processed. One ProgramSpec typically specifies one "material" that can be used in game to render things.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* All shader source files in {@code assets/modid/flywheel/shaders} are completely loaded and parsed into
|
|
||||||
* {@link SourceFile SourceFiles}, but not compiled until one of them is
|
|
||||||
* referenced by a ProgramSpec.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class ProgramSpec {
|
|
||||||
|
|
||||||
public static final Codec<ProgramSpec> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
|
||||||
ResourceLocation.CODEC.fieldOf("vertex")
|
|
||||||
.forGetter(ProgramSpec::getSourceLoc),
|
|
||||||
ResourceLocation.CODEC.fieldOf("fragment")
|
|
||||||
.forGetter(ProgramSpec::getFragmentLoc))
|
|
||||||
.apply(instance, ProgramSpec::new));
|
|
||||||
|
|
||||||
public ResourceLocation name;
|
|
||||||
public final FileResolution vertex;
|
|
||||||
public final FileResolution fragment;
|
|
||||||
|
|
||||||
public ProgramSpec(ResourceLocation vertex, ResourceLocation fragment) {
|
|
||||||
this.vertex = Resolver.INSTANCE.get(vertex);
|
|
||||||
this.fragment = Resolver.INSTANCE.get(fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(ResourceLocation name) {
|
|
||||||
this.name = name;
|
|
||||||
this.vertex.addSpec(name);
|
|
||||||
this.fragment.addSpec(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceLocation getSourceLoc() {
|
|
||||||
return vertex.getFileLoc();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceLocation getFragmentLoc() {
|
|
||||||
return fragment.getFileLoc();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceFile getVertexFile() {
|
|
||||||
return vertex.getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceFile getFragmentFile() {
|
|
||||||
return fragment.getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,6 +11,8 @@ public interface FileIndex {
|
||||||
*/
|
*/
|
||||||
int getFileID(SourceFile sourceFile);
|
int getFileID(SourceFile sourceFile);
|
||||||
|
|
||||||
|
boolean exists(SourceFile sourceFile);
|
||||||
|
|
||||||
SourceFile getFile(int fileID);
|
SourceFile getFile(int fileID);
|
||||||
|
|
||||||
default Span getLineSpan(int fileId, int lineNo) {
|
default Span getLineSpan(int fileId, int lineNo) {
|
||||||
|
|
|
@ -31,12 +31,16 @@ public class FileIndexImpl implements FileIndex {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean exists(SourceFile sourceFile) {
|
||||||
|
return files.indexOf(sourceFile) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SourceFile getFile(int fileId) {
|
public SourceFile getFile(int fileId) {
|
||||||
return files.get(fileId);
|
return files.get(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void printShaderInfoLog(String source, String log, ResourceLocation name) {
|
public void printShaderInfoLog(String source, String log, ResourceLocation name) {
|
||||||
List<String> lines = log.lines()
|
List<String> lines = log.lines()
|
||||||
.toList();
|
.toList();
|
||||||
|
|
|
@ -93,4 +93,9 @@ public class FileResolution {
|
||||||
extraCrashInfoProviders.clear();
|
extraCrashInfoProviders.clear();
|
||||||
file = null;
|
file = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FileResolution[" + fileLoc + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ public class ShaderSources implements SourceFinder {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public SourceFile findSource(ResourceLocation name) {
|
public SourceFile findSource(ResourceLocation name) {
|
||||||
|
|
||||||
return shaderSources.get(name);
|
return shaderSources.get(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ package com.jozufozu.flywheel.core.source;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -27,10 +28,6 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class SourceFile {
|
public class SourceFile {
|
||||||
private static final Pattern includePattern = Pattern.compile("#use \"(.*)\"");
|
|
||||||
|
|
||||||
// https://regexr.com/60n3d
|
|
||||||
public static final Pattern functionDeclaration = Pattern.compile("(\\w+)\\s+(\\w+)\\s*\\(([\\w,\\s]*)\\)\\s*\\{");
|
|
||||||
|
|
||||||
public final ResourceLocation name;
|
public final ResourceLocation name;
|
||||||
|
|
||||||
|
@ -141,15 +138,20 @@ public class SourceFile {
|
||||||
for (Import include : imports) {
|
for (Import include : imports) {
|
||||||
SourceFile file = include.getFile();
|
SourceFile file = include.getFile();
|
||||||
|
|
||||||
if (file != null) file.generateFinalSource(env, source);
|
if (file != null && !env.exists(file)) {
|
||||||
|
file.generateFinalSource(env, source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source.append("#line ")
|
source.append("#line ")
|
||||||
.append(0)
|
.append(0)
|
||||||
.append(' ')
|
.append(' ')
|
||||||
.append(env.getFileID(this))
|
.append(env.getFileID(this))
|
||||||
|
.append(" // ")
|
||||||
|
.append(name)
|
||||||
.append('\n');
|
.append('\n');
|
||||||
source.append(elided);
|
source.append(elided);
|
||||||
|
source.append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
public String printSource() {
|
public String printSource() {
|
||||||
|
@ -176,7 +178,7 @@ public class SourceFile {
|
||||||
* Scan the source for function definitions and "parse" them into objects that contain properties of the function.
|
* Scan the source for function definitions and "parse" them into objects that contain properties of the function.
|
||||||
*/
|
*/
|
||||||
private ImmutableMap<String, ShaderFunction> parseFunctions() {
|
private ImmutableMap<String, ShaderFunction> parseFunctions() {
|
||||||
Matcher matcher = functionDeclaration.matcher(source);
|
Matcher matcher = ShaderFunction.functionDeclaration.matcher(source);
|
||||||
|
|
||||||
Map<String, ShaderFunction> functions = new HashMap<>();
|
Map<String, ShaderFunction> functions = new HashMap<>();
|
||||||
|
|
||||||
|
@ -210,7 +212,7 @@ public class SourceFile {
|
||||||
* Scan the source for function definitions and "parse" them into objects that contain properties of the function.
|
* Scan the source for function definitions and "parse" them into objects that contain properties of the function.
|
||||||
*/
|
*/
|
||||||
private ImmutableMap<String, ShaderStruct> parseStructs() {
|
private ImmutableMap<String, ShaderStruct> parseStructs() {
|
||||||
Matcher matcher = ShaderStruct.struct.matcher(source);
|
Matcher matcher = ShaderStruct.PATTERN.matcher(source);
|
||||||
|
|
||||||
ImmutableMap.Builder<String, ShaderStruct> structs = ImmutableMap.builder();
|
ImmutableMap.Builder<String, ShaderStruct> structs = ImmutableMap.builder();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
|
@ -232,15 +234,22 @@ public class SourceFile {
|
||||||
* @param elisions
|
* @param elisions
|
||||||
*/
|
*/
|
||||||
private ImmutableList<Import> parseImports(List<Span> elisions) {
|
private ImmutableList<Import> parseImports(List<Span> elisions) {
|
||||||
Matcher uses = includePattern.matcher(source);
|
Matcher uses = Import.PATTERN.matcher(source);
|
||||||
|
|
||||||
|
Set<String> importedFiles = new HashSet<>();
|
||||||
List<Import> imports = new ArrayList<>();
|
List<Import> imports = new ArrayList<>();
|
||||||
|
|
||||||
while (uses.find()) {
|
while (uses.find()) {
|
||||||
Span use = Span.fromMatcher(this, uses);
|
Span use = Span.fromMatcher(this, uses);
|
||||||
Span file = Span.fromMatcher(this, uses, 1);
|
Span file = Span.fromMatcher(this, uses, 1);
|
||||||
|
|
||||||
imports.add(new Import(Resolver.INSTANCE, use, file));
|
String fileName = file.get();
|
||||||
|
if (importedFiles.add(fileName)) {
|
||||||
|
Import import1 = Import.create(Resolver.INSTANCE, use, file);
|
||||||
|
if (import1 != null) {
|
||||||
|
imports.add(import1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
elisions.add(use); // we have to trim that later
|
elisions.add(use); // we have to trim that later
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ public class ErrorReporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateFileError(SourceFile file, String message) {
|
public static void generateFileError(SourceFile file, String message) {
|
||||||
|
|
||||||
String error = ErrorBuilder.error(message)
|
String error = ErrorBuilder.error(message)
|
||||||
.pointAtFile(file)
|
.pointAtFile(file)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package com.jozufozu.flywheel.core.source.parse;
|
package com.jozufozu.flywheel.core.source.parse;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -12,34 +11,31 @@ import com.jozufozu.flywheel.core.source.SourceFile;
|
||||||
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
||||||
import com.jozufozu.flywheel.core.source.span.Span;
|
import com.jozufozu.flywheel.core.source.span.Span;
|
||||||
|
|
||||||
|
import net.minecraft.ResourceLocationException;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class Import extends AbstractShaderElement {
|
public class Import extends AbstractShaderElement {
|
||||||
|
|
||||||
public static final List<Import> IMPORTS = new ArrayList<>();
|
public static final Pattern PATTERN = Pattern.compile("^\\s*#\\s*use\\s+\"(.*)\"", Pattern.MULTILINE);
|
||||||
|
|
||||||
private final Span file;
|
|
||||||
|
|
||||||
private final FileResolution resolution;
|
private final FileResolution resolution;
|
||||||
|
|
||||||
public Import(Resolver resolver, Span self, Span file) {
|
protected Import(Span self, FileResolution resolution, Span file) {
|
||||||
super(self);
|
super(self);
|
||||||
this.file = file;
|
this.resolution = resolution.addSpan(file);
|
||||||
|
|
||||||
resolution = resolver.get(toRL(file))
|
|
||||||
.addSpan(file);
|
|
||||||
|
|
||||||
IMPORTS.add(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceLocation toRL(Span file) {
|
@Nullable
|
||||||
|
public static Import create(Resolver resolver, Span self, Span file) {
|
||||||
|
ResourceLocation fileLocation;
|
||||||
try {
|
try {
|
||||||
return new ResourceLocation(file.get());
|
fileLocation = new ResourceLocation(file.get());
|
||||||
} catch (RuntimeException error) {
|
} catch (ResourceLocationException e) {
|
||||||
ErrorReporter.generateSpanError(file, "malformed source name");
|
ErrorReporter.generateSpanError(file, "malformed source location");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResourceLocation("");
|
return new Import(self, resolver.get(fileLocation), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileResolution getResolution() {
|
public FileResolution getResolution() {
|
||||||
|
|
|
@ -9,6 +9,9 @@ import com.jozufozu.flywheel.core.source.span.Span;
|
||||||
|
|
||||||
public class ShaderFunction extends AbstractShaderElement {
|
public class ShaderFunction extends AbstractShaderElement {
|
||||||
|
|
||||||
|
// https://regexr.com/60n3d
|
||||||
|
public static final Pattern functionDeclaration = Pattern.compile("(\\w+)\\s+(\\w+)\\s*\\(([\\w,\\s]*)\\)\\s*\\{");
|
||||||
|
|
||||||
public static final Pattern argument = Pattern.compile("(?:(inout|in|out) )?(\\w+)\\s+(\\w+)");
|
public static final Pattern argument = Pattern.compile("(?:(inout|in|out) )?(\\w+)\\s+(\\w+)");
|
||||||
public static final Pattern assignment = Pattern.compile("(\\w+)\\s*=");
|
public static final Pattern assignment = Pattern.compile("(\\w+)\\s*=");
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import com.jozufozu.flywheel.core.source.span.Span;
|
||||||
public class ShaderStruct extends AbstractShaderElement {
|
public class ShaderStruct extends AbstractShaderElement {
|
||||||
|
|
||||||
// https://regexr.com/61rpe
|
// https://regexr.com/61rpe
|
||||||
public static final Pattern struct = Pattern.compile("struct\\s+([\\w\\d]*)\\s*\\{([\\w\\d\\s,;]*)}\\s*;\\s");
|
public static final Pattern PATTERN = Pattern.compile("struct\\s+([\\w\\d]*)\\s*\\{([\\w\\d\\s,;]*)}\\s*;\\s");
|
||||||
|
|
||||||
public final Span name;
|
public final Span name;
|
||||||
public final Span body;
|
public final Span body;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
@ -38,24 +39,8 @@ public class BlockVertex implements VertexType {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getShaderHeader() {
|
public FileResolution getLayoutShader() {
|
||||||
return """
|
return LayoutShaders.BLOCK;
|
||||||
layout (location = 0) in vec3 _flw_v_pos;
|
|
||||||
layout (location = 1) in vec4 _flw_v_color;
|
|
||||||
layout (location = 2) in vec2 _flw_v_texCoords;
|
|
||||||
layout (location = 3) in vec2 _flw_v_light;
|
|
||||||
layout (location = 4) in vec3 _flw_v_normal;
|
|
||||||
|
|
||||||
Vertex FLWCreateVertex() {
|
|
||||||
Vertex v;
|
|
||||||
v.pos = _flw_v_pos;
|
|
||||||
v.color = _flw_v_color;
|
|
||||||
v.texCoords = _flw_v_texCoords;
|
|
||||||
v.light = _flw_v_light;
|
|
||||||
v.normal = _flw_v_normal;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) {
|
public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import java.nio.ByteBuffer;
|
||||||
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
|
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
|
||||||
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.util.RenderMath;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
|
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.util.RenderMath;
|
||||||
|
|
||||||
public class BlockVertexListUnsafe implements VertexList {
|
public class BlockVertexListUnsafe implements VertexList {
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core.vertex;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.vertex.BlockVertex;
|
|
||||||
import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex;
|
|
||||||
|
|
||||||
public class Formats {
|
public class Formats {
|
||||||
|
|
||||||
public static final PosTexNormalVertex POS_TEX_NORMAL = new PosTexNormalVertex();
|
|
||||||
public static final BlockVertex BLOCK = new BlockVertex();
|
public static final BlockVertex BLOCK = new BlockVertex();
|
||||||
|
public static final PosTexNormalVertex POS_TEX_NORMAL = new PosTexNormalVertex();
|
||||||
}
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.jozufozu.flywheel.core.vertex;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.source.Resolver;
|
||||||
|
import com.jozufozu.flywheel.event.GatherContextEvent;
|
||||||
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
public class LayoutShaders {
|
||||||
|
public static FileResolution BLOCK;
|
||||||
|
public static FileResolution POS_TEX_NORMAL;
|
||||||
|
|
||||||
|
public static void flwInit(GatherContextEvent event) {
|
||||||
|
BLOCK = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.BLOCK, ".vert"));
|
||||||
|
POS_TEX_NORMAL = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Names {
|
||||||
|
public static final ResourceLocation BLOCK = Flywheel.rl("layout/block");
|
||||||
|
public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal");
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import java.nio.ByteBuffer;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
|
||||||
public class PosTexNormalVertex implements VertexType {
|
public class PosTexNormalVertex implements VertexType {
|
||||||
|
|
||||||
|
@ -28,21 +29,7 @@ public class PosTexNormalVertex implements VertexType {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getShaderHeader() {
|
public FileResolution getLayoutShader() {
|
||||||
return """
|
return LayoutShaders.POS_TEX_NORMAL;
|
||||||
layout (location = 0) in vec3 _flw_v_pos;
|
|
||||||
layout (location = 1) in vec2 _flw_v_texCoords;
|
|
||||||
layout (location = 2) in vec3 _flw_v_normal;
|
|
||||||
|
|
||||||
Vertex FLWCreateVertex() {
|
|
||||||
Vertex v;
|
|
||||||
v.pos = _flw_v_pos;
|
|
||||||
v.color = vec4(1.);
|
|
||||||
v.texCoords = _flw_v_texCoords;
|
|
||||||
v.light = vec2(0.);
|
|
||||||
v.normal = _flw_v_normal;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.Formats;
|
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.util.RenderMath;
|
||||||
|
|
||||||
public class PosTexNormalVertexListUnsafe implements VertexList {
|
public class PosTexNormalVertexListUnsafe implements VertexList {
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.core.materials.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
|
|
|
@ -9,8 +9,8 @@ import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.core.materials.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
|
|
|
@ -7,9 +7,9 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
|
||||||
import com.jozufozu.flywheel.core.Models;
|
import com.jozufozu.flywheel.core.Models;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.core.materials.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
|
import com.jozufozu.flywheel.core.materials.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"vertex": "flywheel:model.vert",
|
|
||||||
"fragment": "flywheel:block.frag"
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"vertex": "flywheel:oriented.vert",
|
|
||||||
"fragment": "flywheel:block.frag"
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"vertex": "flywheel:passthru.vert",
|
|
||||||
"fragment": "flywheel:block.frag"
|
|
||||||
}
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
in vec4 flw_vertexPos;
|
||||||
|
in vec4 flw_vertexColor;
|
||||||
|
in vec2 flw_vertexTexCoord;
|
||||||
|
in vec2 flw_vertexLight;
|
||||||
|
in vec3 flw_vertexNormal;
|
||||||
|
|
||||||
|
in float flw_distance;
|
||||||
|
|
||||||
|
in vec4 flw_var0;
|
||||||
|
in vec4 flw_var1;
|
||||||
|
in vec4 flw_var2;
|
||||||
|
in vec4 flw_var3;
|
|
@ -0,0 +1,12 @@
|
||||||
|
out vec4 flw_vertexPos;
|
||||||
|
out vec4 flw_vertexColor;
|
||||||
|
out vec2 flw_vertexTexCoord;
|
||||||
|
out vec2 flw_vertexLight;
|
||||||
|
out vec3 flw_vertexNormal;
|
||||||
|
|
||||||
|
out float flw_distance;
|
||||||
|
|
||||||
|
out vec4 flw_var0;
|
||||||
|
out vec4 flw_var1;
|
||||||
|
out vec4 flw_var2;
|
||||||
|
out vec4 flw_var3;
|
|
@ -1,13 +0,0 @@
|
||||||
|
|
||||||
struct Fragment {
|
|
||||||
vec2 texCoords;
|
|
||||||
vec4 color;
|
|
||||||
float diffuse;
|
|
||||||
vec2 light;
|
|
||||||
};
|
|
||||||
|
|
||||||
vec4 fragment(Fragment r) {
|
|
||||||
vec4 tex = FLWBlockTexture(r.texCoords);
|
|
||||||
|
|
||||||
return vec4(tex.rgb * FLWLight(r.light).rgb * r.diffuse, tex.a) * r.color;
|
|
||||||
}
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
#use "flywheel:util/diffuse.glsl"
|
||||||
|
#use "flywheel:util/fog.glsl"
|
||||||
|
|
||||||
|
uniform mat4 uViewProjection;
|
||||||
|
uniform vec3 uCameraPos;
|
||||||
|
uniform int uConstantAmbientLight;
|
||||||
|
uniform int uFogShape;
|
||||||
|
|
||||||
|
out float _flw_diffuse;
|
||||||
|
|
||||||
|
void flw_contextVertex() {
|
||||||
|
flw_vertexNormal = normalize(flw_vertexNormal);
|
||||||
|
if (uConstantAmbientLight == 1) {
|
||||||
|
_flw_diffuse = diffuseNether(flw_vertexNormal);
|
||||||
|
} else {
|
||||||
|
_flw_diffuse = diffuse(flw_vertexNormal);
|
||||||
|
}
|
||||||
|
flw_distance = fog_distance(flw_vertexPos.xyz, uCameraPos, uFogShape);
|
||||||
|
gl_Position = uViewProjection * flw_vertexPos;
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
|
#ifdef DEBUG_NORMAL
|
||||||
|
flw_vertexColor = vec4(flw_vertexNormal, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#use "flywheel:api/fragment.glsl"
|
||||||
|
#use "flywheel:util/fog.glsl"
|
||||||
|
|
||||||
|
uniform vec2 uFogRange;
|
||||||
|
uniform vec4 uFogColor;
|
||||||
|
uniform vec2 uTextureScale;
|
||||||
|
|
||||||
|
uniform sampler2D uBlockAtlas;
|
||||||
|
uniform sampler2D uCrumbling;
|
||||||
|
|
||||||
|
in float _flw_diffuse;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void flw_contextFragment() {
|
||||||
|
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
||||||
|
vec4 crumblingColor = texture(uCrumbling, flw_vertexTexCoord * uTextureScale);
|
||||||
|
crumblingColor.a *= texColor.a;
|
||||||
|
vec4 color = flw_vertexColor * vec4(crumblingColor.rgb * _flw_diffuse, crumblingColor.a);
|
||||||
|
|
||||||
|
#ifdef ALPHA_DISCARD
|
||||||
|
if (color.a < ALPHA_DISCARD) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLOR_FOG
|
||||||
|
color = linear_fog(color, flw_distance, uFogRange.x, uFogRange.y, uFogColor);
|
||||||
|
#elif defined(FADE_FOG)
|
||||||
|
color = linear_fog_fade(color, flw_distance, uFogRange.x, uFogRange.y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fragColor = color;
|
||||||
|
}
|
|
@ -1,64 +0,0 @@
|
||||||
#use "flywheel:context/fog.glsl"
|
|
||||||
|
|
||||||
uniform float uTime;
|
|
||||||
uniform mat4 uViewProjection;
|
|
||||||
uniform vec3 uCameraPos;
|
|
||||||
uniform int uConstantAmbientLight;
|
|
||||||
|
|
||||||
uniform vec2 uTextureScale;
|
|
||||||
uniform sampler2D uBlockAtlas;
|
|
||||||
uniform sampler2D uLightMap;
|
|
||||||
uniform sampler2D uCrumbling;
|
|
||||||
|
|
||||||
uniform vec2 uWindowSize;
|
|
||||||
|
|
||||||
#ifdef VERTEX_SHADER
|
|
||||||
|
|
||||||
#use "flywheel:context/diffuse.glsl"
|
|
||||||
|
|
||||||
vec4 FLWVertex(inout Vertex v) {
|
|
||||||
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;
|
|
||||||
|
|
||||||
vec4 FLWBlockTexture(vec2 texCoords) {
|
|
||||||
vec4 cr = texture(uCrumbling, texCoords * uTextureScale);
|
|
||||||
float diffuseAlpha = texture(uBlockAtlas, texCoords).a;
|
|
||||||
cr.a = cr.a * diffuseAlpha;
|
|
||||||
return cr;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 FLWLight(vec2 lightCoords) {
|
|
||||||
return vec4(1.);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FLWFinalizeColor(vec4 color) {
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1 @@
|
||||||
|
#use "flywheel:context/common.vert"
|
|
@ -1,50 +0,0 @@
|
||||||
uniform vec4 uFogColor;
|
|
||||||
uniform vec2 uFogRange;
|
|
||||||
uniform int uFogShape;
|
|
||||||
|
|
||||||
#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 fog_distance(vec3 relativePos) {
|
|
||||||
if (uFogShape == 0) {
|
|
||||||
return spherical_distance(relativePos);
|
|
||||||
} else {
|
|
||||||
return cylindrical_distance(relativePos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#use "flywheel:api/fragment.glsl"
|
||||||
|
#use "flywheel:util/fog.glsl"
|
||||||
|
|
||||||
|
// optimize discard usage
|
||||||
|
#ifdef ALPHA_DISCARD
|
||||||
|
#ifdef GL_ARB_conservative_depth
|
||||||
|
layout (depth_greater) out float gl_FragDepth;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform vec2 uFogRange;
|
||||||
|
uniform vec4 uFogColor;
|
||||||
|
|
||||||
|
uniform sampler2D uBlockAtlas;
|
||||||
|
uniform sampler2D uLightMap;
|
||||||
|
|
||||||
|
in float _flw_diffuse;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void flw_contextFragment() {
|
||||||
|
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
||||||
|
vec4 lightColor = texture(uLightMap, flw_vertexLight);
|
||||||
|
vec4 color = flw_vertexColor * vec4(texColor.rgb * lightColor.rgb * _flw_diffuse, texColor.a);
|
||||||
|
|
||||||
|
#ifdef ALPHA_DISCARD
|
||||||
|
if (color.a < ALPHA_DISCARD) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLOR_FOG
|
||||||
|
color = linear_fog(color, flw_distance, uFogRange.x, uFogRange.y, uFogColor);
|
||||||
|
#elif defined(FADE_FOG)
|
||||||
|
color = linear_fog_fade(color, flw_distance, uFogRange.x, uFogRange.y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fragColor = color;
|
||||||
|
}
|
|
@ -1,68 +0,0 @@
|
||||||
#use "flywheel:context/fog.glsl"
|
|
||||||
|
|
||||||
uniform float uTime;
|
|
||||||
uniform mat4 uViewProjection;
|
|
||||||
uniform vec3 uCameraPos;
|
|
||||||
uniform int uConstantAmbientLight;
|
|
||||||
|
|
||||||
uniform vec2 uTextureScale;
|
|
||||||
uniform sampler2D uBlockAtlas;
|
|
||||||
uniform sampler2D uLightMap;
|
|
||||||
|
|
||||||
uniform vec2 uWindowSize;
|
|
||||||
|
|
||||||
#ifdef VERTEX_SHADER
|
|
||||||
|
|
||||||
#use "flywheel:context/diffuse.glsl"
|
|
||||||
|
|
||||||
vec4 FLWVertex(inout Vertex v) {
|
|
||||||
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
|
|
||||||
#ifdef ALPHA_DISCARD
|
|
||||||
#ifdef GL_ARB_conservative_depth
|
|
||||||
layout (depth_greater) out float gl_FragDepth;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
out vec4 fragColor;
|
|
||||||
|
|
||||||
vec4 FLWBlockTexture(vec2 texCoords) {
|
|
||||||
return texture(uBlockAtlas, texCoords);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 FLWLight(vec2 lightCoords) {
|
|
||||||
return texture(uLightMap, shiftLight(lightCoords));
|
|
||||||
}
|
|
||||||
|
|
||||||
void FLWFinalizeColor(vec4 color) {
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1 @@
|
||||||
|
#use "flywheel:context/common.vert"
|
|
@ -0,0 +1,16 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
#use "flywheel:util/light.glsl"
|
||||||
|
|
||||||
|
struct Instance {
|
||||||
|
vec2 light;
|
||||||
|
vec4 color;
|
||||||
|
mat4 transform;
|
||||||
|
mat3 normalMat;
|
||||||
|
};
|
||||||
|
|
||||||
|
void flw_instanceVertex(Instance instance) {
|
||||||
|
flw_vertexPos = instance.transform * flw_vertexPos;
|
||||||
|
flw_vertexNormal = instance.normalMat * flw_vertexNormal;
|
||||||
|
flw_vertexColor = instance.color;
|
||||||
|
flw_vertexLight = shiftLight(instance.light);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
#use "flywheel:util/light.glsl"
|
||||||
|
#use "flywheel:util/quaternion.glsl"
|
||||||
|
|
||||||
|
struct Oriented {
|
||||||
|
vec2 light;
|
||||||
|
vec4 color;
|
||||||
|
vec3 pos;
|
||||||
|
vec3 pivot;
|
||||||
|
vec4 rotation;
|
||||||
|
};
|
||||||
|
|
||||||
|
void flw_instanceVertex(Oriented oriented) {
|
||||||
|
flw_vertexPos = vec4(rotateVertexByQuat(flw_vertexPos.xyz - oriented.pivot, oriented.rotation) + oriented.pivot + oriented.pos, 1.0);
|
||||||
|
flw_vertexNormal = rotateVertexByQuat(flw_vertexNormal, oriented.rotation);
|
||||||
|
flw_vertexColor = oriented.color;
|
||||||
|
flw_vertexLight = shiftLight(oriented.light);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
#use "flywheel:util/light.glsl"
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 _flw_v_pos;
|
||||||
|
layout(location = 1) in vec4 _flw_v_color;
|
||||||
|
layout(location = 2) in vec2 _flw_v_texCoord;
|
||||||
|
layout(location = 3) in vec2 _flw_v_light;
|
||||||
|
layout(location = 4) in vec3 _flw_v_normal;
|
||||||
|
|
||||||
|
void flw_layoutVertex() {
|
||||||
|
flw_vertexPos = vec4(_flw_v_pos, 1.0);
|
||||||
|
flw_vertexColor = _flw_v_color;
|
||||||
|
flw_vertexTexCoord = _flw_v_texCoord;
|
||||||
|
flw_vertexLight = shiftLight(_flw_v_light);
|
||||||
|
flw_vertexNormal = _flw_v_normal;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 _flw_v_pos;
|
||||||
|
layout(location = 1) in vec2 _flw_v_texCoord;
|
||||||
|
layout(location = 2) in vec3 _flw_v_normal;
|
||||||
|
|
||||||
|
void flw_layoutVertex() {
|
||||||
|
flw_vertexPos = vec4(_flw_v_pos, 1.0);
|
||||||
|
flw_vertexColor = vec4(1.0);
|
||||||
|
flw_vertexTexCoord = _flw_v_texCoord;
|
||||||
|
flw_vertexLight = vec2(0.0);
|
||||||
|
flw_vertexNormal = _flw_v_normal;
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
|
|
||||||
struct Instance {
|
|
||||||
vec2 light;
|
|
||||||
vec4 color;
|
|
||||||
mat4 transform;
|
|
||||||
mat3 normalMat;
|
|
||||||
};
|
|
||||||
|
|
||||||
void vertex(inout Vertex v, Instance i) {
|
|
||||||
v.pos = (i.transform * vec4(v.pos, 1.)).xyz;
|
|
||||||
v.normal = i.normalMat * v.normal;
|
|
||||||
v.color = i.color;
|
|
||||||
v.light = i.light;
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#use "flywheel:core/quaternion.glsl"
|
|
||||||
|
|
||||||
struct Oriented {
|
|
||||||
vec2 light;
|
|
||||||
vec4 color;
|
|
||||||
vec3 pos;
|
|
||||||
vec3 pivot;
|
|
||||||
vec4 rotation;
|
|
||||||
};
|
|
||||||
|
|
||||||
void vertex(inout Vertex v, Oriented o) {
|
|
||||||
v.pos = rotateVertexByQuat(v.pos - o.pivot, o.rotation) + o.pivot + o.pos;
|
|
||||||
v.normal = rotateVertexByQuat(v.normal, o.rotation);
|
|
||||||
v.color = o.color;
|
|
||||||
v.light = o.light;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
void vertex(inout Vertex v) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
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 fog_distance(vec3 relativePos, int fogShape) {
|
||||||
|
if (fogShape == 0) {
|
||||||
|
return spherical_distance(relativePos);
|
||||||
|
} else {
|
||||||
|
return cylindrical_distance(relativePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float fog_distance(vec3 worldPos, vec3 cameraPos, int fogShape) {
|
||||||
|
return fog_distance(worldPos - cameraPos, fogShape);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 linear_fog(vec4 color, float distance, float fogStart, float fogEnd, vec4 fogColor) {
|
||||||
|
if (distance <= fogStart) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fogValue = distance < fogEnd ? smoothstep(fogStart, fogEnd, distance) : 1.0;
|
||||||
|
return vec4(mix(color.rgb, fogColor.rgb, fogValue * fogColor.a), color.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 linear_fog_fade(vec4 color, float distance, float fogStart, float fogEnd) {
|
||||||
|
if (distance <= fogStart) {
|
||||||
|
return color;
|
||||||
|
} else if (distance >= fogEnd) {
|
||||||
|
return vec4(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return color * smoothstep(fogEnd, fogStart, distance);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Adjust the [0,1] normalized lightmap value based on the texture matrix from LightTexture#enableLightmap
|
// Adjust the [0,1] normalized lightmap value based on the texture matrix from LightTexture#enableLightmap
|
||||||
vec2 shiftLight(vec2 lm) {
|
vec2 shiftLight(vec2 lm) {
|
||||||
return lm * 0.99609375 + 0.03125;// * 255/256 + 1/32
|
return lm * 0.99609375 + 0.03125; // * 255/256 + 1/32
|
||||||
}
|
}
|
Loading…
Reference in a new issue