beans
This commit is contained in:
@@ -14,7 +14,7 @@ public class RenderPipelineFactory {
|
||||
public static AbstractRenderPipeline createPipeline(AsyncNodeManager nodeManager, NodeCleaner nodeCleaner, HierarchicalOcclusionTraverser traversal, BooleanSupplier frexSupplier) {
|
||||
//Note this is where will choose/create e.g. IrisRenderPipeline or normal pipeline
|
||||
AbstractRenderPipeline pipeline = null;
|
||||
if (IrisUtil.IRIS_INSTALLED && System.getProperty("voxy.enableExperimentalIrisPipeline", "false").equalsIgnoreCase("true")) {
|
||||
if (IrisUtil.IRIS_INSTALLED && IrisUtil.SHADER_SUPPORT) {
|
||||
pipeline = createIrisPipeline(nodeManager, nodeCleaner, traversal, frexSupplier);
|
||||
}
|
||||
if (pipeline == null) {
|
||||
|
||||
@@ -253,7 +253,7 @@ public class VoxyRenderSystem {
|
||||
GlStateManager._glBindVertexArray(0);//Clear binding
|
||||
|
||||
GlStateManager._activeTexture(GlConst.GL_TEXTURE1);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
GlStateManager._activeTexture(GlConst.GL_TEXTURE0+i);
|
||||
GlStateManager._bindTexture(0);
|
||||
glBindSampler(i, 0);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.cortex.voxy.client.core.rendering;
|
||||
|
||||
import me.cortex.voxy.client.core.util.IrisUtil;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import org.vivecraft.client_vr.ClientDataHolderVR;
|
||||
|
||||
@@ -19,19 +20,28 @@ public class ViewportSelector <T extends Viewport<?>> {
|
||||
this.defaultViewport = viewportCreator.get();
|
||||
}
|
||||
|
||||
private T getOrCreate(Object holder) {
|
||||
return this.extraViewports.computeIfAbsent(holder, a->this.creator.get());
|
||||
}
|
||||
|
||||
private T getVivecraftViewport() {
|
||||
var cdh = ClientDataHolderVR.getInstance();
|
||||
var pass = cdh.currentPass;
|
||||
if (pass == null) {
|
||||
return this.defaultViewport;
|
||||
}
|
||||
return this.extraViewports.computeIfAbsent(pass, a->this.creator.get());
|
||||
return this.getOrCreate(pass);
|
||||
}
|
||||
|
||||
private static final Object IRIS_SHADOW_OBJECT = new Object();
|
||||
public T getViewport() {
|
||||
if (VIVECRAFT_INSTALLED) {
|
||||
return getVivecraftViewport();
|
||||
}
|
||||
|
||||
if (IrisUtil.irisShadowActive()) {
|
||||
return this.getOrCreate(IRIS_SHADOW_OBJECT);
|
||||
}
|
||||
return this.defaultViewport;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.irisshaders.iris.shadows.ShadowRenderer;
|
||||
|
||||
public class IrisUtil {
|
||||
public static final boolean IRIS_INSTALLED = FabricLoader.getInstance().isModLoaded("iris");
|
||||
public static final boolean SHADER_SUPPORT = System.getProperty("voxy.enableExperimentalIrisPipeline", "false").equalsIgnoreCase("true");
|
||||
|
||||
|
||||
private static boolean irisShadowActive0() {
|
||||
|
||||
@@ -1,20 +1,107 @@
|
||||
package me.cortex.voxy.client.iris;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.Strictness;
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import me.cortex.voxy.common.Logger;
|
||||
import net.irisshaders.iris.shaderpack.ShaderPack;
|
||||
import net.irisshaders.iris.shaderpack.include.AbsolutePackPath;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL33.*;
|
||||
|
||||
public class IrisShaderPatch {
|
||||
public static final int VERSION = ((IntSupplier)()->1).getAsInt();
|
||||
|
||||
|
||||
private static final class SSBODeserializer implements JsonDeserializer<Int2ObjectOpenHashMap<String>> {
|
||||
@Override
|
||||
public Int2ObjectOpenHashMap<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
Int2ObjectOpenHashMap<String> ret = new Int2ObjectOpenHashMap<>();
|
||||
if (json==null) return null;
|
||||
try {
|
||||
for (var entry : json.getAsJsonObject().entrySet()) {
|
||||
ret.put(Integer.parseInt(entry.getKey()), entry.getValue().getAsString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public record BlendState(int buffer, boolean off, int sRBG, int dRGb, int sA, int dA) {
|
||||
public static BlendState ALL_OFF = new BlendState(-1, true, 0,0,0,0);
|
||||
}
|
||||
|
||||
|
||||
private static final class BlendStateDeserializer implements JsonDeserializer<Int2ObjectMap<BlendState>> {
|
||||
private static int parseType(String type) {
|
||||
type = type.toUpperCase();
|
||||
return switch (type) {
|
||||
case "GL_ZERO" -> GL_ZERO;
|
||||
case "GL_ONE" -> GL_ONE;
|
||||
case "GL_SRC_COLOR" -> GL_SRC_COLOR;
|
||||
case "GL_ONE_MINUS_SRC_COLOR" -> GL_ONE_MINUS_SRC_COLOR;
|
||||
case "GL_SRC_ALPHA" -> GL_SRC_ALPHA;
|
||||
case "GL_ONE_MINUS_SRC_ALPHA" -> GL_ONE_MINUS_SRC_ALPHA;
|
||||
case "GL_DST_ALPHA" -> GL_DST_ALPHA;
|
||||
case "GL_ONE_MINUS_DST_ALPHA" -> GL_ONE_MINUS_DST_ALPHA;
|
||||
case "GL_DST_COLOR" -> GL_DST_COLOR;
|
||||
case "GL_ONE_MINUS_DST_COLOR" -> GL_ONE_MINUS_DST_COLOR;
|
||||
case "GL_SRC_ALPHA_SATURATE" -> GL_SRC_ALPHA_SATURATE;
|
||||
case "GL_SRC1_COLOR" -> GL_SRC1_COLOR;
|
||||
case "GL_ONE_MINUS_SRC1_COLOR" -> GL_ONE_MINUS_SRC1_COLOR;
|
||||
case "GL_ONE_MINUS_SRC1_ALPHA" -> GL_ONE_MINUS_SRC1_ALPHA;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Int2ObjectMap<BlendState> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (json==null) return null;
|
||||
Int2ObjectMap<BlendState> ret = new Int2ObjectOpenHashMap<>();
|
||||
try {
|
||||
if (json.isJsonPrimitive()) {
|
||||
if (json.getAsString().equalsIgnoreCase("off")) {
|
||||
ret.put(-1, BlendState.ALL_OFF);
|
||||
return ret;
|
||||
}
|
||||
} else if (json.isJsonObject()) {
|
||||
for (var entry : json.getAsJsonObject().entrySet()) {
|
||||
int buffer = Integer.parseInt(entry.getKey());
|
||||
BlendState state;
|
||||
var val = entry.getValue();
|
||||
if (val.isJsonArray()) {
|
||||
int[] v = val.getAsJsonArray().asList().stream().mapToInt(a->parseType(a.getAsString())).toArray();
|
||||
state = new BlendState(buffer, false, v[0], v[1], v[2], v[3]);
|
||||
} else if (val.isJsonPrimitive()) {
|
||||
if (val.getAsString().equalsIgnoreCase("off")) {
|
||||
state = new BlendState(buffer, true, 0,0,0,0);
|
||||
} else {
|
||||
state = new BlendState(buffer, true, -1,-1,-1,-1);
|
||||
}
|
||||
} else {
|
||||
state = null;
|
||||
}
|
||||
ret.put(buffer, state);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error(e);
|
||||
}
|
||||
Logger.error("Failed to parse blend state: " + json);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PatchGson {
|
||||
public int version;//TODO maybe replace with semver?
|
||||
public int[] opaqueDrawBuffers;
|
||||
@@ -23,19 +110,35 @@ public class IrisShaderPatch {
|
||||
public String[] samplers;
|
||||
public String[] opaquePatchData;
|
||||
public String[] translucentPatchData;
|
||||
@JsonAdapter(SSBODeserializer.class)
|
||||
public Int2ObjectOpenHashMap<String> ssbos;
|
||||
@JsonAdapter(BlendStateDeserializer.class)
|
||||
public Int2ObjectOpenHashMap<BlendState> blending;
|
||||
|
||||
public boolean checkValid() {
|
||||
return this.opaqueDrawBuffers != null && this.translucentDrawBuffers != null && this.uniforms != null && this.opaquePatchData != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final PatchGson patchData;
|
||||
private final ShaderPack pack;
|
||||
private final Int2ObjectMap<String> ssbos;
|
||||
private IrisShaderPatch(PatchGson patchData, ShaderPack pack) {
|
||||
this.patchData = patchData;
|
||||
this.pack = pack;
|
||||
|
||||
if (patchData.ssbos == null) {
|
||||
this.ssbos = new Int2ObjectOpenHashMap<>();
|
||||
} else {
|
||||
this.ssbos = patchData.ssbos;
|
||||
}
|
||||
}
|
||||
|
||||
public Int2ObjectMap<String> getSSBOs() {
|
||||
return this.ssbos;
|
||||
}
|
||||
public String getPatchOpaqueSource() {
|
||||
return String.join("\n", this.patchData.opaquePatchData);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package me.cortex.voxy.client.iris;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import kroppeb.stareval.function.FunctionReturn;
|
||||
import kroppeb.stareval.function.Type;
|
||||
import me.cortex.voxy.client.core.IrisVoxyRenderPipeline;
|
||||
import me.cortex.voxy.client.mixin.iris.CustomUniformsAccessor;
|
||||
import me.cortex.voxy.client.mixin.iris.IrisRenderingPipelineAccessor;
|
||||
import me.cortex.voxy.common.Logger;
|
||||
import net.irisshaders.iris.gl.buffer.ShaderStorageBufferHolder;
|
||||
import net.irisshaders.iris.gl.image.ImageHolder;
|
||||
import net.irisshaders.iris.gl.sampler.GlSampler;
|
||||
import net.irisshaders.iris.gl.sampler.SamplerHolder;
|
||||
@@ -26,6 +28,7 @@ import org.lwjgl.system.MemoryUtil;
|
||||
import java.util.*;
|
||||
import java.util.function.IntSupplier;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class IrisVoxyRenderPipelineData {
|
||||
public IrisVoxyRenderPipeline thePipeline;
|
||||
@@ -57,11 +60,13 @@ public class IrisVoxyRenderPipelineData {
|
||||
return this.translucentPatch;
|
||||
}
|
||||
|
||||
public static IrisVoxyRenderPipelineData buildPipeline(IrisRenderingPipeline ipipe, IrisShaderPatch patch, CustomUniforms cu) {
|
||||
public static IrisVoxyRenderPipelineData buildPipeline(IrisRenderingPipeline ipipe, IrisShaderPatch patch, CustomUniforms cu, ShaderStorageBufferHolder ssboHolder) {
|
||||
var uniforms = createUniformLayoutStructAndUpdater(createUniformSet(cu, patch));
|
||||
|
||||
createImageSet(ipipe, patch);
|
||||
|
||||
createSSBOLayouts(patch.getSSBOs(), ssboHolder);
|
||||
|
||||
var opaqueDrawTargets = getDrawBuffers(patch.getOpqaueTargets(), ipipe.getFlippedAfterPrepare(), ((IrisRenderingPipelineAccessor)ipipe).getRenderTargets());
|
||||
var translucentDrawTargets = getDrawBuffers(patch.getTranslucentTargets(), ipipe.getFlippedAfterPrepare(), ((IrisRenderingPipelineAccessor)ipipe).getRenderTargets());
|
||||
|
||||
@@ -272,8 +277,12 @@ public class IrisVoxyRenderPipelineData {
|
||||
return uniforms;
|
||||
}
|
||||
|
||||
private record TextureWSampler(String name, IntSupplier texture, int sampler) {
|
||||
|
||||
}
|
||||
private static void createImageSet(IrisRenderingPipeline ipipe, IrisShaderPatch patch) {
|
||||
Set<String> samplerNameSet = new HashSet<>(List.of(patch.getSamplerList()));
|
||||
Set<String> samplerNameSet = new LinkedHashSet<>(List.of(patch.getSamplerList()));
|
||||
Set<TextureWSampler> samplerSet = new LinkedHashSet<>();
|
||||
SamplerHolder samplerBuilder = new SamplerHolder() {
|
||||
@Override
|
||||
public boolean hasSampler(String s) {
|
||||
@@ -287,6 +296,13 @@ public class IrisVoxyRenderPipelineData {
|
||||
return false;
|
||||
}
|
||||
|
||||
private String name(String... names) {
|
||||
for (var name : names) {
|
||||
if (samplerNameSet.contains(name)) return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addDefaultSampler(TextureType type, IntSupplier texture, ValueUpdateNotifier notifier, GlSampler sampler, String... names) {
|
||||
Logger.error("Unsupported default sampler");
|
||||
@@ -301,14 +317,14 @@ public class IrisVoxyRenderPipelineData {
|
||||
@Override
|
||||
public boolean addDynamicSampler(TextureType type, IntSupplier texture, ValueUpdateNotifier notifier, GlSampler sampler, String... names) {
|
||||
if (!this.hasSampler(names)) return false;
|
||||
Logger.info(Arrays.toString(names));
|
||||
return false;
|
||||
samplerSet.add(new TextureWSampler(this.name(names), texture, sampler!=null?sampler.getId():-1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExternalSampler(int texture, String... names) {
|
||||
if (!this.hasSampler(names)) return;
|
||||
Logger.info(Arrays.toString(names));
|
||||
samplerSet.add(new TextureWSampler(this.name(names), ()->texture, -1));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -326,6 +342,18 @@ public class IrisVoxyRenderPipelineData {
|
||||
};
|
||||
|
||||
ipipe.addGbufferOrShadowSamplers(samplerBuilder, imageBuilder, ipipe::getFlippedAfterPrepare, false, true, true, false);
|
||||
|
||||
//samplerSet contains our samplers
|
||||
if (samplerSet.size() != samplerNameSet.size()) {
|
||||
Logger.error("Did not find all requested samplers. Found [" + samplerSet.stream().map(a->a.name).collect(Collectors.joining()) + "] expected " + samplerNameSet);
|
||||
}
|
||||
|
||||
//TODO: generate a layout (defines) for all the samplers with the correct types
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void createSSBOLayouts(Int2ObjectMap<String> ssbos, ShaderStorageBufferHolder ssboStore) {
|
||||
//ssboStore.getBufferIndex()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package me.cortex.voxy.client.mixin.iris;
|
||||
|
||||
import me.cortex.voxy.client.core.util.IrisUtil;
|
||||
import me.cortex.voxy.client.iris.IGetIrisVoxyPipelineData;
|
||||
import me.cortex.voxy.client.iris.IGetVoxyPatchData;
|
||||
import me.cortex.voxy.client.iris.IrisShaderPatch;
|
||||
import me.cortex.voxy.client.iris.IrisVoxyRenderPipelineData;
|
||||
import net.irisshaders.iris.gl.buffer.ShaderStorageBufferHolder;
|
||||
import net.irisshaders.iris.pipeline.IrisRenderingPipeline;
|
||||
import net.irisshaders.iris.shaderpack.programs.ProgramSet;
|
||||
import net.irisshaders.iris.uniforms.custom.CustomUniforms;
|
||||
@@ -18,19 +20,22 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(value = IrisRenderingPipeline.class, remap = false)
|
||||
public class MixinIrisRenderingPipeline implements IGetVoxyPatchData, IGetIrisVoxyPipelineData {
|
||||
@Shadow @Final private CustomUniforms customUniforms;
|
||||
@Shadow private ShaderStorageBufferHolder shaderStorageBufferHolder;
|
||||
@Unique IrisShaderPatch patchData;
|
||||
@Unique
|
||||
IrisVoxyRenderPipelineData pipeline;
|
||||
|
||||
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/irisshaders/iris/pipeline/transform/ShaderPrinter;resetPrintState()V", shift = At.Shift.AFTER))
|
||||
private void voxy$injectPatchDataStore(ProgramSet programSet, CallbackInfo ci) {
|
||||
this.patchData = ((IGetVoxyPatchData)programSet).voxy$getPatchData();
|
||||
if (IrisUtil.SHADER_SUPPORT) {
|
||||
this.patchData = ((IGetVoxyPatchData) programSet).voxy$getPatchData();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/irisshaders/iris/pipeline/IrisRenderingPipeline;createSetupComputes([Lnet/irisshaders/iris/shaderpack/programs/ComputeSource;Lnet/irisshaders/iris/shaderpack/programs/ProgramSet;Lnet/irisshaders/iris/shaderpack/texture/TextureStage;)[Lnet/irisshaders/iris/gl/program/ComputeProgram;"))
|
||||
private void voxy$injectPipeline(ProgramSet programSet, CallbackInfo ci) {
|
||||
if (this.patchData != null) {
|
||||
this.pipeline = IrisVoxyRenderPipelineData.buildPipeline((IrisRenderingPipeline)(Object)this, this.patchData, this.customUniforms);
|
||||
this.pipeline = IrisVoxyRenderPipelineData.buildPipeline((IrisRenderingPipeline)(Object)this, this.patchData, this.customUniforms, this.shaderStorageBufferHolder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.cortex.voxy.client.mixin.iris;
|
||||
|
||||
import me.cortex.voxy.client.config.VoxyConfig;
|
||||
import me.cortex.voxy.client.core.util.IrisUtil;
|
||||
import me.cortex.voxy.client.iris.VoxyUniforms;
|
||||
import net.irisshaders.iris.gl.uniform.UniformHolder;
|
||||
import net.irisshaders.iris.shaderpack.IdMap;
|
||||
@@ -15,6 +17,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public class MixinMatrixUniforms {
|
||||
@Inject(method = "addNonDynamicUniforms", at = @At("TAIL"))
|
||||
private static void voxy$InjectMatrixUniforms(UniformHolder uniforms, IdMap idMap, PackDirectives directives, FrameUpdateNotifier updateNotifier, CallbackInfo ci) {
|
||||
if (VoxyConfig.CONFIG.isRenderingEnabled() && IrisUtil.SHADER_SUPPORT) {
|
||||
VoxyUniforms.addUniforms(uniforms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.cortex.voxy.client.mixin.iris;
|
||||
|
||||
import me.cortex.voxy.client.config.VoxyConfig;
|
||||
import me.cortex.voxy.client.core.util.IrisUtil;
|
||||
import me.cortex.voxy.client.iris.IGetVoxyPatchData;
|
||||
import me.cortex.voxy.client.iris.IrisShaderPatch;
|
||||
import net.irisshaders.iris.shaderpack.ShaderPack;
|
||||
@@ -25,7 +26,7 @@ public class MixinProgramSet implements IGetVoxyPatchData {
|
||||
|
||||
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/irisshaders/iris/shaderpack/programs/ProgramSet;locateDirectives()V", shift = At.Shift.BEFORE))
|
||||
private void voxy$injectPatchMaker(AbsolutePackPath directory, Function<AbsolutePackPath, String> sourceProvider, ShaderProperties shaderProperties, ShaderPack pack, CallbackInfo ci) {
|
||||
if (VoxyConfig.CONFIG.isRenderingEnabled()) {
|
||||
if (VoxyConfig.CONFIG.isRenderingEnabled() && IrisUtil.SHADER_SUPPORT) {
|
||||
this.patchData = IrisShaderPatch.makePatch(pack, directory, sourceProvider);
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import me.cortex.voxy.client.config.VoxyConfig;
|
||||
import me.cortex.voxy.client.core.util.IrisUtil;
|
||||
import net.irisshaders.iris.gl.shader.StandardMacros;
|
||||
import net.irisshaders.iris.helpers.StringPair;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -20,7 +21,7 @@ public abstract class MixinStandardMacros {
|
||||
|
||||
@WrapOperation(method = "createStandardEnvironmentDefines", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;copyOf(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableList;"))
|
||||
private static ImmutableList<StringPair> voxy$injectVoxyDefine(Collection<StringPair> list, Operation<ImmutableList<StringPair>> original) {
|
||||
if (VoxyConfig.CONFIG.isRenderingEnabled()) {
|
||||
if (VoxyConfig.CONFIG.isRenderingEnabled() && IrisUtil.SHADER_SUPPORT) {
|
||||
define((List<StringPair>) list, "VOXY");
|
||||
}
|
||||
return ImmutableList.copyOf(list);
|
||||
|
||||
@@ -119,6 +119,17 @@ void main() {
|
||||
colour = textureLod(blockModelAtlas, texPos, 0);
|
||||
}
|
||||
|
||||
//If we are in shaders and are a helper invocation, just exit, as it enables extra performance gains for small sized
|
||||
// fragments, we do this here after derivative computation
|
||||
//Trying it with all shaders
|
||||
//#ifdef PATCHED_SHADER
|
||||
#ifndef PATCHED_SHADER_ALLOW_DERIVATIVES
|
||||
if (gl_HelperInvocation) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
if (any(notEqual(clamp(tile, vec2(0), vec2((interData.x>>8)&0xFu, (interData.x>>12)&0xFu)), tile))) {
|
||||
discard;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user