Looks good to me

- Make SimpleMaterial.Builder implement Material itself.
- Add way to copy a material.
- Move fog/cutout shaders to their own utility classes.
- Fix crumbling on cutout materials by overriding properties.
- Add helper in glsl for unpacking 2 shorts from one uint.
- Remove Fog enum.
This commit is contained in:
Jozufozu 2023-12-02 13:00:58 -08:00
parent 8a4d319d8d
commit d4426a5f6c
13 changed files with 214 additions and 73 deletions

View file

@ -22,6 +22,8 @@ import com.jozufozu.flywheel.impl.visualization.VisualizationEventHandler;
import com.jozufozu.flywheel.lib.context.Contexts;
import com.jozufozu.flywheel.lib.instance.InstanceTypes;
import com.jozufozu.flywheel.lib.light.LightUpdater;
import com.jozufozu.flywheel.lib.material.CutoutShaders;
import com.jozufozu.flywheel.lib.material.FogShaders;
import com.jozufozu.flywheel.lib.material.StandardMaterialShaders;
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
import com.jozufozu.flywheel.lib.model.ModelCache;
@ -129,6 +131,8 @@ public class Flywheel {
private static void onClientSetup(FMLClientSetupEvent event) {
VertexTypes.init();
InstanceTypes.init();
CutoutShaders.init();
FogShaders.init();
StandardMaterialShaders.init();
Contexts.init();

View file

@ -1,16 +0,0 @@
package com.jozufozu.flywheel.api.material;
public enum Fog {
/**
* Fade out to the fog color based on distance.
*/
LINEAR,
/**
* Fade out to black based on distance.
*/
LINEAR_FADE,
/**
* No fog.
*/
NONE,
}

View file

@ -29,7 +29,7 @@ public class IndirectBuffers {
public static final long PTR_SIZE = Pointer.POINTER_SIZE;
// DRAW COMMAND
public static final long DRAW_COMMAND_STRIDE = 48;
public static final long DRAW_COMMAND_STRIDE = 52;
public static final long DRAW_COMMAND_OFFSET = 0;
// BITS
@ -109,7 +109,7 @@ public class IndirectBuffers {
}
void createObjectStorage(int objectCount) {
freeObjectStogare();
freeObjectStorage();
var objectSize = objectStride * objectCount;
var targetSize = INT_SIZE * objectCount;
@ -165,7 +165,7 @@ public class IndirectBuffers {
FlwMemoryTracker._allocGPUMemory(maxDrawCount * DRAW_COMMAND_STRIDE);
}
private void freeObjectStogare() {
private void freeObjectStorage() {
FlwMemoryTracker._freeGPUMemory(maxObjectCount * objectStride);
}
@ -199,7 +199,7 @@ public class IndirectBuffers {
public void delete() {
nglDeleteBuffers(BUFFER_COUNT, buffers.ptr());
buffers.free();
freeObjectStogare();
freeObjectStorage();
freeDrawStorage();
}
}

View file

@ -10,12 +10,17 @@ import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.material.Transparency;
import com.jozufozu.flywheel.api.material.WriteMask;
import com.jozufozu.flywheel.backend.MaterialUtil;
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
import com.jozufozu.flywheel.gl.GlStateTracker;
import com.jozufozu.flywheel.gl.GlTextureUnit;
import com.jozufozu.flywheel.lib.context.Contexts;
import com.jozufozu.flywheel.lib.material.CutoutShaders;
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
import com.mojang.blaze3d.systems.RenderSystem;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
@ -42,15 +47,20 @@ public class InstancedCrumbling {
ShaderState shader = shaderStateEntry.getKey();
var material = shader.material();
var baseMaterial = shader.material();
int diffuseTexture = getDiffuseTexture(baseMaterial);
var crumblingMaterial = SimpleMaterial.from(baseMaterial)
.transparency(Transparency.CRUMBLING)
.writeMask(WriteMask.COLOR)
.polygonOffset(true)
.cutout(CutoutShaders.OFF);
var program = InstancingPrograms.get()
.get(shader.vertexType(), shader.instanceType(), Contexts.CRUMBLING);
UniformBuffer.syncAndBind(program);
InstancingEngine.uploadMaterialIDUniform(program, material);
int renderTex = getDiffuseTexture(material);
InstancingEngine.uploadMaterialIDUniform(program, crumblingMaterial);
for (Int2ObjectMap.Entry<List<Runnable>> progressEntry : byProgress.int2ObjectEntrySet()) {
var drawCalls = progressEntry.getValue();
@ -59,17 +69,19 @@ public class InstancedCrumbling {
continue;
}
var crumblingType = ModelBakery.DESTROY_TYPES.get(progressEntry.getIntKey());
crumblingMaterial.baseTexture(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey()));
crumblingType.setupRenderState();
MaterialUtil.setup(crumblingMaterial);
RenderSystem.setShaderTexture(1, renderTex);
RenderSystem.setShaderTexture(1, diffuseTexture);
GlTextureUnit.T1.makeActive();
RenderSystem.bindTexture(renderTex);
RenderSystem.bindTexture(diffuseTexture);
drawCalls.forEach(Runnable::run);
}
}
MaterialUtil.reset();
}
}

View file

@ -0,0 +1,28 @@
package com.jozufozu.flywheel.lib.material;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.CutoutShader;
public class CutoutShaders {
/**
* Do not discard any fragments based on alpha.
*/
public static final CutoutShader OFF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/off.glsl")));
/**
* Discard fragments with alpha close to or equal to zero.
*/
public static final CutoutShader EPSILON = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/epsilon.glsl")));
/**
* Discard fragments with alpha less than to 0.5.
*/
public static final CutoutShader HALF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/half.glsl")));
private CutoutShaders() {
}
@ApiStatus.Internal
public static void init() {
}
}

View file

@ -0,0 +1,19 @@
package com.jozufozu.flywheel.lib.material;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.FogShader;
public class FogShaders {
public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/none.glsl")));
public static final FogShader LINEAR = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear.glsl")));
public static final FogShader LINEAR_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl")));
private FogShaders() {
}
@ApiStatus.Internal
public static void init() {
}
}

View file

@ -37,26 +37,26 @@ public final class Materials {
.build();
public static final Material CHUNK_CUTOUT_MIPPED_SHADED = SimpleMaterial.builder()
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(RenderType.cutoutMipped())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_CUTOUT_MIPPED_UNSHADED = SimpleMaterial.builder()
.diffuse(false)
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(RenderType.cutoutMipped())
.build();
public static final Material CHUNK_CUTOUT_SHADED = SimpleMaterial.builder()
.mip(false)
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(RenderType.cutout())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_CUTOUT_UNSHADED = SimpleMaterial.builder()
.diffuse(false)
.mip(false)
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(RenderType.cutout())
.build();
@ -73,14 +73,14 @@ public final class Materials {
public static final Material CHUNK_TRIPWIRE_SHADED = SimpleMaterial.builder()
.transparency(Transparency.TRANSLUCENT)
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(RenderType.tripwire())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_TRIPWIRE_UNSHADED = SimpleMaterial.builder()
.diffuse(false)
.transparency(Transparency.TRANSLUCENT)
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(RenderType.tripwire())
.build();
@ -93,7 +93,7 @@ public final class Materials {
.baseTexture(Sheets.SHULKER_SHEET)
.mip(false)
.backfaceCull(false)
.cutout(StandardMaterialShaders.EPSILON)
.cutout(CutoutShaders.EPSILON)
.fallbackRenderType(Sheets.shulkerBoxSheet())
.build();
public static final Material BELL = SimpleMaterial.builder()

View file

@ -50,6 +50,10 @@ public class SimpleMaterial implements Material {
return new Builder();
}
public static Builder from(Material material) {
return new Builder(material);
}
@Override
public MaterialShaders shaders() {
return shaders;
@ -117,26 +121,58 @@ public class SimpleMaterial implements Material {
@Override
public WriteMask writeMask() {
return WriteMask.BOTH;
return writeMask;
}
public static class Builder {
protected RenderType fallbackRenderType = RenderType.solid();
protected MaterialVertexTransformer vertexTransformer = (vertexList, level) -> {};
protected MaterialShaders shaders = StandardMaterialShaders.DEFAULT;
protected ResourceLocation baseTexture = InventoryMenu.BLOCK_ATLAS;
protected boolean diffuse = true;
protected boolean lighting = true;
protected boolean blur = false;
protected boolean backfaceCull = true;
protected boolean polygonOffset = false;
protected boolean mip = true;
protected FogShader fog = StandardMaterialShaders.LINEAR;
protected Transparency transparency = Transparency.OPAQUE;
protected CutoutShader cutout = StandardMaterialShaders.OFF;
protected WriteMask writeMask = WriteMask.BOTH;
public static class Builder implements Material {
protected RenderType fallbackRenderType;
protected MaterialVertexTransformer vertexTransformer;
protected MaterialShaders shaders;
protected ResourceLocation baseTexture;
protected boolean diffuse;
protected boolean lighting;
protected boolean blur;
protected boolean backfaceCull;
protected boolean polygonOffset;
protected boolean mip;
protected FogShader fog;
protected Transparency transparency;
protected CutoutShader cutout;
protected WriteMask writeMask;
public Builder() {
fallbackRenderType = RenderType.solid();
vertexTransformer = (vertexList, level) -> {
};
shaders = StandardMaterialShaders.DEFAULT;
baseTexture = InventoryMenu.BLOCK_ATLAS;
diffuse = true;
lighting = true;
blur = false;
backfaceCull = true;
polygonOffset = false;
mip = true;
fog = FogShaders.LINEAR;
transparency = Transparency.OPAQUE;
cutout = CutoutShaders.OFF;
writeMask = WriteMask.BOTH;
}
public Builder(Material material) {
fallbackRenderType = material.getFallbackRenderType();
vertexTransformer = material.getVertexTransformer();
shaders = material.shaders();
baseTexture = material.baseTexture();
diffuse = material.diffuse();
lighting = material.lighting();
blur = material.blur();
backfaceCull = material.backfaceCull();
polygonOffset = material.polygonOffset();
mip = material.mip();
fog = material.fog();
transparency = material.transparency();
cutout = material.cutout();
writeMask = material.writeMask();
}
public Builder fallbackRenderType(RenderType type) {
@ -209,6 +245,76 @@ public class SimpleMaterial implements Material {
return this;
}
@Override
public MaterialShaders shaders() {
return shaders;
}
@Override
public RenderType getFallbackRenderType() {
return fallbackRenderType;
}
@Override
public MaterialVertexTransformer getVertexTransformer() {
return vertexTransformer;
}
@Override
public ResourceLocation baseTexture() {
return baseTexture;
}
@Override
public boolean diffuse() {
return diffuse;
}
@Override
public boolean lighting() {
return lighting;
}
@Override
public boolean blur() {
return blur;
}
@Override
public boolean backfaceCull() {
return backfaceCull;
}
@Override
public boolean polygonOffset() {
return polygonOffset;
}
@Override
public boolean mip() {
return mip;
}
@Override
public FogShader fog() {
return fog;
}
@Override
public Transparency transparency() {
return transparency;
}
@Override
public CutoutShader cutout() {
return cutout;
}
@Override
public WriteMask writeMask() {
return writeMask;
}
public SimpleMaterial build() {
return new SimpleMaterial(this);
}

View file

@ -3,29 +3,11 @@ package com.jozufozu.flywheel.lib.material;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.CutoutShader;
import com.jozufozu.flywheel.api.material.FogShader;
import com.jozufozu.flywheel.api.material.MaterialShaders;
import net.minecraft.resources.ResourceLocation;
public final class StandardMaterialShaders {
/**
* Do not discard any fragments based on alpha.
*/
public static final CutoutShader OFF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/off.glsl")));
/**
* Discard fragments with alpha close to or equal to zero.
*/
public static final CutoutShader EPSILON = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/epsilon.glsl")));
/**
* Discard fragments with alpha less than to 0.5.
*/
public static final CutoutShader HALF = CutoutShader.REGISTRY.registerAndGet(new SimpleCutoutShader(Flywheel.rl("cutout/half.glsl")));
public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/none.glsl")));
public static final FogShader LINEAR = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear.glsl")));
public static final FogShader LINEAR_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl")));
public static final MaterialShaders DEFAULT = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Files.DEFAULT_VERTEX, Files.DEFAULT_FRAGMENT));

View file

@ -9,6 +9,9 @@ vec4 flw_crumblingSampleColor;
void flw_beginFragment() {
flw_crumblingSampleColor = texture(flw_crumblingTex, _flw_crumblingTexCoord);
// Make the crumbling overlay transparent when the diffuse layer is transparent.
flw_crumblingSampleColor.a *= flw_fragColor.a;
if (flw_crumblingSampleColor.a < 0.01) {
discard;
}

View file

@ -18,9 +18,8 @@ out vec4 fragColor;
void main() {
_flw_materialFragmentID = _flw_material.x;
_flw_fogID = _flw_material.y & 0xFFFFu;
_flw_cutoutID = _flw_material.y >> 16u;
_flw_unpackUint2x16(_flw_material.y, _flw_cutoutID, _flw_fogID);
_flw_unpackMaterial(_flw_material.z, flw_material);
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);

View file

@ -18,9 +18,8 @@ out vec4 fragColor;
void main() {
_flw_materialFragmentID = _flw_material_instancing.y;
_flw_fogID = _flw_material_instancing.z & 0xFFFFu;
_flw_cutoutID = _flw_material_instancing.z >> 16u;
_flw_unpackUint2x16(_flw_material_instancing.z, _flw_cutoutID, _flw_fogID);
_flw_unpackMaterial(_flw_material_instancing.w, flw_material);
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);

View file

@ -23,3 +23,8 @@ void _flw_unpackMaterial(uint m, out FlwMaterial o) {
o.writeMask = (m & WRITE_MASK_MASK) >> 6;
o.transparency = (m & TRANSPARENCY_MASK) >> 8;
}
void _flw_unpackUint2x16(uint s, out uint hi, out uint lo) {
hi = (s >> 16) & 0xFFFFu;
lo = s & 0xFFFFu;
}