diff --git a/src/main/java/de/bixilon/minosoft/config/config/game/graphics/GraphicsGameConfig.kt b/src/main/java/de/bixilon/minosoft/config/config/game/graphics/GraphicsGameConfig.kt index 7812e50c7..5c5546f39 100644 --- a/src/main/java/de/bixilon/minosoft/config/config/game/graphics/GraphicsGameConfig.kt +++ b/src/main/java/de/bixilon/minosoft/config/config/game/graphics/GraphicsGameConfig.kt @@ -20,4 +20,5 @@ data class GraphicsGameConfig( var animations: AnimationsGameConfig = AnimationsGameConfig(), var particles: ParticleConfig = ParticleConfig(), @Json(name = "biome_blend_radius") var biomeBlendRadius: Int = 3, + @Json(name = "fog_enabled") var fogEnabled: Boolean = true, ) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt index bc51acb76..00e1a9d79 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/camera/Camera.kt @@ -18,6 +18,7 @@ import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.data.player.LocalPlayerEntity import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock +import de.bixilon.minosoft.data.text.ChatColors import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit @@ -50,6 +51,9 @@ class Camera( val connection: PlayConnection, val renderWindow: RenderWindow, ) { + var fogColor = ChatColors.GREEN + private var lastFogColor = fogColor + private var fogStart = 100.0f private var mouseSensitivity = Minosoft.getConfig().config.game.camera.moseSensitivity val entity: LocalPlayerEntity get() = connection.player @@ -111,7 +115,32 @@ class Camera( setRotation(yaw, pitch) } + private fun calculateFogDistance() { + if (!Minosoft.config.config.game.graphics.fogEnabled) { + fogStart = Float.MAX_VALUE + return + } + val renderDistance = 10 // ToDo: Calculate correct, get real render distance + fogStart = (renderDistance * ProtocolDefinition.SECTION_WIDTH_X).toFloat() + } + + private fun applyFog() { + for (shader in renderWindow.renderSystem.shaders) { + if (!shader.uniforms.contains("uFogColor")) { + continue + + } + shader.use() + + shader.setFloat("uFogStart", fogStart) + shader.setFloat("uFogEnd", fogStart + 10.0f) + shader.setRGBColor("uFogColor", fogColor) + } + lastFogColor = fogColor + } + fun init(renderWindow: RenderWindow) { + calculateFogDistance() renderWindow.inputHandler.registerCheckCallback( KeyBindingsNames.MOVE_SPRINT, KeyBindingsNames.MOVE_FORWARD, @@ -153,10 +182,19 @@ class Camera( projectionMatrix = projectionMatrix, viewProjectionMatrix = viewProjectionMatrix, )) + for (shader in renderWindow.renderSystem.shaders) { + shader.use() if (shader.uniforms.contains("uViewProjectionMatrix")) { - shader.use().setMat4("uViewProjectionMatrix", Mat4(viewProjectionMatrix)) + shader.setMat4("uViewProjectionMatrix", Mat4(viewProjectionMatrix)) } + if (shader.uniforms.contains("uCameraPosition")) { + shader.setVec3("uCameraPosition", entity.cameraPosition) + } + + shader.setFloat("uFogStart", fogStart) + shader.setFloat("uFogEnd", fogStart + 10.0f) + shader.setRGBColor("uFogColor", fogColor) } } @@ -204,6 +242,9 @@ class Camera( } fun draw() { + if (fogColor != lastFogColor) { + applyFog() + } val input = if (renderWindow.inputHandler.currentKeyConsumer == null) { MovementInput( pressingForward = renderWindow.inputHandler.isKeyBindingDown(KeyBindingsNames.MOVE_FORWARD), diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt index d7ee842cd..f93a44c45 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt @@ -115,20 +115,18 @@ class SkyRenderer( private fun checkSkyColor() { // ToDo: Calculate correct val brightness = 1.0f - val topColor = RGBColor((baseColor.red * brightness).toInt(), (baseColor.green * brightness).toInt(), (baseColor.blue * brightness).toInt()) - val bottomColor = RGBColor(topColor.red * 8 / 9, topColor.green * 8 / 9, topColor.blue * 8 / 9) - renderWindow.queue += { - updateSkyColor(topColor, bottomColor) + val skyColor = RGBColor((baseColor.red * brightness).toInt(), (baseColor.green * brightness).toInt(), (baseColor.blue * brightness).toInt()) + + renderWindow.inputHandler.camera.fogColor = skyColor + + + for (shader in renderWindow.renderSystem.shaders) { + if (shader.uniforms.contains("uSkyColor")) { + shader.use().setRGBColor("uSkyColor", skyColor) + } } } - private fun updateSkyColor(topColor: RGBColor, bottomColor: RGBColor) { - skyboxShader.use() - - skyboxShader.setRGBColor("uBottomColor", bottomColor) - skyboxShader.setRGBColor("uTopColor", topColor) - } - private fun drawSkybox() { checkSkyColor() skyboxShader.use() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt index 14cdc3a6a..39ea64307 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt @@ -22,6 +22,7 @@ import de.bixilon.minosoft.util.MMath import glm_.mat4x4.Mat4 import glm_.vec2.Vec2 import glm_.vec3.Vec3 +import glm_.vec3.Vec3d import glm_.vec4.Vec4 interface Shader { @@ -50,6 +51,10 @@ interface Shader { fun setTexture(uniformName: String, textureId: Int) fun setUniformBuffer(uniformName: String, uniformBuffer: UniformBuffer) + fun setVec3(uniformName: String, vec3: Vec3d) { + setVec3(uniformName, Vec3(vec3)) + } + operator fun set(uniformName: String, data: Any?) { data ?: return when (data) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt index c62d51762..971b1b3a9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt @@ -54,9 +54,11 @@ class OpenGLShader( throw ShaderLoadingException() } - this.uniforms += code.uniforms glShaderSourceARB(program, code.code) + + this.uniforms += code.uniforms + glCompileShaderARB(program) if (glGetObjectParameteriARB(program, GL_OBJECT_COMPILE_STATUS_ARB) == GL_FALSE) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt index 0b721f3b5..f4a9a5497 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/PositionAndRotationS2CP.kt @@ -82,6 +82,6 @@ class PositionAndRotationS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() { } override fun log() { - Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "LocalPlayerEntity position (position=$position, rotation=$rotation, onGround=$isOnGround, flags=$flags, teleportId=$teleportId, dismountVehicle=$dismountVehicle)" } + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Player position (position=$position, rotation=$rotation, onGround=$isOnGround, flags=$flags, teleportId=$teleportId, dismountVehicle=$dismountVehicle)" } } } diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl new file mode 100644 index 000000000..c99daeaaa --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl @@ -0,0 +1,47 @@ +/* + * Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +#ifdef POSTPROCESSING_FOG +in vec3 finVertexPosition; +uniform vec3 uCameraPosition; +uniform float uFogStart; +uniform float uFogEnd; +uniform vec4 uFogColor; + + +float getFogFactor(float distance) { + if (distance >= uFogEnd) { + return 0.0f; + } + if (distance <= uFogStart) { + return 1.0f; + } + + // ToDo: Exponential fog + return (uFogEnd - distance) / (uFogEnd - uFogStart); +} + + #endif + + +void main() { + work(); + + #ifdef POSTPROCESSING_FOG + float fogFactor = getFogFactor(distance(uCameraPosition, finVertexPosition)); + + if (fogFactor != 1.0f) { + outColor = vec4(mix(uFogColor.rgb, outColor.rgb, fogFactor), outColor.a); + }; + #endif +} diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/vertex.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/vertex.glsl new file mode 100644 index 000000000..07489de4f --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/vertex.glsl @@ -0,0 +1,19 @@ +/* + * Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +out vec3 finVertexPosition; + +void main() { + work(); + finVertexPosition = vinPosition; +} diff --git a/src/main/resources/assets/minosoft/rendering/shader/sky/skybox/sky_skybox.vsh b/src/main/resources/assets/minosoft/rendering/shader/sky/skybox/sky_skybox.vsh index 08eb7c997..da118a256 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/sky/skybox/sky_skybox.vsh +++ b/src/main/resources/assets/minosoft/rendering/shader/sky/skybox/sky_skybox.vsh @@ -19,15 +19,10 @@ out vec4 finColor; uniform mat4 uSkyViewProjectionMatrix; -uniform vec4 uBottomColor; -uniform vec4 uTopColor; +uniform vec4 uSkyColor; void main() { gl_Position = (uSkyViewProjectionMatrix * vec4(vinPosition, 1.0)).xyww; - if (vinPosition.y < 0.5f) { - finColor = uBottomColor; - } else { - finColor = uTopColor; - } + finColor = uSkyColor; } diff --git a/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh b/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh index f00117fb5..7c0c7ba39 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh +++ b/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh @@ -23,9 +23,11 @@ in float finInterpolation; in vec4 finTintColor; +#define POSTPROCESSING_FOG + #include "minosoft:texture" -void main() { +void work() { vec4 firstTexelColor = getTexture(finTextureIndex1, finTextureCoordinates1); if (firstTexelColor.a == 0.0f) { discard; @@ -44,3 +46,5 @@ void main() { outColor = mix(firstTexelColor, secondTexelColor, finInterpolation) * finTintColor; } + + #include "minosoft:postprocessing/fragment" diff --git a/src/main/resources/assets/minosoft/rendering/shader/world/world.vsh b/src/main/resources/assets/minosoft/rendering/shader/world/world.vsh index 886dd5e35..99bae7e8f 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/world/world.vsh +++ b/src/main/resources/assets/minosoft/rendering/shader/world/world.vsh @@ -31,14 +31,13 @@ out vec4 finTintColor; uniform mat4 uViewProjectionMatrix; +#define POSTPROCESSING_FOG #include "minosoft:animation" - #include "minosoft:color" - #include "minosoft:light" -void main() { +void work() { gl_Position = uViewProjectionMatrix * vec4(vinPosition, 1.0f); finTintColor = getRGBColor(vinTintColor) * getLight(vinLight); @@ -65,3 +64,5 @@ void main() { finInterpolation = interpolation / 100.0f; } + + #include "minosoft:postprocessing/vertex"