mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-25 19:29:47 +01:00
Indirectly lit
- "Functional" arena based lighting for indirect - Strip out most of the reference counting stuffs for embeddings - Naively re-buffer all tracked light sections every frame
This commit is contained in:
parent
e10852fe7a
commit
51224d618f
26 changed files with 134 additions and 110 deletions
|
@ -8,5 +8,4 @@ public class Samplers {
|
||||||
public static final GlTextureUnit LIGHT = GlTextureUnit.T2;
|
public static final GlTextureUnit LIGHT = GlTextureUnit.T2;
|
||||||
public static final GlTextureUnit CRUMBLING = GlTextureUnit.T3;
|
public static final GlTextureUnit CRUMBLING = GlTextureUnit.T3;
|
||||||
public static final GlTextureUnit INSTANCE_BUFFER = GlTextureUnit.T4;
|
public static final GlTextureUnit INSTANCE_BUFFER = GlTextureUnit.T4;
|
||||||
public static final GlTextureUnit EMBEDDED_LIGHT = GlTextureUnit.T5;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ public enum ContextShader {
|
||||||
DEFAULT(null, $ -> {
|
DEFAULT(null, $ -> {
|
||||||
}),
|
}),
|
||||||
CRUMBLING("_FLW_CRUMBLING", program -> program.setSamplerBinding("_flw_crumblingTex", Samplers.CRUMBLING)),
|
CRUMBLING("_FLW_CRUMBLING", program -> program.setSamplerBinding("_flw_crumblingTex", Samplers.CRUMBLING)),
|
||||||
EMBEDDED("_FLW_EMBEDDED", program -> program.setSamplerBinding("_flw_lightVolume", Samplers.EMBEDDED_LIGHT));
|
EMBEDDED("_FLW_EMBEDDED", $ -> {});
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String define;
|
private final String define;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||||
import dev.engine_room.flywheel.api.layout.Layout;
|
import dev.engine_room.flywheel.api.layout.Layout;
|
||||||
import dev.engine_room.flywheel.backend.engine.indirect.IndirectBuffers;
|
import dev.engine_room.flywheel.backend.engine.indirect.BufferBindings;
|
||||||
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
||||||
import dev.engine_room.flywheel.backend.glsl.generate.GlslBlock;
|
import dev.engine_room.flywheel.backend.glsl.generate.GlslBlock;
|
||||||
import dev.engine_room.flywheel.backend.glsl.generate.GlslBuilder;
|
import dev.engine_room.flywheel.backend.glsl.generate.GlslBuilder;
|
||||||
|
@ -43,7 +43,7 @@ public class SsboInstanceComponent extends InstanceAssemblerComponent {
|
||||||
|
|
||||||
fnBody.ret(GlslExpr.call(STRUCT_NAME, unpackArgs));
|
fnBody.ret(GlslExpr.call(STRUCT_NAME, unpackArgs));
|
||||||
|
|
||||||
builder._addRaw("layout(std430, binding = " + IndirectBuffers.INSTANCE_INDEX + ") restrict readonly buffer InstanceBuffer {\n"
|
builder._addRaw("layout(std430, binding = " + BufferBindings.INSTANCE_BUFFER_BINDING + ") restrict readonly buffer InstanceBuffer {\n"
|
||||||
+ " uint _flw_instances[];\n"
|
+ " uint _flw_instances[];\n"
|
||||||
+ "};");
|
+ "};");
|
||||||
builder.blankLine();
|
builder.blankLine();
|
||||||
|
|
|
@ -25,8 +25,6 @@ public abstract class AbstractInstancer<I extends Instance> implements Instancer
|
||||||
protected AbstractInstancer(InstanceType<I> type, Environment environment) {
|
protected AbstractInstancer(InstanceType<I> type, Environment environment) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
|
|
||||||
environment.acquire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,9 +175,7 @@ public abstract class AbstractInstancer<I extends Instance> implements Instancer
|
||||||
deleted.clear();
|
deleted.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public abstract void delete();
|
||||||
environment.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import dev.engine_room.flywheel.api.instance.Instancer;
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
import dev.engine_room.flywheel.api.model.Model;
|
||||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||||
import dev.engine_room.flywheel.backend.engine.embed.Environment;
|
import dev.engine_room.flywheel.backend.engine.embed.Environment;
|
||||||
|
import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
|
||||||
import dev.engine_room.flywheel.lib.util.Pair;
|
import dev.engine_room.flywheel.lib.util.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
@ -45,7 +46,7 @@ public abstract class DrawManager<N extends AbstractInstancer<?>> {
|
||||||
initializationQueue.clear();
|
initializationQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() {
|
public void flush(LightStorage lightStorage) {
|
||||||
// Thread safety: flush is called from the render thread after all visual updates have been made,
|
// Thread safety: flush is called from the render thread after all visual updates have been made,
|
||||||
// so there are no:tm: threads we could be racing with.
|
// so there are no:tm: threads we could be racing with.
|
||||||
for (var instancer : initializationQueue) {
|
for (var instancer : initializationQueue) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
public class EngineImpl implements Engine {
|
public class EngineImpl implements Engine {
|
||||||
private final int sqrMaxOriginDistance;
|
private final int sqrMaxOriginDistance;
|
||||||
private final DrawManager<? extends AbstractInstancer<?>> drawManager;
|
private final DrawManager<? extends AbstractInstancer<?>> drawManager;
|
||||||
private final EnvironmentStorage environmentStorage = new EnvironmentStorage();
|
private final EnvironmentStorage environmentStorage;
|
||||||
private final LightStorage lightStorage;
|
private final LightStorage lightStorage;
|
||||||
private final Flag flushFlag = new NamedFlag("flushed");
|
private final Flag flushFlag = new NamedFlag("flushed");
|
||||||
|
|
||||||
|
@ -40,12 +40,13 @@ public class EngineImpl implements Engine {
|
||||||
public EngineImpl(LevelAccessor level, DrawManager<? extends AbstractInstancer<?>> drawManager, int maxOriginDistance) {
|
public EngineImpl(LevelAccessor level, DrawManager<? extends AbstractInstancer<?>> drawManager, int maxOriginDistance) {
|
||||||
this.drawManager = drawManager;
|
this.drawManager = drawManager;
|
||||||
sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance;
|
sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance;
|
||||||
lightStorage = new LightStorage(level);
|
environmentStorage = new EnvironmentStorage();
|
||||||
|
lightStorage = new LightStorage(level, environmentStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Plan<RenderContext> createFramePlan() {
|
public Plan<RenderContext> createFramePlan() {
|
||||||
return SyncedPlan.of(this::flush);
|
return lightStorage.createFramePlan().then(SyncedPlan.of(this::flush));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -96,7 +97,6 @@ public class EngineImpl implements Engine {
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
drawManager.delete();
|
drawManager.delete();
|
||||||
environmentStorage.delete();
|
|
||||||
lightStorage.delete();
|
lightStorage.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +107,8 @@ public class EngineImpl implements Engine {
|
||||||
private void flush(RenderContext ctx) {
|
private void flush(RenderContext ctx) {
|
||||||
try (var state = GlStateTracker.getRestoreState()) {
|
try (var state = GlStateTracker.getRestoreState()) {
|
||||||
Uniforms.update(ctx);
|
Uniforms.update(ctx);
|
||||||
drawManager.flush();
|
|
||||||
environmentStorage.flush();
|
environmentStorage.flush();
|
||||||
|
drawManager.flush(lightStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
flushFlag.raise();
|
flushFlag.raise();
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package dev.engine_room.flywheel.backend.engine;
|
package dev.engine_room.flywheel.backend.engine;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.backend.engine.embed.AbstractEmbeddedEnvironment;
|
import dev.engine_room.flywheel.backend.engine.embed.AbstractEmbeddedEnvironment;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceSet;
|
import it.unimi.dsi.fastutil.objects.ReferenceSet;
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceSets;
|
import it.unimi.dsi.fastutil.objects.ReferenceSets;
|
||||||
|
@ -13,10 +15,13 @@ public class EnvironmentStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
environments.removeIf(AbstractEmbeddedEnvironment::isDeleted);
|
||||||
environments.forEach(AbstractEmbeddedEnvironment::flush);
|
environments.forEach(AbstractEmbeddedEnvironment::flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public LongSet allLightSections() {
|
||||||
environments.clear();
|
var out = new LongOpenHashSet();
|
||||||
|
environments.forEach(e -> e.addLightSections(out));
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,10 @@ import dev.engine_room.flywheel.api.visualization.VisualEmbedding;
|
||||||
import dev.engine_room.flywheel.backend.compile.ContextShader;
|
import dev.engine_room.flywheel.backend.compile.ContextShader;
|
||||||
import dev.engine_room.flywheel.backend.engine.EngineImpl;
|
import dev.engine_room.flywheel.backend.engine.EngineImpl;
|
||||||
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
||||||
import dev.engine_room.flywheel.backend.util.AtomicReferenceCounted;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
|
||||||
public abstract class AbstractEmbeddedEnvironment extends AtomicReferenceCounted implements Environment, VisualEmbedding {
|
public abstract class AbstractEmbeddedEnvironment implements Environment, VisualEmbedding {
|
||||||
protected final Matrix4f pose = new Matrix4f();
|
protected final Matrix4f pose = new Matrix4f();
|
||||||
protected final Matrix3f normal = new Matrix3f();
|
protected final Matrix3f normal = new Matrix3f();
|
||||||
private final Matrix4f poseComposed = new Matrix4f();
|
private final Matrix4f poseComposed = new Matrix4f();
|
||||||
|
@ -27,6 +27,8 @@ public abstract class AbstractEmbeddedEnvironment extends AtomicReferenceCounted
|
||||||
protected final EngineImpl engine;
|
protected final EngineImpl engine;
|
||||||
private final RenderStage renderStage;
|
private final RenderStage renderStage;
|
||||||
|
|
||||||
|
private boolean deleted = false;
|
||||||
|
|
||||||
public AbstractEmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
|
public AbstractEmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.renderStage = renderStage;
|
this.renderStage = renderStage;
|
||||||
|
@ -38,9 +40,6 @@ public abstract class AbstractEmbeddedEnvironment extends AtomicReferenceCounted
|
||||||
return engine.instancer(AbstractEmbeddedEnvironment.this, type, model, renderStage);
|
return engine.instancer(AbstractEmbeddedEnvironment.this, type, model, renderStage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Acquire the reference owned by the visual that created this.
|
|
||||||
acquire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,15 +93,20 @@ public abstract class AbstractEmbeddedEnvironment extends AtomicReferenceCounted
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLightSections(LongSet out) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by visuals
|
* Called by visuals
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
// Release the reference owned by the visual that created this.
|
deleted = true;
|
||||||
// Note that visuals don't explicitly call acquire, instead the
|
|
||||||
// storage acquired a reference when this was constructed.
|
|
||||||
release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void setupLight(GlProgram program);
|
public abstract void setupLight(GlProgram program);
|
||||||
|
|
|
@ -47,4 +47,8 @@ public class Arena {
|
||||||
public void delete() {
|
public void delete() {
|
||||||
memoryBlock.free();
|
memoryBlock.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int capacity() {
|
||||||
|
return top;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,4 @@ public interface Environment {
|
||||||
void setupDraw(GlProgram drawProgram);
|
void setupDraw(GlProgram drawProgram);
|
||||||
|
|
||||||
void setupCull(GlProgram cullProgram);
|
void setupCull(GlProgram cullProgram);
|
||||||
|
|
||||||
void acquire();
|
|
||||||
|
|
||||||
void release();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,4 @@ public class GlobalEnvironment implements Environment {
|
||||||
public void setupCull(GlProgram cullProgram) {
|
public void setupCull(GlProgram cullProgram) {
|
||||||
cullProgram.setBool(EmbeddingUniforms.USE_MODEL_MATRIX, false);
|
cullProgram.setBool(EmbeddingUniforms.USE_MODEL_MATRIX, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void acquire() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,11 @@ import java.util.BitSet;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.api.event.RenderContext;
|
||||||
|
import dev.engine_room.flywheel.api.task.Plan;
|
||||||
|
import dev.engine_room.flywheel.backend.engine.EnvironmentStorage;
|
||||||
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
|
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
|
||||||
|
import dev.engine_room.flywheel.lib.task.SimplePlan;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2IntMap;
|
import it.unimi.dsi.fastutil.longs.Long2IntMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
|
||||||
|
@ -29,11 +33,12 @@ import net.minecraft.world.level.LightLayer;
|
||||||
* <p>Thus, each section occupies 5832 bytes.
|
* <p>Thus, each section occupies 5832 bytes.
|
||||||
*/
|
*/
|
||||||
public class LightStorage {
|
public class LightStorage {
|
||||||
private final long SECTION_SIZE_BYTES = 9 * 9 * 9 * 8;
|
public static final long SECTION_SIZE_BYTES = 9 * 9 * 9 * 8;
|
||||||
private final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
|
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
|
||||||
private final int INVALID_SECTION = -1;
|
private static final int INVALID_SECTION = -1;
|
||||||
|
|
||||||
private final LevelAccessor level;
|
private final LevelAccessor level;
|
||||||
|
private final EnvironmentStorage environmentStorage;
|
||||||
|
|
||||||
private final Arena arena;
|
private final Arena arena;
|
||||||
private final Long2IntMap section2ArenaIndex = new Long2IntOpenHashMap();
|
private final Long2IntMap section2ArenaIndex = new Long2IntOpenHashMap();
|
||||||
|
@ -44,12 +49,24 @@ public class LightStorage {
|
||||||
private final BitSet changed = new BitSet();
|
private final BitSet changed = new BitSet();
|
||||||
private boolean newSections = false;
|
private boolean newSections = false;
|
||||||
|
|
||||||
public LightStorage(LevelAccessor level) {
|
public LightStorage(LevelAccessor level, EnvironmentStorage environmentStorage) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
this.environmentStorage = environmentStorage;
|
||||||
|
|
||||||
arena = new Arena(SECTION_SIZE_BYTES, DEFAULT_ARENA_CAPACITY_SECTIONS);
|
arena = new Arena(SECTION_SIZE_BYTES, DEFAULT_ARENA_CAPACITY_SECTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Plan<RenderContext> createFramePlan() {
|
||||||
|
return SimplePlan.of(() -> {
|
||||||
|
var longs = environmentStorage.allLightSections();
|
||||||
|
longs.forEach(this::addSection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public int capacity() {
|
||||||
|
return arena.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
public void addSection(long section) {
|
public void addSection(long section) {
|
||||||
var lightEngine = level.getLightEngine();
|
var lightEngine = level.getLightEngine();
|
||||||
|
|
||||||
|
@ -187,6 +204,7 @@ public class LightStorage {
|
||||||
for (int i = changed.nextSetBit(0); i >= 0; i = changed.nextSetBit(i + 1)) {
|
for (int i = changed.nextSetBit(0); i >= 0; i = changed.nextSetBit(i + 1)) {
|
||||||
staging.enqueueCopy(arena.indexToPointer(i), SECTION_SIZE_BYTES, dstVbo, i * SECTION_SIZE_BYTES);
|
staging.enqueueCopy(arena.indexToPointer(i), SECTION_SIZE_BYTES, dstVbo, i * SECTION_SIZE_BYTES);
|
||||||
}
|
}
|
||||||
|
changed.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntArrayList createLut() {
|
public IntArrayList createLut() {
|
||||||
|
|
|
@ -14,7 +14,6 @@ public class NestedEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
|
||||||
public NestedEmbeddedEnvironment(AbstractEmbeddedEnvironment parent, EngineImpl engine, RenderStage renderStage) {
|
public NestedEmbeddedEnvironment(AbstractEmbeddedEnvironment parent, EngineImpl engine, RenderStage renderStage) {
|
||||||
super(engine, renderStage);
|
super(engine, renderStage);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
parent.acquire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,9 +32,4 @@ public class NestedEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
|
||||||
pose.mul(this.pose);
|
pose.mul(this.pose);
|
||||||
normal.mul(this.normal);
|
normal.mul(this.normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void _delete() {
|
|
||||||
parent.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,17 @@ public class TopLevelEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
|
||||||
super(engine, renderStage);
|
super(engine, renderStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flush() {
|
|
||||||
super.flush();
|
|
||||||
|
|
||||||
lightSections.forEach(engine.lightStorage()::addSection);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lightChunks(LongSet chunks) {
|
public void lightChunks(LongSet chunks) {
|
||||||
lightSections.clear();
|
lightSections.clear();
|
||||||
lightSections.addAll(chunks);
|
lightSections.addAll(chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLightSections(LongSet out) {
|
||||||
|
out.addAll(lightSections);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupLight(GlProgram program) {
|
public void setupLight(GlProgram program) {
|
||||||
program.setBool(EmbeddingUniforms.USE_LIGHT_VOLUME, !lightSections.isEmpty());
|
program.setBool(EmbeddingUniforms.USE_LIGHT_VOLUME, !lightSections.isEmpty());
|
||||||
|
@ -39,9 +37,4 @@ public class TopLevelEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
|
||||||
pose.set(this.pose);
|
pose.set(this.pose);
|
||||||
normal.set(this.normal);
|
normal.set(this.normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _delete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package dev.engine_room.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
|
public class BufferBindings {
|
||||||
|
public static final int INSTANCE_BUFFER_BINDING = 0;
|
||||||
|
public static final int TARGET_BUFFER_BINDING = 1;
|
||||||
|
public static final int MODEL_INDEX_BUFFER_BINDING = 2;
|
||||||
|
public static final int MODEL_BUFFER_BINDING = 3;
|
||||||
|
public static final int DRAW_BUFFER_BINDING = 4;
|
||||||
|
public static final int EMBEDDING_LUT_BINDING = 5;
|
||||||
|
public static final int EMBEDDING_LIGHT_BINDING = 6;
|
||||||
|
|
||||||
|
private BufferBindings() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,13 +22,6 @@ public class IndirectBuffers {
|
||||||
public static final long DRAW_COMMAND_STRIDE = 40;
|
public static final long DRAW_COMMAND_STRIDE = 40;
|
||||||
public static final long DRAW_COMMAND_OFFSET = 0;
|
public static final long DRAW_COMMAND_OFFSET = 0;
|
||||||
|
|
||||||
public static final int INSTANCE_INDEX = 0;
|
|
||||||
public static final int TARGET_INDEX = 1;
|
|
||||||
public static final int MODEL_INDEX_INDEX = 2;
|
|
||||||
public static final int MODEL_INDEX = 3;
|
|
||||||
public static final int DRAW_INDEX = 4;
|
|
||||||
|
|
||||||
|
|
||||||
// Offsets to the 3 segments
|
// Offsets to the 3 segments
|
||||||
private static final long HANDLE_OFFSET = 0;
|
private static final long HANDLE_OFFSET = 0;
|
||||||
private static final long OFFSET_OFFSET = BUFFER_COUNT * INT_SIZE;
|
private static final long OFFSET_OFFSET = BUFFER_COUNT * INT_SIZE;
|
||||||
|
@ -117,7 +110,7 @@ public class IndirectBuffers {
|
||||||
|
|
||||||
private void multiBind() {
|
private void multiBind() {
|
||||||
final long ptr = multiBindBlock.ptr();
|
final long ptr = multiBindBlock.ptr();
|
||||||
nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, 0, IndirectBuffers.BUFFER_COUNT, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
|
nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.INSTANCE_BUFFER_BINDING, IndirectBuffers.BUFFER_COUNT, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,7 +118,7 @@ public class IndirectBuffers {
|
||||||
*/
|
*/
|
||||||
public void bindForCrumbling() {
|
public void bindForCrumbling() {
|
||||||
final long ptr = multiBindBlock.ptr();
|
final long ptr = multiBindBlock.ptr();
|
||||||
nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, 0, 4, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
|
nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.INSTANCE_BUFFER_BINDING, 4, ptr, ptr + OFFSET_OFFSET, ptr + SIZE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import dev.engine_room.flywheel.backend.engine.InstancerKey;
|
||||||
import dev.engine_room.flywheel.backend.engine.MaterialRenderState;
|
import dev.engine_room.flywheel.backend.engine.MaterialRenderState;
|
||||||
import dev.engine_room.flywheel.backend.engine.MeshPool;
|
import dev.engine_room.flywheel.backend.engine.MeshPool;
|
||||||
import dev.engine_room.flywheel.backend.engine.TextureBinder;
|
import dev.engine_room.flywheel.backend.engine.TextureBinder;
|
||||||
|
import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
|
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
|
||||||
import dev.engine_room.flywheel.backend.gl.array.GlVertexArray;
|
import dev.engine_room.flywheel.backend.gl.array.GlVertexArray;
|
||||||
|
@ -40,6 +41,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
private final Map<GroupKey<?>, IndirectCullingGroup<?>> cullingGroups = new HashMap<>();
|
private final Map<GroupKey<?>, IndirectCullingGroup<?>> cullingGroups = new HashMap<>();
|
||||||
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
|
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
|
||||||
|
|
||||||
|
private final LightBuffers lightBuffers;
|
||||||
|
|
||||||
public IndirectDrawManager(IndirectPrograms programs) {
|
public IndirectDrawManager(IndirectPrograms programs) {
|
||||||
this.programs = programs;
|
this.programs = programs;
|
||||||
programs.acquire();
|
programs.acquire();
|
||||||
|
@ -50,6 +53,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
vertexArray = GlVertexArray.create();
|
vertexArray = GlVertexArray.create();
|
||||||
|
|
||||||
meshPool.bind(vertexArray);
|
meshPool.bind(vertexArray);
|
||||||
|
lightBuffers = new LightBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,6 +87,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
TextureBinder.bindLightAndOverlay();
|
TextureBinder.bindLightAndOverlay();
|
||||||
|
|
||||||
vertexArray.bindForDraw();
|
vertexArray.bindForDraw();
|
||||||
|
lightBuffers.bind();
|
||||||
Uniforms.bindAll();
|
Uniforms.bindAll();
|
||||||
|
|
||||||
for (var group : cullingGroups.values()) {
|
for (var group : cullingGroups.values()) {
|
||||||
|
@ -95,8 +100,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush(LightStorage lightStorage) {
|
||||||
super.flush();
|
super.flush(lightStorage);
|
||||||
|
|
||||||
for (var group : cullingGroups.values()) {
|
for (var group : cullingGroups.values()) {
|
||||||
group.flushInstancers();
|
group.flushInstancers();
|
||||||
|
@ -108,6 +113,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
|
|
||||||
stagingBuffer.reclaim();
|
stagingBuffer.reclaim();
|
||||||
|
|
||||||
|
lightBuffers.flush(stagingBuffer, lightStorage);
|
||||||
|
|
||||||
for (var group : cullingGroups.values()) {
|
for (var group : cullingGroups.values()) {
|
||||||
group.upload(stagingBuffer);
|
group.upload(stagingBuffer);
|
||||||
}
|
}
|
||||||
|
@ -159,7 +166,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
||||||
var block = MemoryBlock.malloc(IndirectBuffers.DRAW_COMMAND_STRIDE);
|
var block = MemoryBlock.malloc(IndirectBuffers.DRAW_COMMAND_STRIDE);
|
||||||
|
|
||||||
GlBufferType.DRAW_INDIRECT_BUFFER.bind(crumblingDrawBuffer.handle());
|
GlBufferType.DRAW_INDIRECT_BUFFER.bind(crumblingDrawBuffer.handle());
|
||||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, IndirectBuffers.DRAW_INDEX, crumblingDrawBuffer.handle(), 0, IndirectBuffers.DRAW_COMMAND_STRIDE);
|
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.DRAW_BUFFER_BINDING, crumblingDrawBuffer.handle(), 0, IndirectBuffers.DRAW_COMMAND_STRIDE);
|
||||||
|
|
||||||
for (var groupEntry : byType.entrySet()) {
|
for (var groupEntry : byType.entrySet()) {
|
||||||
var byProgress = groupEntry.getValue();
|
var byProgress = groupEntry.getValue();
|
||||||
|
|
|
@ -125,8 +125,6 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
super.delete();
|
|
||||||
|
|
||||||
for (IndirectDraw draw : draws()) {
|
for (IndirectDraw draw : draws()) {
|
||||||
draw.delete();
|
draw.delete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
package dev.engine_room.flywheel.backend.engine.indirect;
|
package dev.engine_room.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
|
import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
|
||||||
|
|
||||||
public class LightBuffers {
|
public class LightBuffers {
|
||||||
private final ResizableStorageBuffer lightArena = new ResizableStorageBuffer();
|
private final ResizableStorageArray lightArena = new ResizableStorageArray(LightStorage.SECTION_SIZE_BYTES);
|
||||||
private final ResizableStorageArray lut = new ResizableStorageArray(4);
|
private final ResizableStorageArray lut = new ResizableStorageArray(4);
|
||||||
|
|
||||||
public LightBuffers() {
|
public LightBuffers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush(StagingBuffer staging, LightStorage light) {
|
public void flush(StagingBuffer staging, LightStorage light) {
|
||||||
|
var capacity = light.capacity();
|
||||||
|
|
||||||
|
if (capacity == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lightArena.ensureCapacity(capacity);
|
||||||
light.uploadChangedSections(staging, lightArena.handle());
|
light.uploadChangedSections(staging, lightArena.handle());
|
||||||
|
|
||||||
if (light.hasNewSections()) {
|
if (light.hasNewSections()) {
|
||||||
|
@ -26,4 +34,13 @@ public class LightBuffers {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bind() {
|
||||||
|
if (lightArena.capacity() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL46.glBindBufferRange(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.EMBEDDING_LUT_BINDING, lut.handle(), 0, lut.byteCapacity());
|
||||||
|
GL46.glBindBufferRange(GL46.GL_SHADER_STORAGE_BUFFER, BufferBindings.EMBEDDING_LIGHT_BINDING, lightArena.handle(), 0, lightArena.byteCapacity());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import dev.engine_room.flywheel.backend.engine.MaterialEncoder;
|
||||||
import dev.engine_room.flywheel.backend.engine.MaterialRenderState;
|
import dev.engine_room.flywheel.backend.engine.MaterialRenderState;
|
||||||
import dev.engine_room.flywheel.backend.engine.MeshPool;
|
import dev.engine_room.flywheel.backend.engine.MeshPool;
|
||||||
import dev.engine_room.flywheel.backend.engine.TextureBinder;
|
import dev.engine_room.flywheel.backend.engine.TextureBinder;
|
||||||
|
import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
|
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
|
||||||
import dev.engine_room.flywheel.backend.gl.TextureBuffer;
|
import dev.engine_room.flywheel.backend.gl.TextureBuffer;
|
||||||
|
@ -55,8 +56,8 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush(LightStorage lightStorage) {
|
||||||
super.flush();
|
super.flush(lightStorage);
|
||||||
|
|
||||||
var instancers = this.instancers.values();
|
var instancers = this.instancers.values();
|
||||||
instancers.removeIf(instancer -> {
|
instancers.removeIf(instancer -> {
|
||||||
|
|
|
@ -116,8 +116,6 @@ public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
super.delete();
|
|
||||||
|
|
||||||
if (vbo == null) {
|
if (vbo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,6 @@ uniform sampler2D _flw_crumblingTex;
|
||||||
in vec2 _flw_crumblingTexCoord;
|
in vec2 _flw_crumblingTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _FLW_EMBEDDED
|
|
||||||
uniform sampler3D _flw_lightVolume;
|
|
||||||
|
|
||||||
uniform bool _flw_useLightVolume;
|
|
||||||
|
|
||||||
in vec3 _flw_lightVolumeCoord;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
flat in uint _flw_instanceID;
|
flat in uint _flw_instanceID;
|
||||||
|
|
||||||
out vec4 _flw_outputColor;
|
out vec4 _flw_outputColor;
|
||||||
|
@ -43,12 +35,6 @@ void _flw_main() {
|
||||||
flw_fragOverlay = flw_vertexOverlay;
|
flw_fragOverlay = flw_vertexOverlay;
|
||||||
flw_fragLight = flw_vertexLight;
|
flw_fragLight = flw_vertexLight;
|
||||||
|
|
||||||
#ifdef _FLW_EMBEDDED
|
|
||||||
if (_flw_useLightVolume) {
|
|
||||||
flw_fragLight = max(flw_fragLight, texture(_flw_lightVolume, _flw_lightVolumeCoord).rg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
flw_materialFragment();
|
flw_materialFragment();
|
||||||
|
|
||||||
#ifdef _FLW_CRUMBLING
|
#ifdef _FLW_CRUMBLING
|
||||||
|
@ -98,11 +84,6 @@ void _flw_main() {
|
||||||
case 6u:
|
case 6u:
|
||||||
color = vec4(vec3(diffuseFactor), 1.);
|
color = vec4(vec3(diffuseFactor), 1.);
|
||||||
break;
|
break;
|
||||||
#ifdef _FLW_EMBEDDED
|
|
||||||
case 7u:
|
|
||||||
color = vec4(_flw_lightVolumeCoord, 1.);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_flw_outputColor = flw_fogFilter(color);
|
_flw_outputColor = flw_fogFilter(color);
|
||||||
|
|
|
@ -70,7 +70,7 @@ vec2 getCrumblingTexCoord() {
|
||||||
uniform mat4 _flw_modelMatrix;
|
uniform mat4 _flw_modelMatrix;
|
||||||
uniform mat3 _flw_normalMatrix;
|
uniform mat3 _flw_normalMatrix;
|
||||||
|
|
||||||
bool _flw_embeddedLight(vec3 worldPos, vec3 normal, out vec2 lightCoord);
|
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flat out uint _flw_instanceID;
|
flat out uint _flw_instanceID;
|
||||||
|
@ -89,7 +89,7 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
||||||
flw_vertexNormal = _flw_normalMatrix * flw_vertexNormal;
|
flw_vertexNormal = _flw_normalMatrix * flw_vertexNormal;
|
||||||
|
|
||||||
vec2 embeddedLight;
|
vec2 embeddedLight;
|
||||||
if (_flw_embeddedLight(flw_vertexPos, flw_vertexNormal, embeddedLight)) {
|
if (_flw_embeddedLight(flw_vertexPos.xyz, embeddedLight)) {
|
||||||
flw_vertexLight = max(flw_vertexLight, embeddedLight);
|
flw_vertexLight = max(flw_vertexLight, embeddedLight);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,3 +3,5 @@
|
||||||
#define _FLW_MODEL_INDEX_BUFFER_BINDING 2
|
#define _FLW_MODEL_INDEX_BUFFER_BINDING 2
|
||||||
#define _FLW_MODEL_BUFFER_BINDING 3
|
#define _FLW_MODEL_BUFFER_BINDING 3
|
||||||
#define _FLW_DRAW_BUFFER_BINDING 4
|
#define _FLW_DRAW_BUFFER_BINDING 4
|
||||||
|
#define _FLW_EMBEDDING_LUT_BINDING 5
|
||||||
|
#define _FLW_EMBEDDING_LIGHT_BINDING 6
|
||||||
|
|
|
@ -13,24 +13,33 @@ layout(std430, binding = _FLW_DRAW_BUFFER_BINDING) restrict readonly buffer Draw
|
||||||
|
|
||||||
#ifdef _FLW_EMBEDDED
|
#ifdef _FLW_EMBEDDED
|
||||||
|
|
||||||
layout(std430, binding = 8) restrict readonly buffer EmbeddingLut {
|
layout(std430, binding = _FLW_EMBEDDING_LUT_BINDING) restrict readonly buffer EmbeddingLut {
|
||||||
uint _flw_embeddingLut[];
|
uint _flw_embeddingLut[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint _FLW_LIGHT_SECTION_SIZE_BYTES = 18 * 18 * 18;
|
const uint _FLW_LIGHT_SECTION_SIZE_BYTES = 18 * 18 * 18;
|
||||||
const uint _FLW_LIGHT_SECTION_SIZE_INTS = _FLW_LIGHT_SECTION_SIZE_BYTES / 4;
|
const uint _FLW_LIGHT_SECTION_SIZE_INTS = _FLW_LIGHT_SECTION_SIZE_BYTES / 4;
|
||||||
|
|
||||||
layout(std430, binding = 9) restrict readonly buffer LightSections {
|
layout(std430, binding = _FLW_EMBEDDING_LIGHT_BINDING) restrict readonly buffer LightSections {
|
||||||
uint _flw_lightSections[];
|
uint _flw_lightSections[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Find the index for the next step in the LUT.
|
||||||
|
/// @param base The base index in the LUT, should point to the start of a coordinate span.
|
||||||
|
/// @param coord The coordinate to look for.
|
||||||
|
/// @param next Output. The index of the next step in the LUT.
|
||||||
|
/// @return true if the coordinate is not in the span.
|
||||||
bool _flw_nextLut(uint base, int coord, out uint next) {
|
bool _flw_nextLut(uint base, int coord, out uint next) {
|
||||||
|
// The base coordinate.
|
||||||
int start = int(_flw_embeddingLut[base]);
|
int start = int(_flw_embeddingLut[base]);
|
||||||
|
// The width of the coordinate span.
|
||||||
uint size = _flw_embeddingLut[base + 1];
|
uint size = _flw_embeddingLut[base + 1];
|
||||||
|
|
||||||
|
// Index of the coordinate in the span.
|
||||||
int i = coord - start;
|
int i = coord - start;
|
||||||
|
|
||||||
if (i < 0 || i >= size) {
|
if (i < 0 || i >= size) {
|
||||||
|
// We missed.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,25 +61,29 @@ bool _flw_chunkCoordToSectionIndex(ivec3 sectionPos, out uint index) {
|
||||||
return _flw_nextLut(z, sectionPos.z, index);
|
return _flw_nextLut(z, sectionPos.z, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 _flw_lightAt(uint sectionOffset, ivec3 blockInSectionPos) {
|
vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
||||||
uint byteOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
uint byteOffset = blockInSectionPos.x + blockInSectionPos.z * 18u + blockInSectionPos.y * 18u * 18u;
|
||||||
|
|
||||||
uint uintOffset = byteOffset >> 2u;
|
uint uintOffset = byteOffset >> 2u;
|
||||||
uint bitOffset = (byteOffset & 3u) << 3;
|
uint bitOffset = (byteOffset & 3u) << 3;
|
||||||
|
|
||||||
uint packed = _flw_lightSections[sectionOffset + uintOffset];
|
uint raw = _flw_lightSections[sectionOffset + uintOffset];
|
||||||
uint block = (packed >> bitOffset) & 0xFu;
|
uint block = (raw >> bitOffset) & 0xFu;
|
||||||
uint sky = (packed >> (bitOffset + 4u)) & 0xFu;
|
uint sky = (raw >> (bitOffset + 4u)) & 0xFu;
|
||||||
|
|
||||||
return vec2(block, sky);
|
return vec2(block, sky);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _flw_embeddedLight(vec3 worldPos, vec3 normal, out vec2 lightCoord) {
|
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
||||||
|
ivec3 blockPos = ivec3(floor(worldPos));
|
||||||
|
|
||||||
ivec3 sectionPos = blockPos >> 4;
|
ivec3 sectionPos = blockPos >> 4;
|
||||||
uvec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
uvec3 blockInSectionPos = (blockPos & 0xF) + 1;
|
||||||
|
|
||||||
uint lightSectionIndex;
|
uint lightSectionIndex;
|
||||||
if (_flw_chunkCoordToSectionIndex(sectionPos, lightSectionIndex)) {
|
if (_flw_chunkCoordToSectionIndex(sectionPos, lightSectionIndex)) {
|
||||||
|
// TODO: useful debug mode for this.
|
||||||
|
// flw_vertexOverlay = ivec2(0, 3);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ uniform uvec4 _flw_packedMaterial;
|
||||||
uniform int _flw_baseInstance = 0;
|
uniform int _flw_baseInstance = 0;
|
||||||
|
|
||||||
#ifdef _FLW_EMBEDDED
|
#ifdef _FLW_EMBEDDED
|
||||||
bool _flw_embeddedLight(vec3 worldPos, vec3 normal, out vec2 lightCoord) {
|
bool _flw_embeddedLight(vec3 worldPos, out vec2 lightCoord) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue