diff --git a/game/engines/default/engine/Shader.lua b/game/engines/default/engine/Shader.lua
index 11f024ae3979666ecbad0967f93e0c8444211480..55dab1ed968a5efdf2f2887011e3e58fb5152279 100644
--- a/game/engines/default/engine/Shader.lua
+++ b/game/engines/default/engine/Shader.lua
@@ -36,6 +36,10 @@ function _M:init(name, args)
 	self.totalname = self:makeTotalName()
 --	print("[SHADER] making shader from", name, " into ", self.totalname)
 
+	if args.require_shader then
+		if not core.shader.active(args.require_shader) then return end
+	end
+
 	if not core.shader.active() then return end
 
 	if not self.args.delay_load then
diff --git a/game/modules/tome/class/uiset/Minimalist.lua b/game/modules/tome/class/uiset/Minimalist.lua
index e28d49219860276885aae339eaf9efd282ad2b6b..8116279830a730515f5e7182f3313d996ac295e8 100644
--- a/game/modules/tome/class/uiset/Minimalist.lua
+++ b/game/modules/tome/class/uiset/Minimalist.lua
@@ -47,33 +47,33 @@ local frames_colors = {
 
 -- Load the various shaders used to display resources
 air_c = {0x92/255, 0xe5, 0xe8}
-air_sha = Shader.new("resources", {delay_load=true, color=air_c, speed=100, amp=0.8, distort={2,2.5}})
+air_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=air_c, speed=100, amp=0.8, distort={2,2.5}})
 life_c = {0xc0/255, 0, 0}
-life_sha = Shader.new("resources", {delay_load=true, color=life_c, speed=1000, distort={1.5,1.5}})
+life_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=life_c, speed=1000, distort={1.5,1.5}})
 shield_c = {0.5, 0.5, 0.5}
-shield_sha = Shader.new("resources", {delay_load=true, color=shield_c, speed=5000, a=0.8, distort={0.5,0.5}})
+shield_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=shield_c, speed=5000, a=0.8, distort={0.5,0.5}})
 stam_c = {0xff/255, 0xcc/255, 0x80/255}
-stam_sha = Shader.new("resources", {delay_load=true, color=stam_c, speed=700, distort={1,1.4}})
+stam_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=stam_c, speed=700, distort={1,1.4}})
 mana_c = {106/255, 146/255, 222/255}
-mana_sha = Shader.new("resources", {delay_load=true, color=mana_c, speed=1000, distort={0.4,0.4}})
+mana_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=mana_c, speed=1000, distort={0.4,0.4}})
 soul_c = {128/255, 128/255, 128/255}
-soul_sha = Shader.new("resources", {delay_load=true, color=soul_c, speed=1200, distort={0.4,-0.4}})
+soul_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=soul_c, speed=1200, distort={0.4,-0.4}})
 equi_c = {0x00/255, 0xff/255, 0x74/255}
-equi_sha = Shader.new("resources", {delay_load=true, color=equi_c, amp=0.8, speed=20000, distort={0.3,0.25}})
+equi_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=equi_c, amp=0.8, speed=20000, distort={0.3,0.25}})
 paradox_c = {0x2f/255, 0xa0/255, 0xb4/255}
-paradox_sha = Shader.new("resources", {delay_load=true, color=paradox_c, amp=0.8, speed=20000, distort={0.1,0.25}})
+paradox_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=paradox_c, amp=0.8, speed=20000, distort={0.1,0.25}})
 pos_c = {colors.GOLD.r/255, colors.GOLD.g/255, colors.GOLD.b/255}
-pos_sha = Shader.new("resources", {delay_load=true, color=pos_c, speed=1000, distort={1.6,0.2}})
+pos_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=pos_c, speed=1000, distort={1.6,0.2}})
 neg_c = {colors.DARK_GREY.r/255, colors.DARK_GREY.g/255, colors.DARK_GREY.b/255}
-neg_sha = Shader.new("resources", {delay_load=true, color=neg_c, speed=1000, distort={1.6,-0.2}})
+neg_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=neg_c, speed=1000, distort={1.6,-0.2}})
 vim_c = {0x90/255, 0x40/255, 0x10/255}
-vim_sha = Shader.new("resources", {delay_load=true, color=vim_c, speed=1000, distort={0.4,0.4}})
+vim_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=vim_c, speed=1000, distort={0.4,0.4}})
 hate_c = {0xF5/255, 0x3C/255, 0xBE/255}
-hate_sha = Shader.new("resources", {delay_load=true, color=hate_c, speed=1000, distort={0.4,0.4}})
+hate_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=hate_c, speed=1000, distort={0.4,0.4}})
 psi_c = {colors.BLUE.r/255, colors.BLUE.g/255, colors.BLUE.b/255}
-psi_sha = Shader.new("resources", {delay_load=true, color=psi_c, speed=2000, distort={0.4,0.4}})
+psi_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=psi_c, speed=2000, distort={0.4,0.4}})
 feedback_c = {colors.YELLOW.r/255, colors.YELLOW.g/255, colors.YELLOW.b/255}
-feedback_sha = Shader.new("resources", {delay_load=true, color=feedback_c, speed=2000, distort={0.4,0.4}})
+feedback_sha = Shader.new("resources", {require_shader=4, delay_load=true, color=feedback_c, speed=2000, distort={0.4,0.4}})
 save_c = pos_c
 save_sha = pos_sha
 
diff --git a/game/modules/tome/data/birth/classes/mage.lua b/game/modules/tome/data/birth/classes/mage.lua
index 269af7762c2cbb94e070abf22dd77a5906b41399..0bc1d2e035cf63ab3e73d5d8c25867d76ffa8fe1 100644
--- a/game/modules/tome/data/birth/classes/mage.lua
+++ b/game/modules/tome/data/birth/classes/mage.lua
@@ -127,22 +127,22 @@ newBirthDescriptor{
 	birth_example_particles = {
 		"arcane_power",
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", hide_center=0, xy={0, 0}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", hide_center=0, xy={0, 0}}))
 			else actor:addParticles(Particles.new("wildfire", 1))
 			end
 		end,
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_ring_rotating", 1, {rotation=-0.2, radius=1.1}, {type="sparks", hide_center=0, time_factor=40000, color1={0, 0, 1, 1}, color2={0, 1, 1, 1}, zoom=0.5, xy={0, 0}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_ring_rotating", 1, {rotation=-0.2, radius=1.1}, {type="sparks", hide_center=0, time_factor=40000, color1={0, 0, 1, 1}, color2={0, 1, 1, 1}, zoom=0.5, xy={0, 0}}))
 			else actor:addParticles(Particles.new("uttercold", 1))
 			end
 		end,
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_ring_rotating", 1, {rotation=-0.01, radius=1.1}, {type="stone", hide_center=1, xy={0, 0}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_ring_rotating", 1, {rotation=-0.01, radius=1.1}, {type="stone", hide_center=1, xy={0, 0}}))
 			else actor:addParticles(Particles.new("crystalline_focus", 1))
 			end
 		end,
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="sparks", hide_center=0, zoom=3, xy={0, 0}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="sparks", hide_center=0, zoom=3, xy={0, 0}}))
 			else actor:addParticles(Particles.new("tempest", 1))
 			end
 		end,
diff --git a/game/modules/tome/data/birth/classes/psionic.lua b/game/modules/tome/data/birth/classes/psionic.lua
index 6537a5046338bd17a0827c22484140658a237fa5..26b9b8dad87a7227637f9d0a2e9799c677f12a58 100644
--- a/game/modules/tome/data/birth/classes/psionic.lua
+++ b/game/modules/tome/data/birth/classes/psionic.lua
@@ -60,17 +60,17 @@ newBirthDescriptor{
 	stats = { str=1, wil=4, cun=4, },
 	birth_example_particles = {
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={1, 0, 0.3}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={1, 0, 0.3}}))
 			else actor:addParticles(Particles.new("generic_shield", 1, {r=1, g=0, b=0.3, a=0.5}))
 			end
 		end,
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={0.3, 1, 1}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={0.3, 1, 1}}))
 			else actor:addParticles(Particles.new("generic_shield", 1, {r=0.3, g=1, b=1, a=0.5}))
 			end
 		end,
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={0.8, 1, 0.2}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={0.8, 1, 0.2}}))
 			else actor:addParticles(Particles.new("generic_shield", 1, {r=0.8, g=1, b=0.2, a=0.5}))
 			end
 		end,
@@ -178,7 +178,7 @@ newBirthDescriptor{
 	stats = { str=0, wil=5, cun=4, },
 	birth_example_particles = {
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={1, 1, 0}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={1, 1, 0}}))
 			else actor:addParticles(Particles.new("generic_shield", 1, {r=1, g=1, b=0, a=1}))
 			end
 		end,
diff --git a/game/modules/tome/data/birth/classes/wilder.lua b/game/modules/tome/data/birth/classes/wilder.lua
index d43973037d989af5bd7ba0e62178a708fd708921..1018e651d4bfc3ee62b1c08beff63fa2d778b7a6 100644
--- a/game/modules/tome/data/birth/classes/wilder.lua
+++ b/game/modules/tome/data/birth/classes/wilder.lua
@@ -65,7 +65,7 @@ newBirthDescriptor{
 	stats = { wil=5, cun=3, dex=1, },
 	birth_example_particles = {
 		function(actor)
-			if core.shader.active() then actor:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", zoom=2, npow=4, time_factor=4000, color1={0.2,0.7,0,1}, color2={0,1,0.3,1}, hide_center=0, xy={0, 0}}))
+			if core.shader.active(4) then actor:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", zoom=2, npow=4, time_factor=4000, color1={0.2,0.7,0,1}, color2={0,1,0.3,1}, hide_center=0, xy={0, 0}}))
 			else actor:addParticles(Particles.new("master_summoner", 1))
 			end
 		end,
diff --git a/game/modules/tome/data/general/events/antimagic-bush.lua b/game/modules/tome/data/general/events/antimagic-bush.lua
index 6fa2a7816620631f4c6b3b895b58fa5c6e2ee807..cd4366e1c0dba9b35ce6380564145b618c7e4010 100644
--- a/game/modules/tome/data/general/events/antimagic-bush.lua
+++ b/game/modules/tome/data/general/events/antimagic-bush.lua
@@ -29,7 +29,7 @@ g.add_displays[#g.add_displays+1] = mod.class.Grid.new{image="terrain/antimagic_
 g.nice_tiler = nil
 game.zone:addEntity(game.level, g, "terrain", x, y)
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 3, "shader_ring_rotating", {rotation=0, radius=6}, {type="flames", aam=0.5, zoom=0.4, npow=5, time_factor=15000, color1={0,0.8,0.5,1}, color2={0,0.8,0.7,1}, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 3, "ultrashield", {rm=0, rM=0, gm=160, gM=240, bm=100, bM=160, am=80, aM=150, radius=3, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/events/bligthed-soil.lua b/game/modules/tome/data/general/events/bligthed-soil.lua
index 234ab0bc1b167f6bb737784e29493bce43d51984..2877cbe26426767502ae4dff666d058b11dbbe71 100644
--- a/game/modules/tome/data/general/events/bligthed-soil.lua
+++ b/game/modules/tome/data/general/events/bligthed-soil.lua
@@ -29,7 +29,7 @@ g.add_displays[#g.add_displays+1] = mod.class.Grid.new{image="terrain/blight_roo
 g.nice_tiler = nil
 game.zone:addEntity(game.level, g, "terrain", x, y)
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 3, "shader_ring_rotating", {rotation=0, radius=6}, {type="flames", aam=0.5, zoom=0.4, npow=1, time_factor=15000, color1={0.2,0.4,0,1}, color2={0.2,0.5,0.1,1}, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 3, "ultrashield", {rm=50, rM=80, gm=80, gM=100, bm=30, bM=60, am=80, aM=150, radius=3, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/events/fell-aura.lua b/game/modules/tome/data/general/events/fell-aura.lua
index 4633aa6c0f09427b807daf040a1d1e16239687a8..71c9aba20db395903305f668aac17c6565e53659 100644
--- a/game/modules/tome/data/general/events/fell-aura.lua
+++ b/game/modules/tome/data/general/events/fell-aura.lua
@@ -21,7 +21,7 @@
 local x, y = game.state:findEventGrid(level)
 if not x then return false end
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 2, "shader_ring_rotating", {rotation=0, radius=4}, {type="flames", aam=0.1, zoom=7, npow=4, time_factor=2000, color1={0.1,0.1,0.1,6}, color2={0.3,0.3,0.3,1}, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 2, "ultrashield", {rm=200, rM=250, gm=200, gM=250, bm=80, bM=120, am=80, aM=150, radius=2, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/events/font-life.lua b/game/modules/tome/data/general/events/font-life.lua
index cfc9609bcf8e0c86c453692b97bbf3e5ff55014c..cf9622d937abced5d40e73c9ebd415ce6d4337be 100644
--- a/game/modules/tome/data/general/events/font-life.lua
+++ b/game/modules/tome/data/general/events/font-life.lua
@@ -29,7 +29,7 @@ g.add_displays[#g.add_displays+1] = mod.class.Grid.new{image="terrain/terrain_po
 g.nice_tiler = nil
 game.zone:addEntity(game.level, g, "terrain", x, y)
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 2, "shader_ring_rotating", {rotation=0, radius=4}, {type="flames", aam=0.5, zoom=3, npow=4, time_factor=4000, color1={0.2,0.7,0,1}, color2={0,1,0.3,1}, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 2, "ultrashield", {rm=0, rM=0, gm=180, gM=220, bm=10, bM=80, am=80, aM=150, radius=2, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/events/necrotic-air.lua b/game/modules/tome/data/general/events/necrotic-air.lua
index 83fab9406c4e77bde69a9e791d195c4417082238..b29fe8016d9a8da16a36804b548429a01637b6a9 100644
--- a/game/modules/tome/data/general/events/necrotic-air.lua
+++ b/game/modules/tome/data/general/events/necrotic-air.lua
@@ -21,7 +21,7 @@
 local x, y = game.state:findEventGrid(level)
 if not x then return false end
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 2, "shader_ring_rotating", {rotation=0, radius=4}, {type="flames", aam=0.2, zoom=1, npow=8, time_factor=6000, color1={0.1,0.1,0.1,6}, color2={0.3,0.3,0.3,1}, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 2, "ultrashield", {rm=200, rM=250, gm=200, gM=250, bm=80, bM=120, am=80, aM=150, radius=2, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/events/protective-aura.lua b/game/modules/tome/data/general/events/protective-aura.lua
index 97b4f0a6c5d24611d193ab33a25c73281d42ca8c..c3d1ef00505e53c501047e32ea583e49e76a959f 100644
--- a/game/modules/tome/data/general/events/protective-aura.lua
+++ b/game/modules/tome/data/general/events/protective-aura.lua
@@ -21,7 +21,7 @@
 local x, y = game.state:findEventGrid(level)
 if not x then return false end
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 1, "shader_ring_rotating", {rotation=0, radius=2}, {type="flames", aam=0.1, zoom=7, npow=4, time_factor=2000, color1={0.8,0.8,0,6}, color2={0.9,0.9,0.7,1}, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 1, "ultrashield", {rm=200, rM=250, gm=200, gM=250, bm=80, bM=120, am=80, aM=150, radius=1, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/events/spellblaze-scar.lua b/game/modules/tome/data/general/events/spellblaze-scar.lua
index 5ea46b996681082a1f3e5c50b54e4cbef8ee03d3..072b6ea42b5fae7c4bd89bf25f16ef266ac8a636 100644
--- a/game/modules/tome/data/general/events/spellblaze-scar.lua
+++ b/game/modules/tome/data/general/events/spellblaze-scar.lua
@@ -29,7 +29,7 @@ g.on_stand = nil
 level.map(x, y, engine.Map.TERRAIN, g)
 game.nicer_tiles:updateAround(level, x, y)
 
-if core.shader.active() then
+if core.shader.active(4) then
 	level.map:particleEmitter(x, y, 1, "shader_ring_rotating", {rotation=0, radius=2}, {type="flames", aam=0.5, zoom=3, npow=4, time_factor=1000, hide_center=0})
 else
 	level.map:particleEmitter(x, y, 1, "ultrashield", {rm=180, rM=220, gm=0, gM=0, bm=10, bM=80, am=30, aM=100, radius=1, density=60, life=14, instop=17})
diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua
index 1b8205fa4d6b84642376e8118435100a902e8971..816de0dffdf8ce33c3bef5865988834bc2538334 100644
--- a/game/modules/tome/data/general/npcs/horror.lua
+++ b/game/modules/tome/data/general/npcs/horror.lua
@@ -709,7 +709,7 @@ With each slow breath it takes reality distorts around it.  Blue twirls into red
 	dreamer_sleep_state = 1,
 	-- And some particles to show that we're asleep
 	resolvers.genericlast(function(e)
-		if core.shader.active() then
+		if core.shader.active(4) then
 			e.sleep_particle = e:addParticles(engine.Particles.new("shader_shield", 1, {img="shield2", size_factor=1}, {type="shield", time_factor=6000, aadjust=2, color={0.6, 1, 0.6}}))
 		else
 			e.sleep_particle = e:addParticles(engine.Particles.new("generic_shield", 1, {r=0.6, g=1, b=0.6, a=1}))
diff --git a/game/modules/tome/data/talents/gifts/summon-advanced.lua b/game/modules/tome/data/talents/gifts/summon-advanced.lua
index 6e522fef799f5c280dadb3e272326865c00118f6..6a9482853d5cc53034b8f69d5808e72c12abe1b1 100644
--- a/game/modules/tome/data/talents/gifts/summon-advanced.lua
+++ b/game/modules/tome/data/talents/gifts/summon-advanced.lua
@@ -31,7 +31,7 @@ newTalent{
 	activate = function(self, t)
 		game:playSoundNear(self, "talents/heal")
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", zoom=2, npow=4, time_factor=4000, color1={0.2,0.7,0,1}, color2={0,1,0.3,1}, hide_center=0, xy={self.x, self.y}}))
 		else
 			particle = self:addParticles(Particles.new("master_summoner", 1))
diff --git a/game/modules/tome/data/talents/psionic/absorption.lua b/game/modules/tome/data/talents/psionic/absorption.lua
index e820139ced28b548f9f051ffc5e6848ef489e145..71f8fed3fa02097ee72e2c292478d4a3ccf41433 100644
--- a/game/modules/tome/data/talents/psionic/absorption.lua
+++ b/game/modules/tome/data/talents/psionic/absorption.lua
@@ -85,7 +85,7 @@ newTalent{
 		local s_str = getShieldStrength(self, t)
 
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={1, 0, 0.3}}))
 		else
 			particle = self:addParticles(Particles.new("generic_shield", 1, {r=1, g=0, b=0.3, a=0.5}))
@@ -198,7 +198,7 @@ newTalent{
 		game:playSoundNear(self, "talents/heal")
 		local s_str = getShieldStrength(self, t)
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={0.3, 1, 1}}))
 		else
 			particle = self:addParticles(Particles.new("generic_shield", 1, {r=0.3, g=1, b=1, a=0.5}))
@@ -307,7 +307,7 @@ newTalent{
 		game:playSoundNear(self, "talents/heal")
 		local s_str = getShieldStrength(self, t)
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-10000, llpow=1, aadjust=3, color={0.8, 1, 0.2}}))
 		else
 			particle = self:addParticles(Particles.new("generic_shield", 1, {r=0.8, g=1, b=0.2, a=0.5}))
diff --git a/game/modules/tome/data/talents/spells/aether.lua b/game/modules/tome/data/talents/spells/aether.lua
index 1ba6a7c4d1d167e01581bab6f0ce33c2c7bb491e..4bde14207718fe73f2d44e0b006c4f774b2101d7 100644
--- a/game/modules/tome/data/talents/spells/aether.lua
+++ b/game/modules/tome/data/talents/spells/aether.lua
@@ -237,7 +237,7 @@ newTalent{
 		game:playSoundNear(self, "talents/arcane")
 
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.3}, {type="shield", time_factor=-2500, color={0.8, 0.1, 1.0}, impact_color = {0, 1, 0}, impact_time=800}))
 		else
 			particle = self:addParticles(Particles.new("disruption_shield", 1))
diff --git a/game/modules/tome/data/talents/spells/arcane.lua b/game/modules/tome/data/talents/spells/arcane.lua
index 2362bca72222e952594ab0d3a57a28ccd4ecc8d9..0288062a0c1241207a23a66aa57c299c3219d6d2 100644
--- a/game/modules/tome/data/talents/spells/arcane.lua
+++ b/game/modules/tome/data/talents/spells/arcane.lua
@@ -168,7 +168,7 @@ newTalent{
 		game:playSoundNear(self, "talents/arcane")
 
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.3}, {type="shield", time_factor=-2500, color={0.8, 0.1, 1.0}, impact_color = {0, 1, 0}, impact_time=800}))
 		else
 			particle = self:addParticles(Particles.new("disruption_shield", 1))
diff --git a/game/modules/tome/data/talents/spells/ice.lua b/game/modules/tome/data/talents/spells/ice.lua
index d4d2d1d79432ce85cb5a9db2c5bc25dd8c6af372..28e750c58f6d86b6cc04d8bd9aaed62e984808e0 100644
--- a/game/modules/tome/data/talents/spells/ice.lua
+++ b/game/modules/tome/data/talents/spells/ice.lua
@@ -159,7 +159,7 @@ newTalent{
 		game:playSoundNear(self, "talents/ice")
 
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_ring_rotating", 1, {rotation=-0.2, radius=1.1}, {type="sparks", hide_center=0, time_factor=40000, color1={0, 0, 1, 1}, color2={0, 1, 1, 1}, zoom=0.5, xy={self.x, self.y}}))
 		else
 			particle = self:addParticles(Particles.new("uttercold", 1))
diff --git a/game/modules/tome/data/talents/spells/stone.lua b/game/modules/tome/data/talents/spells/stone.lua
index 91e729bea7fb6471468bf9c8b5e8b17c9085c020..a4e808fbbcfcce773e1221ae0227ea15bfde5e50 100644
--- a/game/modules/tome/data/talents/spells/stone.lua
+++ b/game/modules/tome/data/talents/spells/stone.lua
@@ -188,7 +188,7 @@ newTalent{
 	activate = function(self, t)
 		game:playSoundNear(self, "talents/earth")
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_ring_rotating", 1, {rotation=-0.01, radius=1.1}, {type="stone", hide_center=1, xy={self.x, self.y}}))
 		else
 			particle = self:addParticles(Particles.new("crystalline_focus", 1))
diff --git a/game/modules/tome/data/talents/spells/storm.lua b/game/modules/tome/data/talents/spells/storm.lua
index d6b183601bc8240ef01dcb169f3f21e41ebb7a1c..deeed06428416545e0152d5b3cf885c14969e1a3 100644
--- a/game/modules/tome/data/talents/spells/storm.lua
+++ b/game/modules/tome/data/talents/spells/storm.lua
@@ -40,7 +40,7 @@ newTalent{
 		local dam = self:spellCrit(t.getDamage(self, t))
 		self:project(tg, self.x, self.y, DamageType.LIGHTNING_DAZE, {daze=75, dam=rng.avg(dam / 3, dam, 3)})
 
-		if core.shader.active() then
+		if core.shader.active(4) then
 			game.level.map:particleEmitter(self.x, self.y, tg.radius, "shader_ring", {radius=tg.radius*2, life=8}, {type="sparks"})
 		else
 			local x, y = self.x, self.y
@@ -150,7 +150,7 @@ newTalent{
 	activate = function(self, t)
 		game:playSoundNear(self, "talents/thunderstorm")
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="sparks", hide_center=0, zoom=3, xy={self.x, self.y}}))
 		else
 			particle = self:addParticles(Particles.new("tempest", 1))
diff --git a/game/modules/tome/data/talents/spells/wildfire.lua b/game/modules/tome/data/talents/spells/wildfire.lua
index 24b067c4800d4f4f7d11096f120a1d780486e980..c5496c1d06aac3219a01877828a009dd0af448df 100644
--- a/game/modules/tome/data/talents/spells/wildfire.lua
+++ b/game/modules/tome/data/talents/spells/wildfire.lua
@@ -122,7 +122,7 @@ newTalent{
 		game:playSoundNear(self, "talents/fire")
 
 		local particle
-		if core.shader.active() then
+		if core.shader.active(4) then
 			particle = self:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", hide_center=0, xy={self.x, self.y}}))
 		else
 			particle = self:addParticles(Particles.new("wildfire", 1))
diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua
index 5402db149af2d1f06eeee30c8c3e10636418e74f..0268550a28a19096b88d6bd07955fc7b8c287a09 100644
--- a/game/modules/tome/data/timed_effects/magical.lua
+++ b/game/modules/tome/data/timed_effects/magical.lua
@@ -441,7 +441,7 @@ newEffect{
 		self.displacement_shield_chance = eff.chance
 		--- Warning there can be only one time shield active at once for an actor
 		self.displacement_shield_target = eff.target
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {img="shield3"}, {type="shield", time_factor=6000, color={0.5, 1, 0.2}}))
 		else
 			eff.particle = self:addParticles(Particles.new("displacement_shield", 1))
@@ -494,7 +494,7 @@ newEffect{
 		--- Warning there can be only one time shield active at once for an actor
 		self.damage_shield_absorb = eff.power
 		self.damage_shield_absorb_max = eff.power
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, nil, {type="shield", color={0.4, 0.7, 1.0}}))
 		else
 			eff.particle = self:addParticles(Particles.new("damage_shield", 1))
@@ -1838,7 +1838,7 @@ newEffect{
 	on_timeout = function(self, eff)
 		local spot = rng.table(eff.list)
 		self:project({type="ball", x=spot.x, y=spot.y, radius=2, selffire=self:spellFriendlyFire()}, spot.x, spot.y, DamageType.ARCANE, eff.dam)
-		if core.shader.active() then
+		if core.shader.active(4) then
 			game.level.map:particleEmitter(spot.x, spot.y, 2, "shader_ring", {radius=4, life=12}, {type="sparks", zoom=1, time_factor=400, hide_center=0, color1={0.6, 0.3, 0.8, 1}, color1={0.8, 0, 0.8, 1}})
 		else
 			game.level.map:particleEmitter(spot.x, spot.y, 2, "generic_ball", {rm=150, rM=180, gm=20, gM=60, bm=180, bM=200, am=80, aM=150, radius=2})
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index c5e637aaf89bfa0f53dfc2813c35d35ae50fc5fa..c7b4fc46ad9eeebf5a6ffd48eda58048ec8f59d9 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -1340,7 +1340,7 @@ newEffect{
 		eff.tmpid = self:addTemporaryValue("kinspike_shield", eff.power)
 		self.kinspike_shield_absorb = eff.power
 
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={1, 0, 0.3}}))
 		else
 			eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=1, g=0, b=0.3, a=1}))
@@ -1366,7 +1366,7 @@ newEffect{
 		eff.tmpid = self:addTemporaryValue("thermspike_shield", eff.power)
 		self.thermspike_shield_absorb = eff.power
 
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={0.3, 1, 1}}))
 		else
 			eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=0.3, g=1, b=1, a=1}))
@@ -1392,7 +1392,7 @@ newEffect{
 		eff.tmpid = self:addTemporaryValue("chargespike_shield", eff.power)
 		self.chargespike_shield_absorb = eff.power
 
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={0.8, 1, 0.2}}))
 		else
 			eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=0.8, g=1, b=0.2, a=1}))
@@ -2381,7 +2381,7 @@ newEffect{
 	activate = function(self, eff)
 		self.resonance_field_absorb = eff.power
 		eff.sid = self:addTemporaryValue("resonance_field", eff.power)
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={1, 1, 0}}))
 		--	eff.particle = self:addParticles(Particles.new("shader_shield", 1, {img="shield2", size_factor=1.25}, {type="shield", time_factor=6000, color={1, 1, 0}}))
 		else
@@ -2471,7 +2471,7 @@ newEffect{
 		if dream_prison then
 			eff.dur = eff.dur + 1
 			if not eff.particle then
-				if core.shader.active() then
+				if core.shader.active(4) then
 					eff.particle = self:addParticles(Particles.new("shader_shield", 1, {img="shield2", size_factor=1.25}, {type="shield", time_factor=6000, aadjust=5, color={0, 1, 1}}))
 				else
 					eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=0, g=1, b=1, a=1}))
@@ -2527,7 +2527,7 @@ newEffect{
 		if dream_prison then
 			eff.dur = eff.dur + 1
 			if not eff.particle then
-				if core.shader.active() then
+				if core.shader.active(4) then
 					eff.particle = self:addParticles(Particles.new("shader_shield", 1, {img="shield2", size_factor=1.25}, {type="shield", time_factor=6000, aadjust=5, color={0, 1, 1}}))
 				else
 					eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=0, g=1, b=1, a=1}))
@@ -2579,7 +2579,7 @@ newEffect{
 		if dream_prison then
 			eff.dur = eff.dur + 1
 			if not eff.particle then
-				if core.shader.active() then
+				if core.shader.active(4) then
 					eff.particle = self:addParticles(Particles.new("shader_shield", 1, {img="shield2", size_factor=1.25}, {type="shield", aadjust=5, color={0, 1, 1}}))
 				else
 					eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=0, g=1, b=1, a=1}))
@@ -2740,7 +2740,7 @@ newEffect{
 		end
 	end,
 	activate = function(self, eff)
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {size_factor=1.1}, {type="shield", time_factor=-8000, llpow=1, aadjust=7, color={1, 0.5, 0}}))
 		else
 			eff.particle = self:addParticles(Particles.new("generic_shield", 1, {r=1, g=0.5, b=0.0, a=1}))
diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua
index 4ceadc1250cda4d849b037cfc083a6b14e272734..eb7bcd7ac77ad4808b4f8ce4722ecc0c62589152 100644
--- a/game/modules/tome/data/timed_effects/other.lua
+++ b/game/modules/tome/data/timed_effects/other.lua
@@ -129,7 +129,7 @@ newEffect{
 		--- Warning there can be only one time shield active at once for an actor
 		self.time_shield_absorb = eff.power
 		self.time_shield_absorb_max = eff.power
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = self:addParticles(Particles.new("shader_shield", 1, {img="shield3"}, {type="shield", time_factor=2000, color={1, 1, 0.3}}))
 		else
 			eff.particle = self:addParticles(Particles.new("time_shield_bubble", 1))
@@ -1697,7 +1697,7 @@ newEffect{
 		eff.tid = eff.target:addTemporaryValue("no_timeflow", 1)
 		eff.imid = eff.target:addTemporaryValue("status_effect_immune", 1)
 		eff.target.energy.value = 0
-		if core.shader.active() then
+		if core.shader.active(4) then
 			eff.particle = eff.target:addParticles(Particles.new("shader_shield", 1, {img="shield2", size_factor=1.25}, {type="shield", time_factor=6000, aadjust=5, color={0, 1, 1}}))
 		else
 			eff.particle = eff.target:addParticles(Particles.new("generic_shield", 1, {r=0, g=1, b=1, a=1}))
diff --git a/game/modules/tome/data/zones/shertul-fortress/grids.lua b/game/modules/tome/data/zones/shertul-fortress/grids.lua
index 7ebe1cecac24190d7f63e9512a2c98b24e53f6a2..66b8ad0d2b225d78e60f2bdab09c82df3e7919aa 100644
--- a/game/modules/tome/data/zones/shertul-fortress/grids.lua
+++ b/game/modules/tome/data/zones/shertul-fortress/grids.lua
@@ -138,7 +138,7 @@ newEntity{ base = "FARPORTAL", define_as = "CFARPORTAL",
 		class.new{image="terrain/farportal-base.png", display_x=-1, display_y=-1, display_w=3, display_h=3},
 	},
 	on_added = function(self, level, x, y)
-		if core.shader.active() then
+		if core.shader.active(4) then
 			level.map:particleEmitter(x, y, 3, "shader_shield", {}, {type="shield", time_factor=8000, color={0.3, 0.4, 0.7}})
 		end
 		level.map:particleEmitter(x, y, 3, "farportal_lightning")
diff --git a/src/shaders.c b/src/shaders.c
index db853ca3ba9b10028b0cdcd86f88faa77d061656..964be3fd416e2804001f632da669c9931d061004 100644
--- a/src/shaders.c
+++ b/src/shaders.c
@@ -260,6 +260,12 @@ static int program_use(lua_State *L)
 
 static int shader_is_active(lua_State *L)
 {
+	if (lua_isnumber(L, 1)) {
+		if (lua_tonumber(L, 1) == 4) {
+			lua_pushboolean(L, shaders_active && GLEW_EXT_gpu_shader4);
+			return 1;
+		}
+	}
 	lua_pushboolean(L, shaders_active);
 	return 1;
 }