From 821c7c77d82a7089a0c88f6750b490efc809b625 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 2 Aug 2023 16:37:15 +0900 Subject: [PATCH] much more elegant solution than stretching texture using batch --- src/net/torvald/terrarum/App.java | 2 +- .../terrarum/modulebasegame/clut/Skybox.kt | 18 +++++++- .../torvald/terrarum/weather/WeatherMixer.kt | 41 ++++++++++++------- src/shaders/blendGlow.frag | 5 ++- src/shaders/blendMax.frag | 22 ++++++++++ src/shaders/blendMax.vert | 19 +++++++++ src/shaders/passthrurgb.frag | 16 -------- src/shaders/rgbonly.frag | 2 +- 8 files changed, 88 insertions(+), 37 deletions(-) create mode 100644 src/shaders/blendMax.frag create mode 100644 src/shaders/blendMax.vert delete mode 100644 src/shaders/passthrurgb.frag diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index 41fd078c9..5dd385eda 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -936,7 +936,7 @@ public class App implements ApplicationListener { shaderHicolour = loadShaderFromClasspath("shaders/default.vert", "shaders/hicolour.frag"); shaderDebugDiff = loadShaderFromClasspath("shaders/default.vert", "shaders/diff.frag"); - shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/passthrurgb.frag"); + shaderColLUT = loadShaderFromClasspath("shaders/default.vert", "shaders/rgbonly.frag"); shaderGhastlyWhite = loadShaderFromClasspath("shaders/default.vert", "shaders/ghastlywhite.frag"); // make gamepad(s) diff --git a/src/net/torvald/terrarum/modulebasegame/clut/Skybox.kt b/src/net/torvald/terrarum/modulebasegame/clut/Skybox.kt index e5eb0ec74..a468c3163 100644 --- a/src/net/torvald/terrarum/modulebasegame/clut/Skybox.kt +++ b/src/net/torvald/terrarum/modulebasegame/clut/Skybox.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.utils.Disposable import com.jme3.math.FastMath +import com.jme3.math.Vector2f import net.torvald.colourutil.CIEXYZ import net.torvald.colourutil.toColor import net.torvald.colourutil.toRGB @@ -55,12 +56,25 @@ object Skybox : Disposable { return texRegions.get(alb * elevCnt + elev, turb) } - fun getStrip(turbidity: Double, albedo: Double): TextureRegion { + fun getUV(elevationDeg: Double, turbidity: Double, albedo: Double): Pair { val turb = turbidity.coerceIn(1.0, 10.0).minus(1.0).times(3.0).roundToInt() val alb = albedo.coerceIn(0.1, 0.9).minus(0.1).times(5.0).roundToInt() - return texStripRegions.get(alb, turb) + val region = texStripRegions.get(alb, turb) + + val elev = elevationDeg.coerceIn(-75.0, 75.0).plus(75.0).div(150.0) + + val u = region.u + (elev / albedoCnt).toFloat() + + return tex to floatArrayOf( + u, + region.v, + u, + region.v2 + ) } + private val texcoordEpsilon = 1f / 131072f + private fun Float.scaleFun() = (1f - 1f / 2f.pow(this/6f)) * 0.97f diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index e1057f7b0..b912fe2e6 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -1,7 +1,9 @@ package net.torvald.terrarum.weather +import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.* +import com.badlogic.gdx.graphics.g2d.TextureRegion import com.jme3.math.FastMath import net.torvald.gdx.graphics.Cvec import net.torvald.random.HQRNG @@ -13,6 +15,7 @@ import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.gameworld.WorldTime.Companion.DAY_LENGTH +import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.RNGConsumer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.clut.Skybox @@ -22,6 +25,10 @@ import net.torvald.terrarum.worlddrawer.WorldCamera import java.io.File import java.io.FileFilter +/** + * Currently there is a debate whether this module must be part of the engine or the basegame + */ + /** * * @@ -38,8 +45,6 @@ internal object WeatherMixer : RNGConsumer { override val RNG = HQRNG() - private val renderng = HQRNG() - var globalLightOverridden = false var weatherList: HashMap> @@ -62,6 +67,10 @@ internal object WeatherMixer : RNGConsumer { var forceSolarElev: Double? = null var forceTurbidity: Double? = null + val starmapTex: TextureRegion = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "weathers/astrum.png"))) + + private val shaderBlendMax = App.loadShaderFromClasspath("shaders/blendMax.vert", "shaders/blendMax.frag") + override fun loadFromSave(s0: Long, s1: Long) { super.loadFromSave(s0, s1) internalReset() @@ -162,6 +171,10 @@ internal object WeatherMixer : RNGConsumer { * Sub-portion of IngameRenderer. You are not supposed to directly deal with this. */ internal fun render(camera: Camera, batch: FlippingSpriteBatch, world: GameWorld) { + drawSkybox(camera, batch, world) + } + + private fun drawSkybox(camera: Camera, batch: FlippingSpriteBatch, world: GameWorld) { val parallaxZeroPos = (world.height / 3f) val parallaxDomainSize = 300f @@ -198,24 +211,16 @@ internal object WeatherMixer : RNGConsumer { val thisTurbidity = forceTurbidity ?: turbidity // TODO trilinear with (deg, turb, alb) - val texture1 = Skybox.getStrip(thisTurbidity, 0.3) - -// println("degThis=$degThis, degNext=$degNext, lerp=$lerpScale") - - val stripXcentre = ((solarElev + 75.0) / 150.0).toFloat() - val backMag = 16777216f - val backX = -stripXcentre * backMag - val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f) + val (tex, uvs) = Skybox.getUV(solarElev, thisTurbidity, 0.3) + batch.inUse { batch.shader = null batch.color = Color.WHITE - batch.draw(texture1, backX, gradY, backMag + App.scr.wf, gH) + batch.draw(tex, 0f, gradY, App.scr.wf, gH, uvs[0], uvs[1], uvs[2], uvs[3]) batch.color = Color.WHITE } - - } private operator fun Color.times(other: Color) = Color(this.r * other.r, this.g * other.g, this.b * other.b, 1f) @@ -300,7 +305,7 @@ internal object WeatherMixer : RNGConsumer { fun getWeatherList(classification: String) = weatherList[classification]!! fun getRandomWeather(classification: String) = - getWeatherList(classification)[HQRNG().nextInt(getWeatherList(classification).size)] + getWeatherList(classification)[RNG.nextInt(getWeatherList(classification).size)] fun readFromJson(file: File): BaseModularWeather = readFromJson(file.path) @@ -360,6 +365,12 @@ internal object WeatherMixer : RNGConsumer { } fun dispose() { - + weatherList.values.forEach { list -> + list.forEach { weather -> + weather.extraImages.forEach { it.tryDispose() } + } + } + starmapTex.texture.dispose() + shaderBlendMax.dispose() } } diff --git a/src/shaders/blendGlow.frag b/src/shaders/blendGlow.frag index 7e3098a52..538ea1069 100644 --- a/src/shaders/blendGlow.frag +++ b/src/shaders/blendGlow.frag @@ -11,9 +11,10 @@ uniform sampler2D u_texture; // world texture, has alpha value that is meaningfu uniform sampler2D tex1; // glow texture, SHOULD contain alpha of all 1.0 out vec4 fragColor; +vec2 boolean = vec2(0.0, 1.0); + void main(void) { vec4 colorTex0 = texture(u_texture, v_texCoords); // lightmap (RGB) pre-mixed vec4 colorTex1 = texture(tex1, v_texCoords); // lightmap (A) pre-mixed - - fragColor = vec4(max(colorTex0.rgb, colorTex1.rgb), colorTex0.a); + fragColor = (max(colorTex0, colorTex1) * boolean.yyyx) + (colorTex0 * boolean.xxxy); } \ No newline at end of file diff --git a/src/shaders/blendMax.frag b/src/shaders/blendMax.frag new file mode 100644 index 000000000..8e84633bf --- /dev/null +++ b/src/shaders/blendMax.frag @@ -0,0 +1,22 @@ +#version 150 +#ifdef GL_ES + precision mediump float; +#endif + + +in vec4 v_color; +in vec2 v_texCoord0; +in vec2 v_texCoord1; +uniform sampler2D u_texture; // world texture, has alpha value that is meaningful + +uniform sampler2D tex1; // glow texture, SHOULD contain alpha of all 1.0 +out vec4 fragColor; + +vec2 boolean = vec2(0.0, 1.0); + +void main(void) { + vec4 colorTex0 = texture(u_texture, v_texCoord0); // lightmap (RGB) pre-mixed + vec4 colorTex1 = texture(tex1, v_texCoord1); // lightmap (A) pre-mixed +// fragColor = (max(colorTex0, colorTex1) * boolean.yyyx) + boolean.xxxy; + fragColor = colorTex0; +} \ No newline at end of file diff --git a/src/shaders/blendMax.vert b/src/shaders/blendMax.vert new file mode 100644 index 000000000..92de043e6 --- /dev/null +++ b/src/shaders/blendMax.vert @@ -0,0 +1,19 @@ +#version 150 + +in vec4 a_position; +in vec4 a_color; +in vec2 a_texCoord0; +in vec2 a_texCoord1; + +uniform mat4 u_projTrans; // camera.combined + +out vec4 v_color; +out vec2 v_texCoord0; +out vec2 v_texCoord1; + +void main() { + v_color = a_color; + v_texCoord0 = a_texCoord0; + v_texCoord1 = a_texCoord1; + gl_Position = u_projTrans * a_position; +} \ No newline at end of file diff --git a/src/shaders/passthrurgb.frag b/src/shaders/passthrurgb.frag deleted file mode 100644 index b09893c8f..000000000 --- a/src/shaders/passthrurgb.frag +++ /dev/null @@ -1,16 +0,0 @@ -#version 150 -#ifdef GL_ES - precision mediump float; -#endif - - -in vec4 v_color; -in vec2 v_texCoords; - -uniform sampler2D u_texture; - -out vec4 fragColor; - -void main(void) { - fragColor = vec4(texture(u_texture, v_texCoords).rgb, 1.0); -} \ No newline at end of file diff --git a/src/shaders/rgbonly.frag b/src/shaders/rgbonly.frag index 9cc745088..5b7ad2f01 100644 --- a/src/shaders/rgbonly.frag +++ b/src/shaders/rgbonly.frag @@ -8,5 +8,5 @@ vec2 boolean = vec2(0.0, 1.0); out vec4 fragColor; void main(void) { - fragColor = texture(u_texture, v_texCoords).rgba * boolean.yyyx + boolean.xxxy; + fragColor = texture(u_texture, v_texCoords) * boolean.yyyx + boolean.xxxy; } \ No newline at end of file