Materials and You: Volume 2

- Make the state provided by materials explicit
- Add utility to pack material properties into an int for use in shaders
This commit is contained in:
Jozufozu 2023-11-30 23:16:23 -08:00
parent b7cbc29764
commit b947470089
18 changed files with 465 additions and 156 deletions

View file

@ -0,0 +1,16 @@
package com.jozufozu.flywheel.api.material;
public enum Cutout {
/**
* Do not discard any fragments based on alpha.
*/
OFF,
/**
* Discard fragments with alpha close to or equal to zero.
*/
EPSILON,
/**
* Discard fragments with alpha less than to 0.5.
*/
HALF,
}

View file

@ -0,0 +1,16 @@
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

@ -1,15 +1,54 @@
package com.jozufozu.flywheel.api.material;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation;
public interface Material {
void setup();
void clear();
MaterialShaders shaders();
RenderType getFallbackRenderType();
MaterialVertexTransformer getVertexTransformer();
MaterialShaders shaders();
ResourceLocation baseTexture();
/**
* Should this material be rendered with diffuse lighting?
*
* @return {@code true} if this material should be rendered with diffuse lighting.
*/
boolean diffuse();
/**
* Should this material be rendered with block/sky lighting?
*
* @return {@code true} if this material should be rendered with block/sky lighting.
*/
boolean lighting();
/**
* Should this material have linear filtering applied to the diffuse sampler?
*
* @return {@code true} if this material should be rendered with blur.
*/
boolean blur();
/**
* Should this material be rendered with backface culling?
*
* @return {@code true} if this material should be rendered with backface culling.
*/
boolean backfaceCull();
boolean polygonOffset();
boolean mip();
Fog fog();
Transparency transparency();
Cutout cutout();
WriteMask writeMask();
}

View file

@ -0,0 +1,10 @@
package com.jozufozu.flywheel.api.material;
public enum Transparency {
OPAQUE,
ADDITIVE,
LIGHTING,
GLINT,
CRUMBLING,
TRANSLUCENT,
}

View file

@ -0,0 +1,16 @@
package com.jozufozu.flywheel.api.material;
public enum WriteMask {
/**
* Write to both the color and depth buffers.
*/
BOTH,
/**
* Write to the color buffer only.
*/
COLOR,
/**
* Write to the depth buffer only.
*/
DEPTH,
}

View file

@ -0,0 +1,77 @@
package com.jozufozu.flywheel.backend;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.material.Transparency;
import com.jozufozu.flywheel.gl.GlTextureUnit;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AbstractTexture;
public class MaterialUtil {
public static void setup(Material material) {
GlTextureUnit.T0.makeActive();
AbstractTexture texture = Minecraft.getInstance()
.getTextureManager()
.getTexture(material.baseTexture());
texture.setFilter(material.blur(), material.mip());
RenderSystem.setShaderTexture(0, texture.getId());
if (!material.backfaceCull()) {
RenderSystem.disableCull();
}
if (material.transparency() != Transparency.OPAQUE) {
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
}
}
public static void clear(Material material) {
GlTextureUnit.T0.makeActive();
RenderSystem.setShaderTexture(0, 0);
if (!material.backfaceCull()) {
RenderSystem.enableCull();
}
if (material.transparency() != Transparency.OPAQUE) {
RenderSystem.disableBlend();
RenderSystem.defaultBlendFunc();
}
}
public static final int DIFFUSE_MASK = 1;
public static final int LIGHTING_MASK = 1 << 1;
public static final int BLUR_MASK = 1 << 2;
public static final int BACKFACE_CULL_MASK = 1 << 3;
public static final int POLYGON_OFFSET_MASK = 1 << 4;
public static final int MIP_MASK = 1 << 5;
public static final int FOG_MASK = 0b11000000;
public static final int TRANSPARENCY_MASK = 0b11100000000;
public static final int CUTOUT_MASK = 0b1100000000000;
public static final int WRITE_MASK_MASK = 0b110000000000000;
public static int packProperties(Material material) {
int out = 0;
if (material.diffuse()) out |= DIFFUSE_MASK;
if (material.lighting()) out |= LIGHTING_MASK;
if (material.blur()) out |= BLUR_MASK;
if (material.backfaceCull()) out |= BACKFACE_CULL_MASK;
if (material.polygonOffset()) out |= POLYGON_OFFSET_MASK;
if (material.mip()) out |= MIP_MASK;
out |= (material.fog()
.ordinal() & 0x3) << 6;
out |= (material.transparency()
.ordinal() & 0x7) << 8;
out |= (material.cutout()
.ordinal() & 0x3) << 11;
out |= (material.writeMask()
.ordinal() & 0x3) << 13;
return out;
}
}

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.MaterialShaderIndices;
import com.jozufozu.flywheel.backend.MaterialUtil;
public class IndirectDraw<I extends Instance> {
private final IndirectInstancer<I> instancer;
@ -15,6 +16,7 @@ public class IndirectDraw<I extends Instance> {
private final int vertexMaterialID;
private final int fragmentMaterialID;
private final int packedMaterialProperties;
private int baseInstance = -1;
private boolean needsFullWrite = true;
@ -27,6 +29,7 @@ public class IndirectDraw<I extends Instance> {
this.vertexMaterialID = MaterialShaderIndices.getVertexShaderIndex(material.shaders());
this.fragmentMaterialID = MaterialShaderIndices.getFragmentShaderIndex(material.shaders());
this.packedMaterialProperties = MaterialUtil.packProperties(material);
}
public IndirectInstancer<I> instancer() {
@ -75,5 +78,6 @@ public class IndirectDraw<I extends Instance> {
boundingSphere.getToAddress(ptr + 20); // boundingSphere
MemoryUtil.memPutInt(ptr + 36, vertexMaterialID); // vertexMaterialID
MemoryUtil.memPutInt(ptr + 40, fragmentMaterialID); // fragmentMaterialID
MemoryUtil.memPutInt(ptr + 44, packedMaterialProperties); // packedMaterialProperties
}
}

View file

@ -13,6 +13,7 @@ import java.util.Map;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.MaterialUtil;
public class IndirectDrawSet<I extends Instance> {
@ -72,10 +73,10 @@ public class IndirectDrawSet<I extends Instance> {
private record MultiDraw(Material material, int start, int end) {
void submit() {
material.setup();
MaterialUtil.setup(material);
Textures.bindActiveTextures();
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, start * IndirectBuffers.DRAW_COMMAND_STRIDE, end - start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE);
material.clear();
MaterialUtil.clear(material);
}
}
}

View file

@ -20,6 +20,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelBakery;
public class InstancedCrumbling {
@ -109,11 +110,9 @@ public class InstancedCrumbling {
}
private static int getDiffuseTexture(Material material) {
material.setup();
int out = RenderSystem.getShaderTexture(0);
material.clear();
return out;
return Minecraft.getInstance()
.getTextureManager()
.getTexture(material.baseTexture())
.getId();
}
}

View file

@ -10,6 +10,7 @@ import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.task.Plan;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.backend.MaterialShaderIndices;
import com.jozufozu.flywheel.backend.MaterialUtil;
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
import com.jozufozu.flywheel.backend.engine.AbstractEngine;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
@ -113,20 +114,21 @@ public class InstancingEngine extends AbstractEngine {
uploadMaterialIDUniform(program, shader.material());
shader.material().setup();
MaterialUtil.setup(shader.material());
for (var drawCall : drawCalls) {
drawCall.render();
}
shader.material().clear();
MaterialUtil.clear(shader.material());
}
}
public static void uploadMaterialIDUniform(GlProgram program, Material material) {
int materialIDUniform = program.getUniformLocation("_flw_materialID_instancing");
int materialIDUniform = program.getUniformLocation("_flw_material_instancing");
int vertexID = MaterialShaderIndices.getVertexShaderIndex(material.shaders());
int fragmentID = MaterialShaderIndices.getFragmentShaderIndex(material.shaders());
GL32.glUniform2ui(materialIDUniform, vertexID, fragmentID);
int packedMaterialProperties = MaterialUtil.packProperties(material);
GL32.glUniform3ui(materialIDUniform, vertexID, fragmentID, packedMaterialProperties);
}
}

View file

@ -2,17 +2,12 @@ package com.jozufozu.flywheel.lib.material;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
import com.jozufozu.flywheel.gl.GlTextureUnit;
import com.jozufozu.flywheel.lib.material.SimpleMaterial.GlStateShard;
import com.jozufozu.flywheel.api.material.Transparency;
import com.jozufozu.flywheel.lib.math.DiffuseLightCalculator;
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu;
@ -34,126 +29,108 @@ public final class Materials {
private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
public static final Material CHUNK_SOLID_SHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.shaders(StandardMaterialShaders.SHADED)
.fallbackRenderType(RenderType.solid())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_SOLID_UNSHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.diffuse(false)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.fallbackRenderType(RenderType.solid())
.build();
public static final Material CHUNK_CUTOUT_MIPPED_SHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.fallbackRenderType(RenderType.cutoutMipped())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_CUTOUT_MIPPED_UNSHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.diffuse(false)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.shaders(StandardMaterialShaders.CUTOUT)
.fallbackRenderType(RenderType.cutoutMipped())
.build();
public static final Material CHUNK_CUTOUT_SHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false))
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(false)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.fallbackRenderType(RenderType.cutout())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_CUTOUT_UNSHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false))
.diffuse(false)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(false)
.shaders(StandardMaterialShaders.CUTOUT)
.fallbackRenderType(RenderType.cutout())
.build();
public static final Material CHUNK_TRANSLUCENT_SHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.addShard(Shards.TRANSLUCENT_TRANSPARENCY)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.transparency(Transparency.TRANSLUCENT)
.shaders(StandardMaterialShaders.SHADED)
.fallbackRenderType(RenderType.translucent())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_TRANSLUCENT_UNSHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.addShard(Shards.TRANSLUCENT_TRANSPARENCY)
.diffuse(false)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.transparency(Transparency.TRANSLUCENT)
.fallbackRenderType(RenderType.translucent())
.build();
public static final Material CHUNK_TRIPWIRE_SHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.addShard(Shards.TRANSLUCENT_TRANSPARENCY)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.transparency(Transparency.TRANSLUCENT)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.fallbackRenderType(RenderType.tripwire())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
public static final Material CHUNK_TRIPWIRE_UNSHADED = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true))
.addShard(Shards.TRANSLUCENT_TRANSPARENCY)
.diffuse(false)
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.transparency(Transparency.TRANSLUCENT)
.shaders(StandardMaterialShaders.CUTOUT)
.fallbackRenderType(RenderType.tripwire())
.build();
public static final Material CHEST = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(Sheets.CHEST_SHEET, false, false))
.baseTexture(Sheets.CHEST_SHEET)
.mip(false)
.shaders(StandardMaterialShaders.SHADED)
.fallbackRenderType(Sheets.chestSheet())
.build();
public static final Material SHULKER = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(Sheets.SHULKER_SHEET, false, false))
.addShard(Shards.DISABLE_CULL)
.baseTexture(Sheets.SHULKER_SHEET)
.mip(false)
.backfaceCull(false)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.fallbackRenderType(Sheets.shulkerBoxSheet())
.build();
public static final Material BELL = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false))
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(false)
.shaders(StandardMaterialShaders.SHADED)
.fallbackRenderType(Sheets.solidBlockSheet())
.build();
public static final Material MINECART = SimpleMaterial.builder()
.addShard(Shards.diffuseTex(MINECART_LOCATION, false, false))
.baseTexture(MINECART_LOCATION)
.mip(false)
.shaders(StandardMaterialShaders.SHADED)
.fallbackRenderType(RenderType.entitySolid(MINECART_LOCATION))
.build();
private Materials() {
}
public static final class Shards {
public static final GlStateShard DISABLE_CULL = new GlStateShard(
() -> {
RenderSystem.disableCull();
},
() -> {
RenderSystem.enableCull();
}
);
public static final GlStateShard TRANSLUCENT_TRANSPARENCY = new GlStateShard(
() -> {
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
},
() -> {
RenderSystem.disableBlend();
RenderSystem.defaultBlendFunc();
}
);
public static GlStateShard diffuseTex(ResourceLocation loc, boolean blur, boolean mipmap) {
return new GlStateShard(
() -> {
GlTextureUnit.T0.makeActive();
AbstractTexture texture = Minecraft.getInstance().getTextureManager().getTexture(loc);
texture.setFilter(blur, mipmap);
RenderSystem.setShaderTexture(0, texture.getId());
},
() -> {
GlTextureUnit.T0.makeActive();
RenderSystem.setShaderTexture(0, 0);
}
);
}
}
}

View file

@ -1,41 +1,55 @@
package com.jozufozu.flywheel.lib.material;
import com.jozufozu.flywheel.api.material.Cutout;
import com.jozufozu.flywheel.api.material.Fog;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.material.MaterialShaders;
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
import com.jozufozu.flywheel.api.material.Transparency;
import com.jozufozu.flywheel.api.material.WriteMask;
import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu;
public class SimpleMaterial implements Material {
protected final Runnable setup;
protected final Runnable clear;
protected final MaterialShaders shaders;
protected final RenderType fallbackRenderType;
protected final MaterialVertexTransformer vertexTransformer;
public SimpleMaterial(Runnable setup, Runnable clear, MaterialShaders shaders, RenderType fallbackRenderType, MaterialVertexTransformer vertexTransformer) {
this.setup = setup;
this.clear = clear;
this.shaders = shaders;
this.fallbackRenderType = fallbackRenderType;
this.vertexTransformer = vertexTransformer;
protected final ResourceLocation baseTexture;
protected final boolean diffuse;
protected final boolean lighting;
protected final boolean blur;
protected final boolean backfaceCull;
protected final boolean polygonOffset;
protected final boolean mip;
protected final Fog fog;
protected final Transparency transparency;
protected final Cutout cutout;
protected final WriteMask writeMask;
protected SimpleMaterial(Builder builder) {
this.shaders = builder.shaders;
this.fallbackRenderType = builder.fallbackRenderType;
this.vertexTransformer = builder.vertexTransformer;
this.baseTexture = builder.baseTexture;
this.diffuse = builder.diffuse;
this.lighting = builder.lighting;
this.blur = builder.blur;
this.backfaceCull = builder.backfaceCull;
this.polygonOffset = builder.polygonOffset;
this.mip = builder.mip;
this.fog = builder.fog;
this.transparency = builder.transparency;
this.cutout = builder.cutout;
this.writeMask = builder.writeMask;
}
public static Builder builder() {
return new Builder();
}
@Override
public void setup() {
setup.run();
}
@Override
public void clear() {
clear.run();
}
@Override
public MaterialShaders shaders() {
return shaders;
@ -51,37 +65,80 @@ public class SimpleMaterial implements Material {
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 Fog fog() {
return fog;
}
@Override
public Transparency transparency() {
return transparency;
}
@Override
public Cutout cutout() {
return cutout;
}
@Override
public WriteMask writeMask() {
return WriteMask.BOTH;
}
public static class Builder {
protected Runnable setup = () -> {};
protected Runnable clear = () -> {};
protected MaterialShaders shaders = StandardMaterialShaders.DEFAULT;
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 Fog fog = Fog.LINEAR;
protected Transparency transparency = Transparency.OPAQUE;
protected Cutout cutout = Cutout.OFF;
protected WriteMask writeMask = WriteMask.BOTH;
public Builder() {
}
public Builder addSetup(Runnable setup) {
this.setup = chain(this.setup, setup);
return this;
}
public Builder addClear(Runnable clear) {
this.clear = chain(this.clear, clear);
return this;
}
public Builder addShard(GlStateShard shard) {
addSetup(shard.getSetup());
addClear(shard.getClear());
return this;
}
public Builder shaders(MaterialShaders shaders) {
this.shaders = shaders;
return this;
}
public Builder fallbackRenderType(RenderType type) {
this.fallbackRenderType = type;
return this;
@ -92,37 +149,68 @@ public class SimpleMaterial implements Material {
return this;
}
public Builder shaders(MaterialShaders value) {
this.shaders = value;
return this;
}
public Builder baseTexture(ResourceLocation value) {
this.baseTexture = value;
return this;
}
public Builder diffuse(boolean value) {
this.diffuse = value;
return this;
}
public Builder lighting(boolean value) {
this.lighting = value;
return this;
}
public Builder blur(boolean value) {
this.blur = value;
return this;
}
public Builder backfaceCull(boolean value) {
this.backfaceCull = value;
return this;
}
public Builder polygonOffset(boolean value) {
this.polygonOffset = value;
return this;
}
public Builder mip(boolean value) {
this.mip = value;
return this;
}
public Builder fog(Fog value) {
this.fog = value;
return this;
}
public Builder transparency(Transparency value) {
this.transparency = value;
return this;
}
public Builder cutout(Cutout value) {
this.cutout = value;
return this;
}
public Builder writeMask(WriteMask value) {
this.writeMask = value;
return this;
}
public SimpleMaterial build() {
return new SimpleMaterial(setup, clear, shaders, fallbackRenderType, vertexTransformer);
}
private static Runnable chain(Runnable runnable1, Runnable runnable2) {
return () -> {
runnable1.run();
runnable2.run();
};
}
}
public static class GlStateShard {
protected final Runnable setup;
protected final Runnable clear;
public GlStateShard(Runnable setup, Runnable clear) {
this.setup = setup;
this.clear = clear;
}
public static GlStateShard fromVanilla(RenderStateShard vanillaShard) {
return new GlStateShard(vanillaShard::setupRenderState, vanillaShard::clearRenderState);
}
public Runnable getSetup() {
return setup;
}
public Runnable getClear() {
return clear;
return new SimpleMaterial(this);
}
}
}

View file

@ -14,6 +14,7 @@ in vec4 flw_var2;
in vec4 flw_var3;
flat in uint _flw_materialFragmentID;
flat in uint _flw_packedMaterialProperties;
//

View file

@ -15,4 +15,5 @@ out vec4 flw_var1;
out vec4 flw_var2;
out vec4 flw_var3;
flat out uint _flw_materialFragmentID;
flat out uint _flw_packedMaterialProperties;
#endif

View file

@ -26,6 +26,7 @@ void main() {
_flw_materialVertexID = drawCommands[batchID].vertexMaterialID;
_flw_materialFragmentID = drawCommands[batchID].fragmentMaterialID;
_flw_packedMaterialProperties = drawCommands[batchID].packedMaterialProperties;
flw_layoutVertex();
flw_initVertex();

View file

@ -20,4 +20,5 @@ struct MeshDrawCommand {
BoundingSphere boundingSphere;
uint vertexMaterialID;
uint fragmentMaterialID;
uint packedMaterialProperties;
};

View file

@ -1,10 +1,11 @@
#include "flywheel:api/vertex.glsl"
uniform uvec2 _flw_materialID_instancing;
uniform uvec3 _flw_material_instancing;
void main() {
_flw_materialVertexID = _flw_materialID_instancing.x;
_flw_materialFragmentID = _flw_materialID_instancing.y;
_flw_materialVertexID = _flw_material_instancing.x;
_flw_materialFragmentID = _flw_material_instancing.y;
_flw_packedMaterialProperties = _flw_material_instancing.z;
FlwInstance i = _flw_unpackInstance();

View file

@ -0,0 +1,59 @@
const uint LINEAR = 0;
const uint LINEAR_FADE = 1;
const uint NONE = 2;
const uint OPAQUE_TRANSPARENCY = 0;
const uint ADDITIVE_TRANSPARENCY = 1;
const uint LIGHTING_TRANSPARENCY = 2;
const uint GLINT_TRANSPARENCY = 3;
const uint CRUMBLING_TRANSPARENCY = 4;
const uint TRANSLUCENT_TRANSPARENCY = 5;
const uint CUTOUT_OFF = 0;
const uint CUTOUT_EPSILON = 1;
const uint CUTOUT_HALF = 2;
const uint WRITE_MASK_BOTH = 0;
const uint WRITE_MASK_COLOR = 1;
const uint WRITE_MASK_DEPTH = 2;
struct Material {
bool diffuse;
bool lighting;
bool blur;
bool backfaceCull;
bool polygonOffset;
bool mip;
uint fog;
uint transparency;
uint cutout;
uint writeMask;
};
// Packed format:
// writeMask[2] | cutout[2] | transparency[3] | fog[2] | mip[1] | polygonOffset[1] | backfaceCull[1] | blur[1] | lighting[1] | diffuse[1]
const uint DIFFUSE_MASK = 1;
const uint LIGHTING_MASK = 1 << 1;
const uint BLUR_MASK = 1 << 2;
const uint BACKFACE_CULL_MASK = 1 << 3;
const uint POLYGON_OFFSET_MASK = 1 << 4;
const uint MIP_MASK = 1 << 5;
const uint FOG_MASK = 3 << 6;
const uint TRANSPARENCY_MASK = 7 << 8;
const uint CUTOUT_MASK = 3 << 11;
const uint WRITE_MASK_MASK = 3 << 13;
void unpackMaterial(uint m, out Material o) {
o.diffuse = (m & DIFFUSE_MASK) != 0;
o.lighting = (m & LIGHTING_MASK) != 0;
o.blur = (m & BLUR_MASK) != 0;
o.backfaceCull = (m & BACKFACE_CULL_MASK) != 0;
o.polygonOffset = (m & POLYGON_OFFSET_MASK) != 0;
o.mip = (m & MIP_MASK) != 0;
o.fog = (m & FOG_MASK) >> 6;
o.transparency = (m & TRANSPARENCY_MASK) >> 8;
o.cutout = (m & CUTOUT_MASK) >> 11;
o.writeMask = (m & WRITE_MASK_MASK) >> 13;
}