Usurper materials, do you have any last words?

- Pipeline shaders now implement all currently used material properties.
- Rename flw_initVertex/flw_initFragment to flw_begin*.
- Rename flw_contextVertex/flw_contextFragment to flw_end*.
- Bind the diffuse texture by hand instead of calling bindActive.
- Add cutout property to materials that need it.
This commit is contained in:
Jozufozu 2023-12-01 23:44:04 -08:00
parent 4cccc9214c
commit eb60e7d179
19 changed files with 171 additions and 87 deletions

View file

@ -15,8 +15,10 @@ public class MaterialUtil {
AbstractTexture texture = Minecraft.getInstance()
.getTextureManager()
.getTexture(material.baseTexture());
var textureId = texture.getId();
texture.setFilter(material.blur(), material.mip());
RenderSystem.setShaderTexture(0, texture.getId());
RenderSystem.setShaderTexture(0, textureId);
RenderSystem.bindTexture(textureId);
if (!material.backfaceCull()) {
RenderSystem.disableCull();

View file

@ -74,7 +74,6 @@ public class IndirectDrawSet<I extends Instance> {
private record MultiDraw(Material material, int start, int end) {
void submit() {
MaterialUtil.setup(material);
Textures.bindActiveTextures();
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, start * IndirectBuffers.DRAW_COMMAND_STRIDE, end - start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE);
MaterialUtil.clear(material);
}

View file

@ -1,5 +1,6 @@
package com.jozufozu.flywheel.lib.material;
import com.jozufozu.flywheel.api.material.Cutout;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
import com.jozufozu.flywheel.api.material.Transparency;
@ -46,6 +47,7 @@ public final class Materials {
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(RenderType.cutoutMipped())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
@ -54,6 +56,7 @@ public final class Materials {
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(true)
.shaders(StandardMaterialShaders.CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(RenderType.cutoutMipped())
.build();
@ -61,6 +64,7 @@ public final class Materials {
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(false)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(RenderType.cutout())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
@ -69,6 +73,7 @@ public final class Materials {
.baseTexture(InventoryMenu.BLOCK_ATLAS)
.mip(false)
.shaders(StandardMaterialShaders.CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(RenderType.cutout())
.build();
@ -93,6 +98,7 @@ public final class Materials {
.mip(true)
.transparency(Transparency.TRANSLUCENT)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(RenderType.tripwire())
.vertexTransformer(SHADING_TRANSFORMER)
.build();
@ -102,6 +108,7 @@ public final class Materials {
.mip(true)
.transparency(Transparency.TRANSLUCENT)
.shaders(StandardMaterialShaders.CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(RenderType.tripwire())
.build();
@ -116,6 +123,7 @@ public final class Materials {
.mip(false)
.backfaceCull(false)
.shaders(StandardMaterialShaders.SHADED_CUTOUT)
.cutout(Cutout.EPSILON)
.fallbackRenderType(Sheets.shulkerBoxSheet())
.build();
public static final Material BELL = SimpleMaterial.builder()

View file

@ -28,5 +28,5 @@ bool flw_discardPredicate(vec4 finalColor);
void flw_materialFragment();
// To be implemented by the context shader.
void flw_initFragment();
void flw_contextFragment();
void flw_beginFragment();
void flw_endFragment();

View file

@ -1,6 +1,7 @@
const uint FLW_FOG_LINEAR = 0u;
const uint FLW_FOG_LINEAR_FADE = 1u;
const uint FLW_FOG_NONE = 2u;
const uint FLW_FOG_CUSTOM = 3u;
const uint FLW_TRANSPARENCY_OPAQUE = 0u;
const uint FLW_TRANSPARENCY_ADDITIVE = 1u;
@ -12,6 +13,7 @@ const uint FLW_TRANSPARENCY_TRANSLUCENT = 5u;
const uint FLW_CUTOUT_OFF = 0u;
const uint FLW_CUTOUT_EPSILON = 1u;
const uint FLW_CUTOUT_HALF = 2u;
const uint FLW_CUTOUT_CUSTOM = 3u;
const uint FLW_WRITE_MASK_BOTH = 0u;
const uint FLW_WRITE_MASK_COLOR = 1u;

View file

@ -27,5 +27,5 @@ void flw_instanceVertex(FlwInstance i);
void flw_materialVertex();
// To be implemented by the context shader.
void flw_initVertex();
void flw_contextVertex();
void flw_beginVertex();
void flw_endVertex();

View file

@ -1,24 +1,13 @@
#include "flywheel:api/fragment.glsl"
// optimize discard usage
#ifdef ALPHA_DISCARD
#ifdef GL_ARB_conservative_depth
layout (depth_greater) out float gl_FragDepth;
#endif
#endif
uniform sampler2D flw_diffuseTex;
uniform sampler2D flw_crumblingTex;
in vec2 _flw_crumblingTexCoord;
out vec4 fragColor;
vec4 flw_crumblingSampleColor;
void flw_initFragment() {
void flw_beginFragment() {
flw_crumblingSampleColor = texture(flw_crumblingTex, _flw_crumblingTexCoord);
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
// Let the other components modify the diffuse color as they normally would.
flw_fragColor = flw_vertexColor * flw_sampleColor;
@ -26,13 +15,10 @@ void flw_initFragment() {
flw_fragLight = flw_vertexLight;
}
void flw_contextFragment() {
vec4 color = flw_fragColor;
void flw_endFragment() {
// Still need to discard based on the diffuse color so we don't crumble over empty space.
if (flw_discardPredicate(color) || flw_crumblingSampleColor.a < 0.01) {
if (flw_crumblingSampleColor.a < 0.01) {
discard;
}
fragColor = flw_fogFilter(flw_crumblingSampleColor);
}

View file

@ -65,14 +65,10 @@ vec2 getCrumblingTexCoord() {
return vec2(-flw_vertexPos.x, -flw_vertexPos.y);
}
void flw_initVertex() {
void flw_beginVertex() {
// no-op
}
void flw_contextVertex() {
void flw_endVertex() {
_flw_crumblingTexCoord = getCrumblingTexCoord();
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
flw_vertexNormal = normalize(flw_vertexNormal);
}

View file

@ -1,36 +1,9 @@
#include "flywheel:api/fragment.glsl"
// optimize discard usage
#ifdef ALPHA_DISCARD
#ifdef GL_ARB_conservative_depth
layout (depth_greater) out float gl_FragDepth;
#endif
#endif
void flw_beginFragment() {
uniform sampler2D flw_diffuseTex;
uniform sampler2D flw_overlayTex;
uniform sampler2D flw_lightTex;
out vec4 fragColor;
void flw_initFragment() {
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
flw_fragColor = flw_vertexColor * flw_sampleColor;
flw_fragOverlay = flw_vertexOverlay;
flw_fragLight = flw_vertexLight;
}
void flw_contextFragment() {
vec4 overlayColor = texelFetch(flw_overlayTex, flw_fragOverlay, 0);
vec4 lightColor = texture(flw_lightTex, (flw_fragLight * 15.0 + 0.5) / 16.0);
void flw_endFragment() {
vec4 color = flw_fragColor;
color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a);
color *= lightColor;
if (flw_discardPredicate(color)) {
discard;
}
fragColor = flw_fogFilter(color);
}

View file

@ -1,12 +1,10 @@
#include "flywheel:api/vertex.glsl"
#include "flywheel:util/fog.glsl"
void flw_initVertex() {
void flw_beginVertex() {
// noop
}
void flw_contextVertex() {
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
flw_vertexNormal = normalize(flw_vertexNormal);
void flw_endVertex() {
}

View file

@ -29,9 +29,9 @@ vec4 flw_fogFilter(vec4 color);
bool flw_discardPredicate(vec4 finalColor);
void flw_initFragment();
void flw_beginFragment();
void flw_materialFragment();
void flw_contextFragment();
void flw_endFragment();
// ------------------------------------------
// INTERNAL

View file

@ -20,10 +20,10 @@ out vec4 flw_var3;
FlwMaterial flw_material;
void flw_layoutVertex();
void flw_initVertex();
void flw_beginVertex();
void flw_instanceVertex(FlwInstance i);
void flw_materialVertex();
void flw_contextVertex();
void flw_endVertex();
// ------------------------------------------
// INTERNAL

View file

@ -1,14 +1,62 @@
#include "flywheel:internal/indirect/api/fragment.glsl"
#include "flywheel:internal/material.glsl"
// optimize discard usage
#ifdef ALPHA_DISCARD
#ifdef GL_ARB_conservative_depth
layout (depth_greater) out float gl_FragDepth;
#endif
#endif
uniform sampler2D flw_diffuseTex;
uniform sampler2D flw_overlayTex;
uniform sampler2D flw_lightTex;
flat in uvec2 _flw_material;
out vec4 fragColor;
void main() {
_flw_materialFragmentID = _flw_material.x;
_flw_unpackMaterial(_flw_material.y, flw_material);
flw_initFragment();
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
flw_fragColor = flw_vertexColor * flw_sampleColor;
flw_fragOverlay = flw_vertexOverlay;
flw_fragLight = flw_vertexLight;
flw_beginFragment();
flw_materialFragment();
flw_contextFragment();
flw_endFragment();
vec4 overlayColor = texelFetch(flw_overlayTex, flw_fragOverlay, 0);
vec4 lightColor = texture(flw_lightTex, (flw_fragLight * 15.0 + 0.5) / 16.0);
vec4 color = flw_fragColor;
color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a);
if (flw_material.lighting) {
color *= lightColor;
}
if (flw_material.cutout == FLW_CUTOUT_EPSILON && color.a < 0.01) {
discard;
} else if (flw_material.cutout == FLW_CUTOUT_HALF && color.a < 0.5) {
discard;
} else if (flw_material.cutout == FLW_CUTOUT_CUSTOM) {
if (flw_discardPredicate(color)) {
discard;
}
}
if (flw_material.fog == FLW_FOG_LINEAR) {
color = linear_fog(color, flw_distance, flywheel.fogRange.x, flywheel.fogRange.y, flywheel.fogColor);
} else if (flw_material.fog == FLW_FOG_LINEAR_FADE) {
color = linear_fog_fade(color, flw_distance, flywheel.fogRange.x, flywheel.fogRange.y);
} else if (flw_material.fog == FLW_FOG_CUSTOM) {
color = flw_fogFilter(color);
}
fragColor = color;
}

View file

@ -34,8 +34,23 @@ void main() {
_flw_material = uvec2(_flw_materialFragmentID, p);
flw_layoutVertex();
flw_initVertex();
flw_beginVertex();
flw_instanceVertex(i);
flw_materialVertex();
flw_contextVertex();
flw_endVertex();
flw_vertexNormal = normalize(flw_vertexNormal);
if (flw_material.diffuse) {
float diffuseFactor;
if (flywheel.constantAmbientLight == 1) {
diffuseFactor = diffuseNether(flw_vertexNormal);
} else {
diffuseFactor = diffuse(flw_vertexNormal);
}
flw_vertexColor = vec4(flw_vertexColor.rgb * diffuseFactor, flw_vertexColor.a);
}
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
}

View file

@ -28,9 +28,9 @@ vec4 flw_fogFilter(vec4 color);
bool flw_discardPredicate(vec4 finalColor);
void flw_initFragment();
void flw_beginFragment();
void flw_materialFragment();
void flw_contextFragment();
void flw_endFragment();
// -----------------------------------------
// INTERNAL

View file

@ -19,10 +19,10 @@ out vec4 flw_var3;
FlwMaterial flw_material;
void flw_layoutVertex();
void flw_initVertex();
void flw_beginVertex();
void flw_instanceVertex(FlwInstance i);
void flw_materialVertex();
void flw_contextVertex();
void flw_endVertex();
// ------------------------------------
// INTERNAL

View file

@ -1,5 +1,19 @@
#include "flywheel:internal/instancing/api/fragment.glsl"
#include "flywheel:internal/material.glsl"
#include "flywheel:util/fog.glsl"
// optimize discard usage
#ifdef ALPHA_DISCARD
#ifdef GL_ARB_conservative_depth
layout (depth_greater) out float gl_FragDepth;
#endif
#endif
uniform sampler2D flw_diffuseTex;
uniform sampler2D flw_overlayTex;
uniform sampler2D flw_lightTex;
out vec4 fragColor;
void main() {
_flw_materialVertexID = _flw_material_instancing.x;
@ -7,7 +21,42 @@ void main() {
_flw_unpackMaterial(_flw_material_instancing.z, flw_material);
flw_initFragment();
flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
flw_fragColor = flw_vertexColor * flw_sampleColor;
flw_fragOverlay = flw_vertexOverlay;
flw_fragLight = flw_vertexLight;
flw_beginFragment();
flw_materialFragment();
flw_contextFragment();
flw_endFragment();
vec4 overlayColor = texelFetch(flw_overlayTex, flw_fragOverlay, 0);
vec4 lightColor = texture(flw_lightTex, (flw_fragLight * 15.0 + 0.5) / 16.0);
vec4 color = flw_fragColor;
color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a);
if (flw_material.lighting) {
color *= lightColor;
}
if (flw_material.cutout == FLW_CUTOUT_EPSILON && color.a < 0.01) {
discard;
} else if (flw_material.cutout == FLW_CUTOUT_HALF && color.a < 0.5) {
discard;
} else if (flw_material.cutout == FLW_CUTOUT_CUSTOM) {
if (flw_discardPredicate(color)) {
discard;
}
}
if (flw_material.fog == FLW_FOG_LINEAR) {
color = linear_fog(color, flw_distance, flywheel.fogRange.x, flywheel.fogRange.y, flywheel.fogColor);
} else if (flw_material.fog == FLW_FOG_LINEAR_FADE) {
color = linear_fog_fade(color, flw_distance, flywheel.fogRange.x, flywheel.fogRange.y);
} else if (flw_material.fog == FLW_FOG_CUSTOM) {
color = flw_fogFilter(color);
}
fragColor = color;
}

View file

@ -1,5 +1,6 @@
#include "flywheel:internal/instancing/api/vertex.glsl"
#include "flywheel:internal/material.glsl"
#include "flywheel:util/diffuse.glsl"
void main() {
_flw_materialVertexID = _flw_material_instancing.x;
@ -10,8 +11,23 @@ void main() {
FlwInstance i = _flw_unpackInstance();
flw_layoutVertex();
flw_initVertex();
flw_beginVertex();
flw_instanceVertex(i);
flw_materialVertex();
flw_contextVertex();
flw_endVertex();
flw_vertexNormal = normalize(flw_vertexNormal);
if (flw_material.diffuse) {
float diffuseFactor;
if (flywheel.constantAmbientLight == 1) {
diffuseFactor = diffuseNether(flw_vertexNormal);
} else {
diffuseFactor = diffuse(flw_vertexNormal);
}
flw_vertexColor = vec4(flw_vertexColor.rgb * diffuseFactor, flw_vertexColor.a);
}
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
}

View file

@ -2,13 +2,5 @@
#include "flywheel:util/diffuse.glsl"
void flw_materialVertex() {
flw_vertexNormal = normalize(flw_vertexNormal);
float diffuseFactor;
if (flywheel.constantAmbientLight == 1) {
diffuseFactor = diffuseNether(flw_vertexNormal);
} else {
diffuseFactor = diffuse(flw_vertexNormal);
}
flw_vertexColor = vec4(flw_vertexColor.rgb * diffuseFactor, flw_vertexColor.a);
}