probably fix all issues with ghost instances

instanced tiles on contraptions now self light properly
This commit is contained in:
JozsefA 2021-02-02 13:11:22 -08:00
parent f319dd5e8d
commit b766658415
16 changed files with 93 additions and 70 deletions

View File

@ -21,6 +21,7 @@ import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.world.LightType;
import static net.minecraft.state.properties.BlockStateProperties.FACING; import static net.minecraft.state.properties.BlockStateProperties.FACING;
@ -50,6 +51,7 @@ public class DrillRenderer extends KineticTileEntityRenderer {
float eulerX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0); float eulerX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0);
float eulerY = facing.getHorizontalAngle(); float eulerY = facing.getHorizontalAngle();
data.setPosition(context.localPos) data.setPosition(context.localPos)
.setBlockLight(contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos))
.setRotationOffset(0) .setRotationOffset(0)
.setRotationAxis(0, 0, 1) .setRotationAxis(0, 0, 1)
.setLocalRotation(eulerX, eulerY, 0); .setLocalRotation(eulerX, eulerY, 0);

View File

@ -20,6 +20,7 @@ import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.LightType;
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
@ -49,6 +50,7 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
float originOffset = 1 / 16f; float originOffset = 1 / 16f;
Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
data.setPosition(context.localPos) data.setPosition(context.localPos)
.setBlockLight(contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos))
.setRotationOffset(0) .setRotationOffset(0)
.setRotationCenter(rotOffset) .setRotationCenter(rotOffset)
.setRotationAxis(-1, 0, 0) .setRotationAxis(-1, 0, 0)
@ -80,7 +82,4 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
.getModel()) .getModel())
.renderInto(ms, buffers.getBuffer(RenderType.getCutoutMipped())); .renderInto(ms, buffers.getBuffer(RenderType.getCutoutMipped()));
} }
public static void transformHead(MatrixStack ms, float angle) {}
} }

View File

@ -1,6 +1,6 @@
package com.simibubi.create.foundation.render; package com.simibubi.create.foundation.render;
import com.simibubi.create.foundation.render.gl.Backend; import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer; import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.GlVertexArray; import com.simibubi.create.foundation.render.gl.GlVertexArray;
import com.simibubi.create.foundation.render.instancing.VertexFormat; import com.simibubi.create.foundation.render.instancing.VertexFormat;
@ -45,7 +45,7 @@ public abstract class BufferedModel extends TemplateBuffer {
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW);
// mirror it in system memory so we can write to it // mirror it in system memory so we can write to it
Backend.MAP_BUFFER.mapBuffer(GL15.GL_ARRAY_BUFFER, invariantSize, buffer -> { Backend.mapBuffer(GL15.GL_ARRAY_BUFFER, invariantSize, buffer -> {
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
copyVertex(buffer, i); copyVertex(buffer, i);
} }

View File

@ -1,8 +1,7 @@
package com.simibubi.create.foundation.render; package com.simibubi.create.foundation.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import com.simibubi.create.foundation.render.gl.Backend; import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer; import com.simibubi.create.foundation.render.gl.GlBuffer;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.client.renderer.vertex.VertexFormatElement;
@ -42,7 +41,7 @@ public class TemplateBuffer {
ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER); ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW); GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
Backend.MAP_BUFFER.mapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices -> { Backend.mapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices -> {
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
indices.putShort((short) i); indices.putShort((short) i);
} }

View File

@ -19,6 +19,7 @@ import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template; import net.minecraft.world.gen.feature.template.Template;
import net.minecraft.world.lighting.WorldLightManager; import net.minecraft.world.lighting.WorldLightManager;
@ -36,6 +37,8 @@ import java.util.Random;
public class RenderedContraption { public class RenderedContraption {
private HashMap<RenderType, ContraptionModel> renderLayers = new HashMap<>(); private HashMap<RenderType, ContraptionModel> renderLayers = new HashMap<>();
public final PlacementSimulationWorld renderWorld;
private final ContraptionLighter<?> lighter; private final ContraptionLighter<?> lighter;
public final ContraptionKineticRenderer kinetics; public final ContraptionKineticRenderer kinetics;
@ -48,10 +51,11 @@ public class RenderedContraption {
this.contraption = contraption; this.contraption = contraption;
this.lighter = contraption.makeLighter(); this.lighter = contraption.makeLighter();
this.kinetics = new ContraptionKineticRenderer(); this.kinetics = new ContraptionKineticRenderer();
this.renderWorld = setupRenderWorld(world, contraption);
buildLayers(contraption); buildLayers();
buildInstancedTiles(contraption); buildInstancedTiles();
buildActors(contraption); buildActors();
} }
public int getEntityId() { public int getEntityId() {
@ -79,34 +83,37 @@ public class RenderedContraption {
} }
} }
private void buildLayers(Contraption c) { private void buildLayers() {
for (ContraptionModel buffer : renderLayers.values()) { for (ContraptionModel buffer : renderLayers.values()) {
buffer.delete(); buffer.delete();
} }
renderLayers.clear(); renderLayers.clear();
PlacementSimulationWorld renderWorld = setupRenderWorld(c);
List<RenderType> blockLayers = RenderType.getBlockLayers(); List<RenderType> blockLayers = RenderType.getBlockLayers();
for (RenderType layer : blockLayers) { for (RenderType layer : blockLayers) {
renderLayers.put(layer, buildStructureModel(renderWorld, c, layer)); renderLayers.put(layer, buildStructureModel(renderWorld, contraption, layer));
} }
} }
private void buildInstancedTiles(Contraption c) { private void buildInstancedTiles() {
Collection<TileEntity> tileEntities = c.maybeInstancedTileEntities; Collection<TileEntity> tileEntities = contraption.maybeInstancedTileEntities;
if (!tileEntities.isEmpty()) { if (!tileEntities.isEmpty()) {
for (TileEntity te : tileEntities) { for (TileEntity te : tileEntities) {
if (te instanceof IInstanceRendered) { if (te instanceof IInstanceRendered) {
kinetics.getInstance(te); // this is enough to instantiate the model instance World world = te.getWorld();
BlockPos pos = te.getPos();
te.setLocation(renderWorld, pos);
kinetics.add(te);
te.setLocation(world, pos);
} }
} }
} }
} }
private void buildActors(Contraption c) { private void buildActors() {
List<MutablePair<Template.BlockInfo, MovementContext>> actors = c.getActors(); List<MutablePair<Template.BlockInfo, MovementContext>> actors = contraption.getActors();
for (MutablePair<Template.BlockInfo, MovementContext> actor : actors) { for (MutablePair<Template.BlockInfo, MovementContext> actor : actors) {
Template.BlockInfo blockInfo = actor.left; Template.BlockInfo blockInfo = actor.left;
@ -172,8 +179,8 @@ public class RenderedContraption {
return new ContraptionModel(builder); return new ContraptionModel(builder);
} }
public static PlacementSimulationWorld setupRenderWorld(Contraption c) { public static PlacementSimulationWorld setupRenderWorld(World world, Contraption c) {
PlacementSimulationWorld renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world); PlacementSimulationWorld renderWorld = new PlacementSimulationWorld(world);
renderWorld.setTileEntities(c.presentTileEntities.values()); renderWorld.setTileEntities(c.presentTileEntities.values());

View File

@ -1,7 +0,0 @@
package com.simibubi.create.foundation.render.gl;
import com.simibubi.create.foundation.render.gl.backend.MapBuffer;
public class Backend {
public static final MapBuffer MAP_BUFFER = MapBuffer.GL30_RANGE;
}

View File

@ -0,0 +1,20 @@
package com.simibubi.create.foundation.render.gl.backend;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
public class Backend {
private static final MapBuffer MAP_BUFFER = MapBuffer.GL30_RANGE;
private Backend() {
throw new UnsupportedOperationException();
}
public static void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
MAP_BUFFER.mapBuffer(target, offset, length, upload);
}
public static void mapBuffer(int target, int size, Consumer<ByteBuffer> upload) {
MAP_BUFFER.mapBuffer(target, 0, size, upload);
}
}

View File

@ -51,8 +51,4 @@ public enum MapBuffer {
public abstract void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload); public abstract void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload);
public final void mapBuffer(int target, int size, Consumer<ByteBuffer> upload) {
mapBuffer(target, 0, size, upload);
}
} }

View File

@ -6,7 +6,7 @@ import net.minecraft.util.ResourceLocation;
public enum AllShaderPrograms { public enum AllShaderPrograms {
ROTATING("shader/rotating.vert", "shader/instanced.frag"), ROTATING("shader/rotating.vert", "shader/instanced.frag"),
BELT("shader/belt.vert", "shader/instanced.frag"), BELT("shader/belt.vert", "shader/instanced.frag"),
CONTRAPTION_STRUCTURE("shader/contraption_structure.vert", "shader/contraption_structure.frag"), CONTRAPTION_STRUCTURE("shader/contraption_structure.vert", "shader/contraption.frag"),
CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"), CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"),
CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"), CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"),
CONTRAPTION_ACTOR("shader/contraption_actor.vert", "shader/contraption.frag"), CONTRAPTION_ACTOR("shader/contraption_actor.vert", "shader/contraption.frag"),

View File

@ -1,10 +1,9 @@
package com.simibubi.create.foundation.render.instancing; package com.simibubi.create.foundation.render.instancing;
import com.google.common.collect.Range;
import com.simibubi.create.foundation.render.BufferedModel; import com.simibubi.create.foundation.render.BufferedModel;
import com.simibubi.create.foundation.render.RenderMath; import com.simibubi.create.foundation.render.RenderMath;
import com.simibubi.create.foundation.render.gl.Backend; import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer; import com.simibubi.create.foundation.render.gl.GlBuffer;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -161,7 +160,8 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
VertexFormat instanceFormat = getInstanceFormat(); VertexFormat instanceFormat = getInstanceFormat();
int stride = instanceFormat.getStride(); int stride = instanceFormat.getStride();
int instanceSize = RenderMath.nextPowerOf2((instanceCount() + 1) * stride); int newInstanceCount = instanceCount();
int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride);
instanceVBO.bind(GL15.GL_ARRAY_BUFFER); instanceVBO.bind(GL15.GL_ARRAY_BUFFER);
@ -170,19 +170,29 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW);
glBufferSize = instanceSize; glBufferSize = instanceSize;
minIndexChanged = 0; minIndexChanged = 0;
maxIndexChanged = data.size() - 1; maxIndexChanged = newInstanceCount - 1;
} }
int offset = minIndexChanged * stride; int offset = minIndexChanged * stride;
int length = (1 + maxIndexChanged - minIndexChanged) * stride; int length = (1 + maxIndexChanged - minIndexChanged) * stride;
Backend.MAP_BUFFER.mapBuffer(GL15.GL_ARRAY_BUFFER, offset, length, buffer -> { Backend.mapBuffer(GL15.GL_ARRAY_BUFFER, offset, length, buffer -> {
for (int i = minIndexChanged; i <= maxIndexChanged; i++) { for (int i = minIndexChanged; i <= maxIndexChanged; i++) {
data.get(i).write(buffer); data.get(i).write(buffer);
} }
}); });
glInstanceCount = data.size(); if (newInstanceCount < glInstanceCount) {
int clearFrom = (maxIndexChanged + 1) * stride;
int clearTo = (glInstanceCount) * stride;
Backend.mapBuffer(GL15.GL_ARRAY_BUFFER, clearFrom, clearTo - clearFrom, buffer -> {
for (int i = clearFrom; i < clearTo; i++) {
buffer.put((byte) 0);
}
});
}
glInstanceCount = newInstanceCount;
int staticAttributes = getModelFormat().getShaderAttributeCount(); int staticAttributes = getModelFormat().getShaderAttributeCount();
instanceFormat.informAttributes(staticAttributes); instanceFormat.informAttributes(staticAttributes);

View File

@ -10,11 +10,13 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*; import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
public class StaticRotatingActorData extends InstanceData { public class StaticRotatingActorData extends InstanceData {
public static VertexFormat FORMAT = new VertexFormat(POSITION, FLOAT, NORMAL, VEC3, NORMAL); public static VertexFormat FORMAT = new VertexFormat(POSITION, LIGHT, FLOAT, NORMAL, VEC3, NORMAL);
private float x; private float x;
private float y; private float y;
private float z; private float z;
private byte blockLight;
private byte skyLight;
private float rotationOffset; private float rotationOffset;
private byte rotationAxisX; private byte rotationAxisX;
private byte rotationAxisY; private byte rotationAxisY;
@ -33,6 +35,16 @@ public class StaticRotatingActorData extends InstanceData {
return this; return this;
} }
public StaticRotatingActorData setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4);
return this;
}
public StaticRotatingActorData setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4);
return this;
}
public StaticRotatingActorData setRotationOffset(float rotationOffset) { public StaticRotatingActorData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset; this.rotationOffset = rotationOffset;
return this; return this;
@ -77,6 +89,7 @@ public class StaticRotatingActorData extends InstanceData {
@Override @Override
public void write(ByteBuffer buf) { public void write(ByteBuffer buf) {
putVec3(buf, x, y, z); putVec3(buf, x, y, z);
putVec2(buf, blockLight, skyLight);
put(buf, rotationOffset); put(buf, rotationOffset);
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ); putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
putVec3(buf, localRotationX, localRotationY, localRotationZ); putVec3(buf, localRotationX, localRotationY, localRotationZ);

View File

@ -4,6 +4,7 @@ in vec2 TexCoords;
in vec4 Color; in vec4 Color;
in float Diffuse; in float Diffuse;
in vec3 BoxCoord; in vec3 BoxCoord;
in vec2 ModelLight;
out vec4 fragColor; out vec4 fragColor;
@ -13,7 +14,7 @@ layout(binding=4) uniform sampler3D LightVolume;
vec4 light() { vec4 light() {
vec2 lm = texture(LightVolume, BoxCoord).rg * 0.9375 + 0.03125; vec2 lm = texture(LightVolume, BoxCoord).rg * 0.9375 + 0.03125;
return texture2D(LightMap, lm); return texture2D(LightMap, max(lm, ModelLight));
} }
void main() { void main() {

View File

@ -7,18 +7,20 @@ layout (location = 2) in vec2 aTexCoords;
// instance data // instance data
layout (location = 3) in vec3 instancePos; layout (location = 3) in vec3 instancePos;
layout (location = 4) in float rotationOffset; layout (location = 4) in vec2 modelLight;
layout (location = 5) in vec3 localRotationAxis; layout (location = 5) in float rotationOffset;
layout (location = 6) in vec3 localRotation; layout (location = 6) in vec3 localRotationAxis;
layout (location = 7) in vec3 rotationCenter; layout (location = 7) in vec3 localRotation;
layout (location = 8) in vec3 rotationCenter;
// dynamic data // dynamic data
//layout (location = 7) in vec3 relativeMotion; //layout (location = 9) in vec3 relativeMotion;
out float Diffuse; out float Diffuse;
out vec2 TexCoords; out vec2 TexCoords;
out vec4 Color; out vec4 Color;
out vec3 BoxCoord; out vec3 BoxCoord;
out vec2 ModelLight;
uniform vec3 lightBoxSize; uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin; uniform vec3 lightBoxMin;
@ -77,6 +79,7 @@ void main() {
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(norm); Diffuse = diffuse(norm);
TexCoords = aTexCoords; TexCoords = aTexCoords;
ModelLight = modelLight;
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) { if (debug == 2) {

View File

@ -19,6 +19,7 @@ out float Diffuse;
out vec2 TexCoords; out vec2 TexCoords;
out vec4 Color; out vec4 Color;
out vec3 BoxCoord; out vec3 BoxCoord;
out vec2 ModelLight;
uniform vec3 lightBoxSize; uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin; uniform vec3 lightBoxMin;
@ -72,6 +73,7 @@ void main() {
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(norm); Diffuse = diffuse(norm);
TexCoords = aTexCoords - uv + scrollTexture.xy + vec2(0, scroll); TexCoords = aTexCoords - uv + scrollTexture.xy + vec2(0, scroll);
ModelLight = light;
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) { if (debug == 2) {

View File

@ -15,6 +15,7 @@ out float Diffuse;
out vec2 TexCoords; out vec2 TexCoords;
out vec4 Color; out vec4 Color;
out vec3 BoxCoord; out vec3 BoxCoord;
out vec2 ModelLight;
uniform vec3 lightBoxSize; uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin; uniform vec3 lightBoxMin;
@ -67,6 +68,7 @@ void main() {
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(norm); Diffuse = diffuse(norm);
TexCoords = aTexCoords; TexCoords = aTexCoords;
ModelLight = light;
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) { if (debug == 2) {

View File

@ -1,24 +0,0 @@
#version 440 core
in vec2 TexCoords;
in vec4 Color;
in float Diffuse;
in vec3 BoxCoord;
in vec2 ModelLight;
out vec4 fragColor;
layout(binding=0) uniform sampler2D BlockAtlas;
layout(binding=2) uniform sampler2D LightMap;
layout(binding=4) uniform sampler3D LightVolume;
vec4 light() {
vec2 lm = texture(LightVolume, BoxCoord).rg * 0.9375 + 0.03125;
return texture2D(LightMap, max(lm, ModelLight));
}
void main() {
vec4 tex = texture2D(BlockAtlas, TexCoords);
fragColor = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a);
}