We have shards at home

- Break material setup into constituent parts.
- Sort materials by what they setup.
- Fix some shader issues.
This commit is contained in:
Jozufozu 2023-12-02 00:40:54 -08:00
parent 90ae50a5ca
commit 5ae01e4899
6 changed files with 100 additions and 32 deletions

View file

@ -13,4 +13,13 @@ public enum WriteMask {
* Write to the depth buffer only.
*/
DEPTH,
;
public boolean depth() {
return this == BOTH || this == DEPTH;
}
public boolean color() {
return this == BOTH || this == COLOR;
}
}

View file

@ -1,7 +1,10 @@
package com.jozufozu.flywheel.backend;
import java.util.Comparator;
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.gl.GlTextureUnit;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
@ -10,7 +13,59 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AbstractTexture;
public class MaterialUtil {
public static final Comparator<Material> BY_STATE = Comparator.comparing(Material::baseTexture)
.thenComparing(Material::mip)
.thenComparing(Material::blur)
.thenComparing(Material::backfaceCull)
.thenComparing(Material::polygonOffset)
.thenComparing(Material::writeMask);
public static void setup(Material material) {
setupTexture(material);
setupBackfaceCull(material.backfaceCull());
setupTransparency(material.transparency());
setupWriteMask(material.writeMask());
setupPolygonOffset(material.polygonOffset());
}
private static void setupPolygonOffset(boolean polygonOffset) {
if (polygonOffset) {
RenderSystem.polygonOffset(-1.0F, -10.0F);
RenderSystem.enablePolygonOffset();
}
}
private static void setupWriteMask(WriteMask mask) {
RenderSystem.depthMask(mask.depth());
boolean writeColor = mask.color();
RenderSystem.colorMask(writeColor, writeColor, writeColor, writeColor);
}
private static void setupTransparency(Transparency transparency) {
if (transparency != Transparency.OPAQUE) {
RenderSystem.enableBlend();
}
switch (transparency) {
case ADDITIVE -> RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE);
case LIGHTING -> RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE);
case GLINT ->
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_COLOR, GlStateManager.DestFactor.ONE, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE);
case CRUMBLING ->
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
case TRANSLUCENT ->
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
}
}
private static void setupBackfaceCull(boolean backfaceCull) {
if (!backfaceCull) {
RenderSystem.disableCull();
}
}
private static void setupTexture(Material material) {
GlTextureUnit.T0.makeActive();
AbstractTexture texture = Minecraft.getInstance()
.getTextureManager()
@ -19,29 +74,38 @@ public class MaterialUtil {
texture.setFilter(material.blur(), material.mip());
RenderSystem.setShaderTexture(0, textureId);
RenderSystem.bindTexture(textureId);
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) {
public static void reset() {
resetDiffuse();
resetBackfaceCull();
resetTransparency();
resetWriteMask();
resetPolygonOffset();
}
private static void resetPolygonOffset() {
RenderSystem.polygonOffset(0.0F, 0.0F);
RenderSystem.disablePolygonOffset();
}
private static void resetWriteMask() {
RenderSystem.depthMask(true);
RenderSystem.colorMask(true, true, true, true);
}
private static void resetTransparency() {
RenderSystem.disableBlend();
RenderSystem.defaultBlendFunc();
}
private static void resetBackfaceCull() {
RenderSystem.enableCull();
}
private static void resetDiffuse() {
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;

View file

@ -42,14 +42,14 @@ public class IndirectDrawSet<I extends Instance> {
for (var multiDraw : multiDraws.get(stage)) {
multiDraw.submit();
}
MaterialUtil.reset();
}
public void determineMultiDraws() {
// TODO: Better material equality. Really we only need to bin by the results of the setup method.
multiDraws.clear();
// sort by stage, then material
indirectDraws.sort(Comparator.comparing(IndirectDraw<I>::stage)
.thenComparing(draw -> draw.material().hashCode()));
.thenComparing(IndirectDraw::material, MaterialUtil.BY_STATE));
for (int start = 0, i = 0; i < indirectDraws.size(); i++) {
var draw = indirectDraws.get(i);
@ -75,7 +75,6 @@ public class IndirectDrawSet<I extends Instance> {
void submit() {
MaterialUtil.setup(material);
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, start * IndirectBuffers.DRAW_COMMAND_STRIDE, end - start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE);
MaterialUtil.clear(material);
}
}
}

View file

@ -120,7 +120,7 @@ public class InstancingEngine extends AbstractEngine {
drawCall.render();
}
MaterialUtil.clear(shader.material());
MaterialUtil.reset();
}
}

View file

@ -9,16 +9,11 @@ vec4 flw_crumblingSampleColor;
void flw_beginFragment() {
flw_crumblingSampleColor = texture(flw_crumblingTex, _flw_crumblingTexCoord);
// Let the other components modify the diffuse color as they normally would.
flw_fragColor = flw_vertexColor * flw_sampleColor;
flw_fragOverlay = flw_vertexOverlay;
flw_fragLight = flw_vertexLight;
}
void flw_endFragment() {
// Still need to discard based on the diffuse color so we don't crumble over empty space.
if (flw_crumblingSampleColor.a < 0.01) {
discard;
}
}
void flw_endFragment() {
flw_fragColor = flw_crumblingSampleColor;
}

View file

@ -1,6 +1,7 @@
#include "flywheel:internal/indirect/api/vertex.glsl"
#include "flywheel:internal/indirect/mesh.glsl"
#include "flywheel:internal/material.glsl"
#include "flywheel:util/diffuse.glsl"
flat out uvec2 _flw_material;