From 98212df076a58d9b521cc748f3ea55357514b173 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 9 Mar 2019 22:53:16 -0500 Subject: [PATCH] Water shader --- core/assets/bundles/bundle.properties | 1 + core/assets/shaders/mix.fragment | 19 ----- core/assets/shaders/water.fragment | 77 +++++++++++++++++++ .../src/io/anuke/mindustry/core/Renderer.java | 10 +-- .../anuke/mindustry/graphics/CacheLayer.java | 33 +++++++- .../mindustry/graphics/FloorRenderer.java | 13 +++- .../io/anuke/mindustry/graphics/Shaders.java | 16 ++++ .../ui/dialogs/SettingsMenuDialog.java | 1 + .../anuke/mindustry/world/blocks/Floor.java | 17 +++- .../mindustry/world/blocks/OreBlock.java | 4 +- 10 files changed, 158 insertions(+), 33 deletions(-) delete mode 100644 core/assets/shaders/mix.fragment create mode 100644 core/assets/shaders/water.fragment diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 083455a850..81b71ebf88 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -370,6 +370,7 @@ category.items = Items category.crafting = Crafting category.shooting = Shooting category.optional = Optional Enhancements +setting.animatedwater.name = Animated Water setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS diff --git a/core/assets/shaders/mix.fragment b/core/assets/shaders/mix.fragment deleted file mode 100644 index 92c19f24a6..0000000000 --- a/core/assets/shaders/mix.fragment +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef GL_ES -precision mediump float; -precision mediump int; -#endif - -uniform sampler2D u_texture; -uniform vec4 u_color; - -varying vec4 v_color; -varying vec2 v_texCoord; - -void main() { - - vec4 c = texture2D(u_texture, v_texCoord.xy); - - c = mix(c, vec4(u_color.rgb, c.a), v_color.a); - - gl_FragColor = c * vec4(v_color.rgb, 1.0); -} diff --git a/core/assets/shaders/water.fragment b/core/assets/shaders/water.fragment new file mode 100644 index 0000000000..83910bbe5f --- /dev/null +++ b/core/assets/shaders/water.fragment @@ -0,0 +1,77 @@ +#ifdef GL_ES +precision highp float; +precision mediump int; +#endif + +uniform sampler2D u_texture; + +uniform vec2 camerapos; +uniform vec2 screensize; +uniform float time; + +varying vec4 v_color; +varying vec2 v_texCoord; + +vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); } + +float snoise(vec2 v){ + const vec4 C = vec4(0.211324865405187, 0.366025403784439, + -0.577350269189626, 0.024390243902439); + vec2 i = floor(v + dot(v, C.yy) ); + vec2 x0 = v - i + dot(i, C.xx); + vec2 i1; + i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + vec4 x12 = x0.xyxy + C.xxzz; + x12.xy -= i1; + i = mod(i, 289.0); + vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + + i.x + vec3(0.0, i1.x, 1.0 )); + vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), + dot(x12.zw,x12.zw)), 0.0); + m = m*m ; + m = m*m ; + vec3 x = 2.0 * fract(p * C.www) - 1.0; + vec3 h = abs(x) - 0.5; + vec3 ox = floor(x + 0.5); + vec3 a0 = x - ox; + m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); + vec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + g.yz = a0.yz * x12.xz + h.yz * x12.yw; + return 130.0 * dot(m, g); +} + +void main() { + + vec2 c = v_texCoord.xy; + vec4 color = texture2D(u_texture, c) * v_color; + + vec2 v = vec2(1.0/screensize.x, 1.0/screensize.y); + vec2 coords = vec2(c.x / v.x + camerapos.x, c.y / v.y + camerapos.y); + + float stime = time / 5.0; + + float mscl = 30.0; + float mth = 5.0; + + color = texture2D(u_texture, c + vec2(sin(stime/3.0 + coords.y/0.75) * v.x, 0.0)) * vec4(0.9, 0.9, 1, 1.0); + color.a = 1.0; + + float n1 = snoise(coords / 40.0 + vec2(time) / 200.0); + float n2 = snoise((coords + vec2(632.0)) / 25.0 + vec2(0.0, -time) / 190.0); + + float r = (n1 + n2) * 3.0; + + if(mod(float(int(coords.x + coords.y*1.1 + sin(stime / 8.0 + coords.x/5.0 - coords.y/100.0)*2.0)) + + sin(stime / 20.0 + coords.y/3.0) * 1.0 + + sin(stime / 10.0 + coords.y/2.0) * 2.0 + + sin(stime / 7.0 + coords.y/1.0) * 0.5 + + sin(coords.x + coords.y) + + sin(stime / 20.0 + coords.x/4.0) * 1.0, mscl) + r < mth){ + + color *= 1.2; + color.a = 1.0; + } + + gl_FragColor = color; +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 354d721392..a6dbfdab31 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -44,7 +44,7 @@ public class Renderer implements ApplicationListener{ public final MinimapRenderer minimap = new MinimapRenderer(); public final OverlayRenderer overlays = new OverlayRenderer(); - private FrameBuffer shieldBuffer = new FrameBuffer(2, 2); + public FrameBuffer shieldBuffer = new FrameBuffer(2, 2); private Color clearColor; private float targetscale = io.anuke.arc.scene.ui.layout.Unit.dp.scl(4); private float camerascale = targetscale; @@ -159,6 +159,10 @@ public class Renderer implements ApplicationListener{ graphics.clear(clearColor); + if(graphics.getWidth() >= 2 && graphics.getHeight() >= 2 && (shieldBuffer.getWidth() != graphics.getWidth() || shieldBuffer.getHeight() != graphics.getHeight())){ + shieldBuffer.resize(graphics.getWidth(), graphics.getHeight()); + } + Draw.proj(camera.projection()); blocks.floor.drawFloor(); @@ -200,10 +204,6 @@ public class Renderer implements ApplicationListener{ drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests); if(EntityDraw.countInBounds(shieldGroup) > 0){ - if(graphics.getWidth() >= 2 && graphics.getHeight() >= 2 && (shieldBuffer.getWidth() != graphics.getWidth() || shieldBuffer.getHeight() != graphics.getHeight())){ - shieldBuffer.resize(graphics.getWidth(), graphics.getHeight()); - } - Draw.flush(); shieldBuffer.begin(); graphics.clear(Color.CLEAR); diff --git a/core/src/io/anuke/mindustry/graphics/CacheLayer.java b/core/src/io/anuke/mindustry/graphics/CacheLayer.java index e84bd0a823..0a01cc202c 100644 --- a/core/src/io/anuke/mindustry/graphics/CacheLayer.java +++ b/core/src/io/anuke/mindustry/graphics/CacheLayer.java @@ -1,7 +1,38 @@ package io.anuke.mindustry.graphics; +import io.anuke.arc.Core; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.g2d.Draw; + +import static io.anuke.arc.Core.camera; +import static io.anuke.mindustry.Vars.renderer; + public enum CacheLayer{ - water, + water{ + @Override + public void begin(){ + if(!Core.settings.getBool("animatedwater")) return; + + renderer.blocks.floor.endc(); + renderer.shieldBuffer.begin(); + Core.graphics.clear(Color.CLEAR); + renderer.blocks.floor.beginc(); + } + + @Override + public void end(){ + if(!Core.settings.getBool("animatedwater")) return; + + renderer.blocks.floor.endc(); + renderer.shieldBuffer.end(); + + Draw.shader(Shaders.water); + Draw.rect(Draw.wrap(renderer.shieldBuffer.getTexture()), camera.position.x, camera.position.y, camera.width, -camera.height); + Draw.shader(); + + renderer.blocks.floor.beginc(); + } + }, lava, oil, space, diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index cac217ce05..7bc7acc202 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -95,6 +95,14 @@ public class FloorRenderer{ endDraw(); } + public void beginc(){ + cbatch.beginDraw(); + } + + public void endc(){ + cbatch.endDraw(); + } + public void beginDraw(){ if(cache == null){ return; @@ -124,8 +132,6 @@ public class FloorRenderer{ int crangex = (int) (camera.width / (chunksize * tilesize)) + 1; int crangey = (int) (camera.height / (chunksize * tilesize)) + 1; - SpriteBatch batch = Core.batch; - Core.batch = cbatch; layer.begin(); for(int x = -crangex; x <= crangex; x++){ @@ -144,7 +150,6 @@ public class FloorRenderer{ } layer.end(); - Core.batch = batch; } private void cacheChunk(int cx, int cy){ @@ -191,6 +196,8 @@ public class FloorRenderer{ tile.block().draw(tile); }else if(floor.cacheLayer == layer && (world.isAccessible(tile.x,tile.y) || tile.block().cacheLayer != CacheLayer.walls || !tile.block().fillsTile)){ floor.draw(tile); + }else if(floor.cacheLayer.ordinal() < layer.ordinal() && layer != CacheLayer.walls){ + floor.drawNonLayer(tile); } } } diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 223cf38dee..b6b725806b 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -14,6 +14,7 @@ public class Shaders{ public static UnitBuild build; public static FogShader fog; public static MenuShader menu; + public static SurfaceShader water; public static void init(){ shadow = new Shadow(); @@ -22,6 +23,7 @@ public class Shaders{ build = new UnitBuild(); fog = new FogShader(); menu = new MenuShader(); + water = new SurfaceShader("water"); } public static class MenuShader extends LoadShader{ @@ -123,6 +125,20 @@ public class Shaders{ Core.camera.height ); } } + + public static class SurfaceShader extends LoadShader{ + + public SurfaceShader(String frag){ + super(frag, "default"); + } + + @Override + public void apply(){ + setUniformf("camerapos", Core.camera.position.x - Core.camera.width / 2, Core.camera.position.y - Core.camera.height / 2); + setUniformf("screensize", Core.camera.width, Core.camera.height); + setUniformf("time", Time.time()); + } + } public static class LoadShader extends Shader{ public LoadShader(String frag, String vert){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index fd998b7d0c..60e0ad707e 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -195,6 +195,7 @@ public class SettingsMenuDialog extends SettingsDialog{ graphics.checkPref("fps", false); graphics.checkPref("indicators", true); + graphics.checkPref("animatedwater", !mobile); graphics.checkPref("lasers", true); } diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index a7f4430371..2bd9db15ac 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -114,13 +114,24 @@ public class Floor extends Block{ drawEdges(tile); } + + public void drawNonLayer(Tile tile){ + Mathf.random.setSeed(tile.pos()); + + drawEdges(tile, true); + } + protected void drawEdges(Tile tile){ + drawEdges(tile, false); + } + + protected void drawEdges(Tile tile, boolean sameLayer){ eq = 0; for(int i = 0; i < 8; i++){ Point2 point = Geometry.d8[i]; Tile other = tile.getNearby(point); - if(other != null && doEdge(other.floor()) && other.floor().edges() != null){ + if(other != null && doEdge(other.floor(), sameLayer) && other.floor().edges() != null){ eq |= (1 << i); } } @@ -140,8 +151,8 @@ public class Floor extends Block{ return ((Floor)blendGroup).edges; } - protected boolean doEdge(Floor other){ - return (other.blendGroup.id > blendGroup.id || edges() == null) && other.edgeOnto(this); + protected boolean doEdge(Floor other, boolean sameLayer){ + return (other.blendGroup.id > blendGroup.id || edges() == null) && other.edgeOnto(this) && (other.cacheLayer.ordinal() > this.cacheLayer.ordinal() || !sameLayer); } protected boolean edgeOnto(Floor other){ diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index 97c7dec8a9..5ddcdde94e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -43,8 +43,8 @@ public class OreBlock extends Floor{ } @Override - public boolean doEdge(Floor floor){ - return floor != base && super.doEdge(floor); + public boolean doEdge(Floor floor, boolean f){ + return floor != base && super.doEdge(floor, f); } @Override