mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-10 12:34:11 +01:00
Uber smooth
- Add material shader component to specify smooth lighting behavior - Allows much easier composition of smooth lighting/material shader effects, and potentially gives backends the option to specialize shaders on the complexity of shader lighting - Pack fog, cutout, and light into a single uint
This commit is contained in:
parent
cdc68244e7
commit
69411fb36f
@ -0,0 +1,11 @@
|
||||
package dev.engine_room.flywheel.api.material;
|
||||
|
||||
import dev.engine_room.flywheel.api.internal.FlwApiLink;
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface LightShader {
|
||||
Registry<LightShader> REGISTRY = FlwApiLink.INSTANCE.createRegistry();
|
||||
|
||||
ResourceLocation source();
|
||||
}
|
@ -9,6 +9,8 @@ public interface Material {
|
||||
|
||||
CutoutShader cutout();
|
||||
|
||||
LightShader light();
|
||||
|
||||
ResourceLocation texture();
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@ import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
||||
import dev.engine_room.flywheel.api.material.FogShader;
|
||||
import dev.engine_room.flywheel.api.material.LightShader;
|
||||
import dev.engine_room.flywheel.api.material.MaterialShaders;
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
@ -25,6 +26,8 @@ public final class MaterialShaderIndices {
|
||||
private static Index fogSources;
|
||||
@Nullable
|
||||
private static Index cutoutSources;
|
||||
@Nullable
|
||||
private static Index lightSources;
|
||||
|
||||
private MaterialShaderIndices() {
|
||||
}
|
||||
@ -57,6 +60,13 @@ public final class MaterialShaderIndices {
|
||||
return cutoutSources;
|
||||
}
|
||||
|
||||
public static Index lightSources() {
|
||||
if (lightSources == null) {
|
||||
lightSources = indexFromRegistry(LightShader.REGISTRY, LightShader::source);
|
||||
}
|
||||
return lightSources;
|
||||
}
|
||||
|
||||
public static int vertexIndex(MaterialShaders shaders) {
|
||||
return vertexSources().index(shaders.vertexSource());
|
||||
}
|
||||
@ -73,6 +83,10 @@ public final class MaterialShaderIndices {
|
||||
return cutoutSources().index(cutoutShader.source());
|
||||
}
|
||||
|
||||
public static int lightIndex(LightShader lightShader) {
|
||||
return lightSources().index(lightShader.source());
|
||||
}
|
||||
|
||||
private static <T> Index indexFromRegistry(Registry<T> registry, Function<T, ResourceLocation> sourceFunc) {
|
||||
if (!registry.isFrozen()) {
|
||||
throw new IllegalStateException("Cannot create index from registry that is not frozen!");
|
||||
|
@ -46,15 +46,16 @@ public final class FlwPrograms {
|
||||
var fragmentMaterialComponent = createFragmentMaterialComponent(loader);
|
||||
var fogComponent = createFogComponent(loader);
|
||||
var cutoutComponent = createCutoutComponent(loader);
|
||||
var lightComponent = createLightComponent(loader);
|
||||
|
||||
if (stats.errored() || vertexComponentsHeader == null || fragmentComponentsHeader == null || vertexMaterialComponent == null || fragmentMaterialComponent == null || fogComponent == null || cutoutComponent == null) {
|
||||
if (stats.errored() || vertexComponentsHeader == null || fragmentComponentsHeader == null || vertexMaterialComponent == null || fragmentMaterialComponent == null || fogComponent == null || cutoutComponent == null || lightComponent == null) {
|
||||
// Probably means the shader sources are missing.
|
||||
stats.emitErrorLog();
|
||||
return;
|
||||
}
|
||||
|
||||
List<SourceComponent> vertexComponents = List.of(vertexComponentsHeader, vertexMaterialComponent);
|
||||
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fragmentMaterialComponent, fogComponent, cutoutComponent);
|
||||
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fragmentMaterialComponent, fogComponent, cutoutComponent, lightComponent);
|
||||
|
||||
var pipelineKeys = createPipelineKeys();
|
||||
InstancingPrograms.reload(sources, pipelineKeys, vertexComponents, fragmentComponents);
|
||||
@ -118,4 +119,17 @@ public final class FlwPrograms {
|
||||
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
|
||||
.build(loader);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static UberShaderComponent createLightComponent(SourceLoader loader) {
|
||||
return UberShaderComponent.builder(Flywheel.rl("light"))
|
||||
.materialSources(MaterialShaderIndices.lightSources()
|
||||
.all())
|
||||
.adapt(FnSignature.create()
|
||||
.returnType("void")
|
||||
.name("flw_shaderLight")
|
||||
.build())
|
||||
.switchOn(GlslExpr.variable("_flw_uberLightIndex"))
|
||||
.build(loader);
|
||||
}
|
||||
}
|
||||
|
@ -52,10 +52,11 @@ public final class MaterialEncoder {
|
||||
return ((1 << bitLength) - 1) << bitOffset;
|
||||
}
|
||||
|
||||
public static int packFogAndCutout(Material material) {
|
||||
public static int packUberShader(Material material) {
|
||||
var fog = MaterialShaderIndices.fogIndex(material.fog());
|
||||
var cutout = MaterialShaderIndices.cutoutIndex(material.cutout());
|
||||
return fog & 0xFFFF | (cutout & 0xFFFF) << 16;
|
||||
var light = MaterialShaderIndices.lightIndex(material.light());
|
||||
return (light & 0x3FF) | (cutout & 0x3FF) << 10 | (fog & 0x3FF) << 20;
|
||||
}
|
||||
|
||||
// Packed format:
|
||||
|
@ -34,7 +34,7 @@ public class IndirectDraw {
|
||||
|
||||
this.materialVertexIndex = MaterialShaderIndices.vertexIndex(material.shaders());
|
||||
this.materialFragmentIndex = MaterialShaderIndices.fragmentIndex(material.shaders());
|
||||
this.packedFogAndCutout = MaterialEncoder.packFogAndCutout(material);
|
||||
this.packedFogAndCutout = MaterialEncoder.packUberShader(material);
|
||||
this.packedMaterialProperties = MaterialEncoder.packProperties(material);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ public class IndirectDraw {
|
||||
|
||||
MemoryUtil.memPutInt(ptr + 24, MaterialShaderIndices.vertexIndex(materialOverride.shaders())); // materialVertexIndex
|
||||
MemoryUtil.memPutInt(ptr + 28, MaterialShaderIndices.fragmentIndex(materialOverride.shaders())); // materialFragmentIndex
|
||||
MemoryUtil.memPutInt(ptr + 32, MaterialEncoder.packFogAndCutout(materialOverride)); // packedFogAndCutout
|
||||
MemoryUtil.memPutInt(ptr + 32, MaterialEncoder.packUberShader(materialOverride)); // packedFogAndCutout
|
||||
MemoryUtil.memPutInt(ptr + 36, MaterialEncoder.packProperties(materialOverride)); // packedMaterialProperties
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
||||
int uniformLocation = program.getUniformLocation("_flw_packedMaterial");
|
||||
int vertexIndex = MaterialShaderIndices.vertexIndex(material.shaders());
|
||||
int fragmentIndex = MaterialShaderIndices.fragmentIndex(material.shaders());
|
||||
int packedFogAndCutout = MaterialEncoder.packFogAndCutout(material);
|
||||
int packedFogAndCutout = MaterialEncoder.packUberShader(material);
|
||||
int packedMaterialProperties = MaterialEncoder.packProperties(material);
|
||||
GL32.glUniform4ui(uniformLocation, vertexIndex, fragmentIndex, packedFogAndCutout, packedMaterialProperties);
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ void _flw_main() {
|
||||
|
||||
vec4 color = flw_fragColor;
|
||||
|
||||
if (flw_discardPredicate(color)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
float diffuseFactor = _flw_diffuseFactor();
|
||||
color.rgb *= diffuseFactor;
|
||||
|
||||
@ -57,14 +61,12 @@ void _flw_main() {
|
||||
|
||||
vec4 lightColor = vec4(1.);
|
||||
if (flw_material.useLight) {
|
||||
flw_shaderLight();
|
||||
|
||||
lightColor = texture(flw_lightTex, clamp(flw_fragLight, 0.5 / 16.0, 15.5 / 16.0));
|
||||
color *= lightColor;
|
||||
}
|
||||
|
||||
if (flw_discardPredicate(color)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
switch (_flw_debugMode) {
|
||||
case 1u:
|
||||
color = vec4(flw_vertexNormal * .5 + .5, 1.);
|
||||
|
@ -1,3 +1,4 @@
|
||||
uint _flw_uberMaterialFragmentIndex;
|
||||
uint _flw_uberFogIndex;
|
||||
uint _flw_uberCutoutIndex;
|
||||
uint _flw_uberLightIndex;
|
||||
|
@ -6,7 +6,7 @@ flat in uvec3 _flw_packedMaterial;
|
||||
|
||||
void main() {
|
||||
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.x;
|
||||
_flw_unpackUint2x16(_flw_packedMaterial.y, _flw_uberCutoutIndex, _flw_uberFogIndex);
|
||||
_flw_unpackUint3x10(_flw_packedMaterial.y, _flw_uberFogIndex, _flw_uberCutoutIndex, _flw_uberLightIndex);
|
||||
_flw_unpackMaterialProperties(_flw_packedMaterial.z, flw_material);
|
||||
|
||||
_flw_main();
|
||||
|
@ -5,7 +5,7 @@ uniform uvec4 _flw_packedMaterial;
|
||||
|
||||
void main() {
|
||||
_flw_uberMaterialFragmentIndex = _flw_packedMaterial.y;
|
||||
_flw_unpackUint2x16(_flw_packedMaterial.z, _flw_uberCutoutIndex, _flw_uberFogIndex);
|
||||
_flw_unpackUint3x10(_flw_packedMaterial.z, _flw_uberFogIndex, _flw_uberCutoutIndex, _flw_uberLightIndex);
|
||||
_flw_unpackMaterialProperties(_flw_packedMaterial.w, flw_material);
|
||||
|
||||
_flw_main();
|
||||
|
@ -53,3 +53,9 @@ void _flw_unpackUint2x16(uint s, out uint hi, out uint lo) {
|
||||
hi = (s >> 16) & 0xFFFFu;
|
||||
lo = s & 0xFFFFu;
|
||||
}
|
||||
|
||||
void _flw_unpackUint3x10(uint s, out uint hi, out uint mi, out uint lo) {
|
||||
hi = (s >> 20) & 0x3FFu;
|
||||
mi = (s >> 10) & 0x3FFu;
|
||||
lo = s & 0x3FFu;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package dev.engine_room.flywheel.lib.material;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.api.material.LightShader;
|
||||
|
||||
public class LightShaders {
|
||||
public static final LightShader SMOOTH_WHEN_EMBEDDED = LightShader.REGISTRY.registerAndGet(new SimpleLightShader(Flywheel.rl("light/smooth_when_embedded.glsl")));
|
||||
public static final LightShader SMOOTH = LightShader.REGISTRY.registerAndGet(new SimpleLightShader(Flywheel.rl("light/smooth.glsl")));
|
||||
public static final LightShader FLAT = LightShader.REGISTRY.registerAndGet(new SimpleLightShader(Flywheel.rl("light/flat.glsl")));
|
||||
|
||||
private LightShaders() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void init() {
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package dev.engine_room.flywheel.lib.material;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.LightShader;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public record SimpleLightShader(@Override ResourceLocation source) implements LightShader {
|
||||
}
|
@ -3,6 +3,7 @@ package dev.engine_room.flywheel.lib.material;
|
||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
||||
import dev.engine_room.flywheel.api.material.DepthTest;
|
||||
import dev.engine_room.flywheel.api.material.FogShader;
|
||||
import dev.engine_room.flywheel.api.material.LightShader;
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.material.MaterialShaders;
|
||||
import dev.engine_room.flywheel.api.material.Transparency;
|
||||
@ -14,6 +15,7 @@ public class SimpleMaterial implements Material {
|
||||
protected final MaterialShaders shaders;
|
||||
protected final FogShader fog;
|
||||
protected final CutoutShader cutout;
|
||||
protected final LightShader light;
|
||||
|
||||
protected final ResourceLocation texture;
|
||||
protected final boolean blur;
|
||||
@ -33,6 +35,7 @@ public class SimpleMaterial implements Material {
|
||||
shaders = builder.shaders();
|
||||
fog = builder.fog();
|
||||
cutout = builder.cutout();
|
||||
light = builder.light();
|
||||
texture = builder.texture();
|
||||
blur = builder.blur();
|
||||
mipmap = builder.mipmap();
|
||||
@ -69,6 +72,11 @@ public class SimpleMaterial implements Material {
|
||||
return cutout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightShader light() {
|
||||
return light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation texture() {
|
||||
return texture;
|
||||
@ -128,6 +136,7 @@ public class SimpleMaterial implements Material {
|
||||
protected MaterialShaders shaders;
|
||||
protected FogShader fog;
|
||||
protected CutoutShader cutout;
|
||||
protected LightShader light;
|
||||
|
||||
protected ResourceLocation texture;
|
||||
protected boolean blur;
|
||||
@ -147,6 +156,7 @@ public class SimpleMaterial implements Material {
|
||||
shaders = StandardMaterialShaders.DEFAULT;
|
||||
fog = FogShaders.LINEAR;
|
||||
cutout = CutoutShaders.OFF;
|
||||
light = LightShaders.SMOOTH_WHEN_EMBEDDED;
|
||||
texture = InventoryMenu.BLOCK_ATLAS;
|
||||
blur = false;
|
||||
mipmap = true;
|
||||
@ -197,6 +207,11 @@ public class SimpleMaterial implements Material {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder light(LightShader value) {
|
||||
this.light = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder texture(ResourceLocation value) {
|
||||
this.texture = value;
|
||||
return this;
|
||||
@ -267,6 +282,11 @@ public class SimpleMaterial implements Material {
|
||||
return cutout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightShader light() {
|
||||
return light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation texture() {
|
||||
return texture;
|
||||
|
@ -0,0 +1,6 @@
|
||||
void flw_shaderLight() {
|
||||
vec2 embeddedLight;
|
||||
if (flw_lightFetch(ivec3(floor(flw_vertexPos.xyz)), embeddedLight)) {
|
||||
flw_fragLight = max(flw_fragLight, embeddedLight);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
void flw_shaderLight() {
|
||||
vec2 embeddedLight;
|
||||
if (flw_light(flw_vertexPos.xyz, flw_vertexNormal, embeddedLight)) {
|
||||
flw_fragLight = max(flw_fragLight, embeddedLight);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
void flw_shaderLight() {
|
||||
#ifdef FLW_EMBEDDED
|
||||
vec2 embeddedLight;
|
||||
if (flw_light(flw_vertexPos.xyz, flw_vertexNormal, embeddedLight)) {
|
||||
flw_fragLight = max(flw_fragLight, embeddedLight);
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,8 +1,2 @@
|
||||
void flw_materialFragment() {
|
||||
#ifdef FLW_EMBEDDED
|
||||
vec2 embeddedLight;
|
||||
if (flw_light(flw_vertexPos.xyz, flw_vertexNormal, embeddedLight)) {
|
||||
flw_fragLight = max(flw_fragLight, embeddedLight);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import dev.engine_room.flywheel.impl.registry.RegistryImpl;
|
||||
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
||||
import dev.engine_room.flywheel.lib.material.CutoutShaders;
|
||||
import dev.engine_room.flywheel.lib.material.FogShaders;
|
||||
import dev.engine_room.flywheel.lib.material.LightShaders;
|
||||
import dev.engine_room.flywheel.lib.material.StandardMaterialShaders;
|
||||
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
||||
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
||||
@ -30,6 +31,7 @@ public final class FlwImpl {
|
||||
InstanceTypes.init();
|
||||
CutoutShaders.init();
|
||||
FogShaders.init();
|
||||
LightShaders.init();
|
||||
StandardMaterialShaders.init();
|
||||
|
||||
// backend
|
||||
|
Loading…
Reference in New Issue
Block a user