diff --git a/src/main/java/vazkii/psi/client/core/handler/HUDHandler.java b/src/main/java/vazkii/psi/client/core/handler/HUDHandler.java index 9a5c038fb..1ff9d9c84 100644 --- a/src/main/java/vazkii/psi/client/core/handler/HUDHandler.java +++ b/src/main/java/vazkii/psi/client/core/handler/HUDHandler.java @@ -27,8 +27,6 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import org.lwjgl.opengl.ARBMultitexture; -import org.lwjgl.opengl.ARBShaderObjects; import org.lwjgl.opengl.GL11; import vazkii.psi.api.PsiAPI; @@ -46,7 +44,6 @@ import vazkii.psi.common.lib.LibMisc; import vazkii.psi.common.lib.LibResources; -import java.util.function.Consumer; import java.util.regex.Pattern; @Mod.EventBusSubscriber(value = Dist.CLIENT, modid = LibMisc.MOD_ID) @@ -56,8 +53,6 @@ public final class HUDHandler { private static final ResourceLocation psiBarMask = new ResourceLocation(LibResources.GUI_PSI_BAR_MASK); private static final ResourceLocation psiBarShatter = new ResourceLocation(LibResources.GUI_PSI_BAR_SHATTER); - private static final int secondaryTextureUnit = 7; - private static boolean registeredMask = false; private static final int maxRemainingTicks = 30; @@ -161,14 +156,6 @@ public static void drawPsiBar(PoseStack ms, Window res, float pticks) { int origY = y; int v = 0; - int texture = 0; - boolean shaders = ShaderHandler.useShaders; - - if (shaders) { - RenderSystem.activeTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); - texture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); - } - RenderSystem.enableBlend(); RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); @@ -180,8 +167,8 @@ public static void drawPsiBar(PoseStack ms, Window res, float pticks) { v = origHeight - effHeight; y = origY + v; - ShaderHandler.useShader(ShaderHandler.psiBar, generateCallback(a, d.shatter, data.overflowed)); - GuiComponent.blit(ms, x, y, 32, v, width, height, 64, 256); + usePsiBarShader(a, d.shatter, data.overflowed); + GuiComponent.blit(poseStack, x, y, 32, v, width, height, 64, 256); } float textY = origY; @@ -202,16 +189,8 @@ public static void drawPsiBar(PoseStack ms, Window res, float pticks) { } RenderSystem.setShaderColor(r, g, b, 1F); - ShaderHandler.useShader(ShaderHandler.psiBar, generateCallback(1F, false, data.overflowed)); - GuiComponent.blit(ms, x, y, 32, v, width, height, 64, 256); - ShaderHandler.releaseShader(); - - if (shaders) { - RenderSystem.activeTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); - RenderSystem.bindTexture(texture); - RenderSystem.activeTexture(ARBMultitexture.GL_TEXTURE0_ARB); - } - + usePsiBarShader(1F, false, data.overflowed); + GuiComponent.blit(poseStack, x, y, 32, v, width, height, 64, 256); RenderSystem.setShaderColor(1F, 1F, 1F, 1F); ms.pushPose(); @@ -221,7 +200,7 @@ public static void drawPsiBar(PoseStack ms, Window res, float pticks) { int storedPsi = cad.getStoredPsi(cadStack); - String s1 = storedPsi == -1 ? "\u221E" : "" + data.availablePsi; + String s1 = storedPsi == -1 ? "∞" : "" + data.availablePsi; String s2 = "" + storedPsi; int offBar = 22; @@ -327,8 +306,8 @@ private static void renderRemainingItems(PoseStack ms, Window resolution, float + ChatFormatting.GRAY + max + ChatFormatting.RESET + "+" + ChatFormatting.YELLOW + rem + ChatFormatting.RESET + ")"; } - } else if (remainingCount == -1) { - text = "\u221E"; + } else if(remainingCount == -1) { + text = "∞"; } int color = 0x00FFFFFF | (int) (alpha * 0xFF) << 24; @@ -371,28 +350,13 @@ public static void setRemaining(Player player, ItemStack displayStack, Pattern p } @OnlyIn(Dist.CLIENT) - private static Consumer generateCallback(final float percentile, final boolean shatter, final boolean overflowed) { - Minecraft mc = Minecraft.getInstance(); - return (Integer shader) -> { - int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "percentile"); - int overflowedUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "overflowed"); - int imageUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "image"); - int maskUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "mask"); - - RenderSystem.activeTexture(ARBMultitexture.GL_TEXTURE0_ARB); - RenderSystem.setShaderTexture(0, psiBar); - ARBShaderObjects.glUniform1iARB(imageUniform, 0); - - RenderSystem.activeTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); - - RenderSystem.enableTexture(); - - RenderSystem.setShaderTexture(1, shatter ? psiBarShatter : psiBarMask); - ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit); - - ARBShaderObjects.glUniform1fARB(percentileUniform, percentile); - ARBShaderObjects.glUniform1iARB(overflowedUniform, overflowed ? 1 : 0); - }; + public static void usePsiBarShader(final float percentile, final boolean shatter, final boolean overflowed) { + var psiBarShader = ShaderHandler.getPsiBarShader(); + RenderSystem.setShader(ShaderHandler::getPsiBarShader); + RenderSystem.setShaderTexture(0, psiBar); + RenderSystem.setShaderTexture(1, shatter ? psiBarShatter : psiBarMask); + psiBarShader.safeGetUniform("GameTime").set(RenderSystem.getShaderGameTime()); + psiBarShader.safeGetUniform("PsiBarPercentile").set(percentile); + psiBarShader.safeGetUniform("PsiBarOverflowed").set(overflowed ? 1 : 0); } - } diff --git a/src/main/java/vazkii/psi/client/core/handler/ShaderHandler.java b/src/main/java/vazkii/psi/client/core/handler/ShaderHandler.java index 41cc11a5a..c317fe27d 100644 --- a/src/main/java/vazkii/psi/client/core/handler/ShaderHandler.java +++ b/src/main/java/vazkii/psi/client/core/handler/ShaderHandler.java @@ -8,164 +8,30 @@ */ package vazkii.psi.client.core.handler; -import com.google.common.io.CharStreams; -import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import org.lwjgl.opengl.ARBFragmentShader; -import org.lwjgl.opengl.ARBShaderObjects; -import org.lwjgl.opengl.ARBVertexShader; -import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GL11; +import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RegisterShadersEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; -import vazkii.psi.common.Psi; -import vazkii.psi.common.core.handler.ConfigHandler; +import vazkii.psi.common.lib.LibMisc; import vazkii.psi.common.lib.LibResources; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.function.Consumer; +import java.io.IOException; +@Mod.EventBusSubscriber(modid = LibMisc.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) public final class ShaderHandler { - private static final int VERT_ST = ARBVertexShader.GL_VERTEX_SHADER_ARB; - private static final int FRAG_ST = ARBFragmentShader.GL_FRAGMENT_SHADER_ARB; - public static boolean useShaders = false; + private static ShaderInstance psiBarShader; - private static final int VERT = 1; - private static final int FRAG = 2; - - private static final String VERT_EXTENSION = ".vsh"; - private static final String FRAG_EXTENSION = ".fsh"; - - public static int rawColor; - public static int psiBar; - public static int simpleBloom; - - public static void init() { - useShaders = canUseShaders(); - if (!useShaders) { - return; - } - Psi.logger.info("Initializing Psi shaders!"); - - rawColor = createProgram(LibResources.SHADER_RAW_COLOR, FRAG); - psiBar = createProgram(LibResources.SHADER_PSI_BAR, FRAG); - simpleBloom = createProgram(LibResources.SHADER_SIMPLE_BLOOM, FRAG); - } - - public static void useShader(int shader, Consumer callback) { - if (!useShaders) { - return; - } - - ARBShaderObjects.glUseProgramObjectARB(shader); - - if (shader != 0) { - int time = ARBShaderObjects.glGetUniformLocationARB(shader, "time"); - ARBShaderObjects.glUniform1iARB(time, ClientTickHandler.ticksInGame); - - if (callback != null) { - callback.accept(shader); - } - } - } - - public static void useShader(int shader) { - useShader(shader, null); - } - - public static void releaseShader() { - useShader(0); - } - - public static boolean canUseShaders() { - RenderSystem.assertOnRenderThread(); - return ConfigHandler.CLIENT.useShaders.get() && ((GL.getCapabilities().OpenGL14 && (GL.getCapabilities().GL_ARB_framebuffer_object || GL.getCapabilities().GL_EXT_framebuffer_object || GL.getCapabilities().OpenGL30)) - && (GL.getCapabilities().OpenGL21 || GL.getCapabilities().GL_ARB_fragment_shader && GL.getCapabilities().GL_ARB_fragment_shader && GL.getCapabilities().GL_ARB_shader_objects)); - } - - private static int createProgram(String s, int sides) { - boolean vert = (sides & VERT) != 0; - boolean frag = (sides & FRAG) != 0; - - return createProgram(vert ? s + VERT_EXTENSION : null, frag ? s + FRAG_EXTENSION : null); - } - - // Most of the code taken from the LWJGL wiki - // http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL - - private static int createProgram(String vert, String frag) { - int vertId = 0, fragId = 0, program; - if (vert != null) { - vertId = createShader(vert, VERT_ST); - } - if (frag != null) { - fragId = createShader(frag, FRAG_ST); - } - - program = ARBShaderObjects.glCreateProgramObjectARB(); - if (program == 0) { - return 0; - } - - if (vert != null) { - ARBShaderObjects.glAttachObjectARB(program, vertId); - } - if (frag != null) { - ARBShaderObjects.glAttachObjectARB(program, fragId); - } - - ARBShaderObjects.glLinkProgramARB(program); - if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) { - Psi.logger.error(getLogInfo(program)); - return 0; - } - - ARBShaderObjects.glValidateProgramARB(program); - if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) { - Psi.logger.error(getLogInfo(program)); - return 0; - } - - return program; - } - - private static int createShader(String filename, int shaderType) { - int shader = 0; - try { - shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType); - - if (shader == 0) { - return 0; - } - - ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename)); - ARBShaderObjects.glCompileShaderARB(shader); - - if (ARBShaderObjects.glGetObjectParameteriARB(shader, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE) { - throw new RuntimeException("Error creating shader: " + getLogInfo(shader)); - } - - return shader; - } catch (Exception e) { - ARBShaderObjects.glDeleteObjectARB(shader); - e.printStackTrace(); - return -1; - } - } - - private static String getLogInfo(int obj) { - return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB)); - } - - private static String readFileAsString(String filename) throws Exception { - try (InputStream in = ShaderHandler.class.getResourceAsStream(filename)) { - if (in == null) { - return ""; - } - - return CharStreams.toString(new InputStreamReader(in, StandardCharsets.UTF_8)); - } + @SubscribeEvent + static void registerShaders(RegisterShadersEvent event) throws IOException { + event.registerShader( + new ShaderInstance(event.getResourceManager(), new ResourceLocation(LibMisc.MOD_ID, LibResources.SHADER_PSI_BAR), DefaultVertexFormat.POSITION_TEX_COLOR), + shader -> psiBarShader = shader + ); } } diff --git a/src/main/java/vazkii/psi/client/core/proxy/ClientProxy.java b/src/main/java/vazkii/psi/client/core/proxy/ClientProxy.java index 2d092fbf5..58b4e8a39 100644 --- a/src/main/java/vazkii/psi/client/core/proxy/ClientProxy.java +++ b/src/main/java/vazkii/psi/client/core/proxy/ClientProxy.java @@ -42,7 +42,6 @@ import vazkii.psi.client.core.handler.ClientTickHandler; import vazkii.psi.client.core.handler.ColorHandler; import vazkii.psi.client.core.handler.KeybindHandler; -import vazkii.psi.client.core.handler.ShaderHandler; import vazkii.psi.client.fx.SparkleParticleData; import vazkii.psi.client.fx.WispParticleData; import vazkii.psi.client.gui.GuiProgrammer; @@ -55,7 +54,11 @@ import vazkii.psi.common.block.base.ModBlocks; import vazkii.psi.common.block.tile.TileProgrammer; import vazkii.psi.common.core.proxy.IProxy; -import vazkii.psi.common.entity.*; +import vazkii.psi.common.entity.EntitySpellCharge; +import vazkii.psi.common.entity.EntitySpellCircle; +import vazkii.psi.common.entity.EntitySpellGrenade; +import vazkii.psi.common.entity.EntitySpellMine; +import vazkii.psi.common.entity.EntitySpellProjectile; import vazkii.psi.common.item.base.ModItems; import vazkii.psi.common.lib.LibItemNames; import vazkii.psi.common.lib.LibMisc; @@ -106,7 +109,6 @@ private void loadComplete(FMLLoadCompleteEvent event) { map.put(layer, new BufferBuilder(layer.bufferSize())); map.put(GuiProgrammer.LAYER, new BufferBuilder(GuiProgrammer.LAYER.bufferSize())); ColorHandler.init(); - ShaderHandler.init(); }); } diff --git a/src/main/java/vazkii/psi/common/lib/LibResources.java b/src/main/java/vazkii/psi/common/lib/LibResources.java index 2df1d9b38..772ee681e 100644 --- a/src/main/java/vazkii/psi/common/lib/LibResources.java +++ b/src/main/java/vazkii/psi/common/lib/LibResources.java @@ -15,15 +15,11 @@ public class LibResources { public static final String PREFIX_MOD = "psi:"; public static final ResourceLocation PATCHOULI_BOOK = new ResourceLocation(LibMisc.MOD_ID, "encyclopaedia_psionica"); - public static final String PREFIX_SHADER = "/assets/psi/shaders/"; public static final String PREFIX_GUI = PREFIX_MOD + "textures/gui/"; public static final String PREFIX_MODEL = PREFIX_MOD + "textures/model/"; public static final String PREFIX_MISC = PREFIX_MOD + "textures/misc/"; - public static final String SHADER_RAW_COLOR = PREFIX_SHADER + "raw_color"; - public static final String SHADER_PSI_BAR = PREFIX_SHADER + "psi_bar"; - public static final String SHADER_SIMPLE_BLOOM = PREFIX_SHADER + "simple_bloom"; - + public static final String SHADER_PSI_BAR = "psi_bar"; public static final String GUI_CREATIVE = "psi.png"; public static final String GUI_CAD_ASSEMBLER = PREFIX_GUI + "cad_assembler.png"; public static final String GUI_PSI_BAR = PREFIX_GUI + "psi_bar.png"; diff --git a/src/main/resources/assets/psi/shaders/core/psi_bar.fsh b/src/main/resources/assets/psi/shaders/core/psi_bar.fsh new file mode 100644 index 000000000..bbcadc205 --- /dev/null +++ b/src/main/resources/assets/psi/shaders/core/psi_bar.fsh @@ -0,0 +1,43 @@ +#version 150 + +uniform float PsiBarPercentile; +uniform int PsiBarOverflowed; + +in vec2 texCoord0; +in vec4 textureColor; +in vec4 maskColor; +in vec4 vertexColor; +in float timeTicks; + +out vec4 fragColor; + +void main() { + float maskgs = (maskColor.r + maskColor.g + maskColor.b) / 3.0; + + float r = textureColor.r * vertexColor.r; + float g = textureColor.g * vertexColor.g; + float b = textureColor.b * vertexColor.b; + float a = textureColor.a; + + float exr1 = sin(texCoord0.x * 2 + texCoord0.y * 10 + timeTicks * 0.035); + float exr2 = sin(texCoord0.x * 20 + texCoord0.y * 2 + timeTicks * 0.15); + float exr3 = sin(texCoord0.x * 1 + texCoord0.y * 90 + timeTicks * 0.75); + + float w1 = (cos(timeTicks * 0.1) + 1) * 0.5; + float w2 = (sin(timeTicks * 0.08) + 1) * 0.5; + float w3 = (cos(timeTicks * 0.001) + 1) * 0.5; + + float w = w1 + w2 + w3; + float exr = (exr1 * w1 + exr2 * w2 + exr3 * w3) / w * 0.1; + + r = PsiBarOverflowed == 1 ? 1.0 : r + exr; + g -= exr; + b = PsiBarOverflowed == 1 ? b - 0.2 : b; + + r = max(0, min(1, r)); + g = max(0, min(1, g)); + b = max(0, min(1, b)); + a = maskgs <= PsiBarPercentile ? a : 0; + + fragColor = vec4(r, g, b, a); +} diff --git a/src/main/resources/assets/psi/shaders/core/psi_bar.json b/src/main/resources/assets/psi/shaders/core/psi_bar.json new file mode 100644 index 000000000..8ba8792cb --- /dev/null +++ b/src/main/resources/assets/psi/shaders/core/psi_bar.json @@ -0,0 +1,24 @@ +{ + "__comment": "[VanillaCopy] position_color_tex.json with extra uniforms and custom frag shader", + "blend": { + "func": "add", + "srcrgb": "srcalpha", + "dstrgb": "1-srcalpha" + }, + "vertex": "psi:psi_bar", + "fragment": "psi:psi_bar", + "attributes": [ + "Position", + "Color", + "UV0" + ], + "samplers": [ + { "name": "Sampler0" }, + { "name": "Sampler1" } + ], + "uniforms": [ + { "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "PsiBarPercentile", "type": "float", "count": 1, "values": [ 0.0 ] }, + { "name": "PsiBarOverflowed", "type": "int", "count": 1, "values": [ 0 ] } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/psi/shaders/core/psi_bar.vsh b/src/main/resources/assets/psi/shaders/core/psi_bar.vsh new file mode 100644 index 000000000..552a77b07 --- /dev/null +++ b/src/main/resources/assets/psi/shaders/core/psi_bar.vsh @@ -0,0 +1,23 @@ +#version 150 + +in vec3 Position; +in vec4 Color; +in vec2 UV0; + +uniform sampler2D Sampler0; +uniform sampler2D Sampler1; +uniform float GameTime; + +out vec2 texCoord0; +out vec4 textureColor; +out vec4 maskColor; +out vec4 vertexColor; +out float timeTicks; + +void main() { + vertexColor = Color; + textureColor = texture(Sampler0, UV0); + maskColor = texture(Sampler1, UV0); + texCoord0 = UV0; + timeTicks = GameTime * 24000; +} \ No newline at end of file diff --git a/src/main/resources/assets/psi/shaders/psi_bar.fsh b/src/main/resources/assets/psi/shaders/psi_bar.fsh deleted file mode 100644 index 5b706d3de..000000000 --- a/src/main/resources/assets/psi/shaders/psi_bar.fsh +++ /dev/null @@ -1,47 +0,0 @@ -#version 120 - -uniform int time; // Passed in, see ShaderHandler.java - -uniform float percentile; // Passed in via Callback -uniform int overflowed; -uniform sampler2D image; -uniform sampler2D mask; - -void main() { - vec2 texcoord = vec2(gl_TexCoord[0]); - vec4 color = texture2D(image, texcoord); - vec4 maskColor = texture2D(mask, texcoord); - float maskgs = (maskColor.r + maskColor.g + maskColor.b) / 3.0; - - float r = color.r * gl_Color.r; - float g = color.g * gl_Color.g; - float b = color.b * gl_Color.b; - float a = color.a; // Ignore gl_Color.a as we don't want to make use of that for the dissolve effect - - float exr1 = sin(texcoord.x * 2 + texcoord.y * 10 + time * 0.035); - float exr2 = sin(texcoord.x * 20 + texcoord.y * 2 + time * 0.15); - float exr3 = sin(texcoord.x * 1 + texcoord.y * 90 + time * 0.75); - - float w1 = (cos(time * 0.1) + 1) * 0.5; - float w2 = (sin(time * 0.08) + 1) * 0.5; - float w3 = (cos(time * 0.001) + 1) * 0.5; - - float w = w1 + w2 + w3; - float exr = (exr1 * w1 + exr2 * w2 + exr3 * w3) / w * 0.1; - - r += exr; - g -= exr; - - if(overflowed == 1) { - r = 1.0; - b -= 0.2; - } - - r = max(0, min(1, r)); - g = max(0, min(1, g)); - b = max(0, min(1, b)); - - if(maskgs <= percentile) - gl_FragColor = vec4(r, g, b, a); - else gl_FragColor = vec4(r, g, b, 0); -} diff --git a/src/main/resources/assets/psi/shaders/raw_color.fsh b/src/main/resources/assets/psi/shaders/raw_color.fsh deleted file mode 100644 index b0aef4463..000000000 --- a/src/main/resources/assets/psi/shaders/raw_color.fsh +++ /dev/null @@ -1,15 +0,0 @@ -#version 120 - -uniform sampler2D bgl_RenderedTexture; - -void main() { - vec2 texcoord = vec2(gl_TexCoord[0]); - vec4 color = texture2D(bgl_RenderedTexture, texcoord); - - float r = color.r * gl_Color.r; - float g = color.g * gl_Color.g; - float b = color.b * gl_Color.b; - float a = color.a * gl_Color.a; - - gl_FragColor = vec4(r, g, b, a); -} diff --git a/src/main/resources/assets/psi/shaders/simple_bloom.fsh b/src/main/resources/assets/psi/shaders/simple_bloom.fsh deleted file mode 100644 index 062c4848f..000000000 --- a/src/main/resources/assets/psi/shaders/simple_bloom.fsh +++ /dev/null @@ -1,23 +0,0 @@ -#version 120 - -uniform sampler2D bgl_RenderedTexture; -uniform int time; // Passed in, see ShaderHandler.java - -// Source: http://wp.applesandoranges.eu/?p=14 (Modified) -void main() { - vec4 sum = vec4(0); - vec2 texcoord = vec2(gl_TexCoord[0]); - float brightness = sin(time / 20.0) * 0.5 + 0.5; - - for(int i = -4 ; i < 4; i++) - for(int j = -3; j < 3; j++) - sum += texture2D(bgl_RenderedTexture, texcoord + vec2(j, i) * 0.004) * 0.25; - - if(texture2D(bgl_RenderedTexture, texcoord).r < 0.3) - gl_FragColor = sum * sum * 0.012 + texture2D(bgl_RenderedTexture, texcoord); - else { - if(texture2D(bgl_RenderedTexture, texcoord).r < 0.5) - gl_FragColor = sum * sum * 0.009 * brightness + texture2D(bgl_RenderedTexture, texcoord); - else gl_FragColor = sum * sum * 0.0075 * brightness + texture2D(bgl_RenderedTexture, texcoord); - } -} \ No newline at end of file