Pass texturemap to composite shader and honor texture replacements (#1589)

This commit is contained in:
DarkShadow44 authored and GitHub committed 2026-03-27 19:07:45 -07:00
1 parent 52b0db2566
commit 29f8d718cc
6 files changed
+84 -15

No files matched your search

@@ -200,14 +200,17 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
public DeferredWorldRenderingPipeline(ProgramSet programs) {
Objects.requireNonNull(programs);
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> prepareTransformFutures = submitCompositeTransforms(programs.getPrepare());
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> deferredTransformFutures = submitCompositeTransforms(programs.getDeferred());
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> compositeTransformFutures = submitCompositeTransforms(programs.getComposite());
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> prepareTransformFutures =
submitCompositeTransforms(programs.getPrepare(), TextureStage.PREPARE, programs.getPackDirectives().getTextureMap());
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> deferredTransformFutures =
submitCompositeTransforms(programs.getDeferred(), TextureStage.DEFERRED, programs.getPackDirectives().getTextureMap());
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> compositeTransformFutures =
submitCompositeTransforms(programs.getComposite(), TextureStage.COMPOSITE_AND_FINAL, programs.getPackDirectives().getTextureMap());
final CompletableFuture<Map<PatchShaderType, String>> finalTransformFuture =
programs.getCompositeFinal()
.filter(ProgramSource::isValid)
.map(DeferredWorldRenderingPipeline::submitCompositeTransform)
.map(source -> submitCompositeTransform(source, TextureStage.COMPOSITE_AND_FINAL, programs.getPackDirectives().getTextureMap()))
.orElse(null);
resolver = new ProgramFallbackResolver(programs);
@@ -1710,11 +1713,20 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
private static final InputAvailability INPUT_TEXTURE_LIGHTMAP = new InputAvailability(true, true);
private static final InputAvailability[] INPUT_AVAILABILITIES = { INPUT_NONE, INPUT_TEXTURE, INPUT_TEXTURE_LIGHTMAP };
private static CompletableFuture<Map<PatchShaderType, String>> submitCompositeTransform(ProgramSource source) {
return Iris.ShaderTransformExecutor.submitTracked(() -> TransformPatcher.patchComposite(source.getVertexSource().orElse(null), source.getGeometrySource().orElse(null), source.getTessControlSource().orElse(null), source.getTessEvalSource().orElse(null), source.getFragmentSource().orElse(null)));
private static CompletableFuture<Map<PatchShaderType, String>> submitCompositeTransform(ProgramSource source, TextureStage stage,
Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
return Iris.ShaderTransformExecutor.submitTracked(() -> TransformPatcher.patchComposite(
source.getVertexSource().orElse(null),
source.getGeometrySource().orElse(null),
source.getTessControlSource().orElse(null),
source.getTessEvalSource().orElse(null),
source.getFragmentSource().orElse(null),
stage,
textureMap));
}
private static Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> submitCompositeTransforms(ProgramSource[] sources) {
private static Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> submitCompositeTransforms(ProgramSource[] sources,
TextureStage stage, Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
// Count valid sources for initial capacity
int count = 0;
for (ProgramSource source : sources) {
@@ -1723,7 +1735,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
final Map<Integer, CompletableFuture<Map<PatchShaderType, String>>> futures = new HashMap<>(count);
for (int i = 0; i < sources.length; i++) {
if (sources[i] != null && sources[i].isValid()) {
futures.put(i, submitCompositeTransform(sources[i]));
futures.put(i, submitCompositeTransform(sources[i], stage, textureMap));
}
}
return futures;
@@ -448,6 +448,7 @@ public class ShaderTransformer {
default:
throw new IllegalStateException("Unknown patch type: " + patchType.name());
}
TextureTransformer.transform(transformer, parameters);
CompatibilityTransformer.transformEach(transformer, parameters);
}
@@ -0,0 +1,51 @@
package net.coderbot.iris.pipeline.transform;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import net.coderbot.iris.gl.texture.TextureType;
import net.coderbot.iris.helpers.Tri;
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
import net.coderbot.iris.shaderpack.texture.TextureStage;
import org.taumc.glsl.Transformer;
import org.taumc.glsl.grammar.GLSLLexer;
final class TextureTransformer {
private TextureTransformer() {
}
static void transform(Transformer transformer, Parameters parameters) {
final Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap = parameters.getTextureMap();
if (textureMap == null || textureMap.isEmpty()) {
return;
}
final TextureStage stage = parameters.getTextureStage();
textureMap.forEach((key, replacement) -> {
if (key.third() != stage) {
return;
}
final String name = key.first();
final int type = transformer.findType(name);
if (type != 0 && isTypeValid(key.second(), type)) {
transformer.rename(name, replacement);
}
});
}
private static boolean isTypeValid(TextureType expectedType, int extractedType) {
return switch (expectedType) {
case TEXTURE_1D -> extractedType == GLSLLexer.SAMPLER1D ||
extractedType == GLSLLexer.ISAMPLER1D ||
extractedType == GLSLLexer.USAMPLER1D;
case TEXTURE_RECTANGLE -> extractedType == GLSLLexer.SAMPLER2DRECT ||
extractedType == GLSLLexer.ISAMPLER2DRECT ||
extractedType == GLSLLexer.USAMPLER2DRECT;
case TEXTURE_2D -> extractedType == GLSLLexer.SAMPLER2D ||
extractedType == GLSLLexer.ISAMPLER2D ||
extractedType == GLSLLexer.USAMPLER2D;
case TEXTURE_3D -> extractedType == GLSLLexer.SAMPLER3D ||
extractedType == GLSLLexer.ISAMPLER3D ||
extractedType == GLSLLexer.USAMPLER3D;
};
}
}
@@ -120,10 +120,6 @@ public class TransformPatcher {
return patchComposite(vertex, geometry, null, null, fragment, TextureStage.COMPOSITE_AND_FINAL, null);
}
public static Map<PatchShaderType, String> patchComposite(String vertex, String geometry, String tessControl, String tessEval, String fragment) {
return patchComposite(vertex, geometry, tessControl, tessEval, fragment, TextureStage.COMPOSITE_AND_FINAL, null);
}
public static Map<PatchShaderType, String> patchComposite(String vertex, String geometry, String tessControl, String tessEval, String fragment, TextureStage stage, Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
return transform(vertex, geometry, tessControl, tessEval, fragment, new TextureStageParameters(Patch.COMPOSITE, stage, textureMap));
}
@@ -146,7 +146,7 @@ public class FinalPassRenderer {
GLStateManager.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, 0);
}
private static Map<PatchShaderType, String> getTransformed(ProgramSource source, CompletableFuture<Map<PatchShaderType, String>> precomputedTransformFuture, String stageName) {
private Map<PatchShaderType, String> getTransformed(ProgramSource source, CompletableFuture<Map<PatchShaderType, String>> precomputedTransformFuture, String stageName) {
if (precomputedTransformFuture != null) {
try {
final Map<PatchShaderType, String> result = precomputedTransformFuture.join();
@@ -157,7 +157,14 @@ public class FinalPassRenderer {
throw new RuntimeException("Shader transformation failed for '" + source.getName() + "' in stage '" + stageName + "'", e.getCause() != null ? e.getCause() : e);
}
}
return TransformPatcher.patchComposite(source.getVertexSource().orElseThrow(NullPointerException::new), source.getGeometrySource().orElse(null), source.getTessControlSource().orElse(null), source.getTessEvalSource().orElse(null), source.getFragmentSource().orElseThrow(NullPointerException::new));
return TransformPatcher.patchComposite(
source.getVertexSource().orElseThrow(NullPointerException::new),
source.getGeometrySource().orElse(null),
source.getTessControlSource().orElse(null),
source.getTessEvalSource().orElse(null),
source.getFragmentSource().orElseThrow(NullPointerException::new),
TextureStage.COMPOSITE_AND_FINAL,
pipeline != null ? pipeline.getTextureMap() : null);
}
private static final class Pass {
@@ -263,7 +263,9 @@ public class ShadowCompositeRenderer {
source.getGeometrySource().orElse(null),
source.getTessControlSource().orElse(null),
source.getTessEvalSource().orElse(null),
source.getFragmentSource().orElseThrow(NullPointerException::new));
source.getFragmentSource().orElseThrow(NullPointerException::new),
TextureStage.SHADOWCOMP,
pipeline.getTextureMap());
String vertex = transformed.get(PatchShaderType.VERTEX);
String geometry = transformed.get(PatchShaderType.GEOMETRY);
String tessControl = transformed.get(PatchShaderType.TESS_CONTROL);