From 5458a4a60d8e4639b809a01b7efdafcb9f3e662d Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 16 Sep 2022 13:27:22 +0700 Subject: [PATCH] More GPU shadows tests --- .../kstarbound/client/ClientWorld.kt | 2 +- .../kstarbound/client/gl/GLStateTracker.kt | 20 ++++++++++++++++ .../kstarbound/client/gl/program/Programs.kt | 1 + .../kstarbound/client/render/LightRenderer.kt | 24 ++++++++++++++++--- .../resources/shaders/hard_light_geometry.fsh | 4 +++- .../resources/shaders/hard_light_geometry.vsh | 4 +++- 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientWorld.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientWorld.kt index 6755b9da..070f8598 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientWorld.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/ClientWorld.kt @@ -127,7 +127,7 @@ class ClientWorld( client.pushScissorRect(x, client.viewportHeight - y, x2 - x, y - y2) } - client.lightRenderer.renderSoftLight(lightPosition, color, radius = 20f, innerRadius = 1f) + client.lightRenderer.renderHardLight(lightPosition, color, radius = 20f) if (isScreenspaceRender) { client.popScissorRect() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt index 91b8a2c7..86bf65c5 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/GLStateTracker.kt @@ -52,6 +52,23 @@ private class GLStateSwitchTracker(private val enum: Int, private var value: Boo } } +private class GLStateFuncTracker(private val glFunc: (Int) -> Unit, private var value: Int) { + operator fun getValue(glStateTracker: GLStateTracker, property: KProperty<*>): Int { + return value + } + + operator fun setValue(glStateTracker: GLStateTracker, property: KProperty<*>, value: Int) { + glStateTracker.ensureSameThread() + + if (value == this.value) + return + + glFunc.invoke(value) + checkForGLError() + this.value = value + } +} + private class GLStateGenericTracker(private var value: T, private val callback: (T) -> Unit) : ReadWriteProperty { override fun getValue(thisRef: GLStateTracker, property: KProperty<*>): T { return value @@ -248,6 +265,9 @@ class GLStateTracker { var blend by GLStateSwitchTracker(GL_BLEND) var scissor by GLStateSwitchTracker(GL_SCISSOR_TEST) + var cull by GLStateSwitchTracker(GL_CULL_FACE) + var cullMode by GLStateFuncTracker(::glCullFace, GL_BACK) + var scissorRect by GLStateGenericTracker(ScissorRect(0, 0, 0, 0)) { // require(it.x >= 0) { "Invalid X ${it.x}"} // require(it.y >= 0) { "Invalid Y ${it.y}"} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/program/Programs.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/program/Programs.kt index df8f9916..fb2a4411 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/program/Programs.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/gl/program/Programs.kt @@ -87,6 +87,7 @@ class GLHardLightGeometryProgram(state: GLStateTracker) : GLInternalProgram(stat val transform = this["transform"]!! val localToWorldTransform = this["localToWorldTransform"]!! val lightPosition = this["lightPosition"]!! + val lightPenetration = this["lightPenetration"]!! val builder by lazy { StreamVertexBuilder(state, LightRenderer.SHADOW_FORMAT, GeometryType.QUADS_AS_LINES, 32) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/LightRenderer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/LightRenderer.kt index 415d37f5..aa3c614d 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/LightRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/LightRenderer.kt @@ -1,6 +1,8 @@ package ru.dbotthepony.kstarbound.client.render +import org.lwjgl.opengl.GL11.GL_BACK import org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT +import org.lwjgl.opengl.GL11.GL_FRONT import org.lwjgl.opengl.GL11.GL_RGBA import org.lwjgl.opengl.GL11.glClear import ru.dbotthepony.kstarbound.client.gl.BlendFunc @@ -139,6 +141,7 @@ class LightRenderer(val state: GLStateTracker) { position: Vector2f, color: Color = Color.WHITE, radius: Float = 10f, + lightPenetration: Float = 0.1f, stack: Matrix4fStack = state.matrixStack ) { state.ensureSameThread() @@ -157,7 +160,7 @@ class LightRenderer(val state: GLStateTracker) { // Геометрия val old = state.clearColor - state.clearColor = Color.BLACK + state.clearColor = CLEAR_COLOR_HARD glClear(GL_COLOR_BUFFER_BIT) checkForGLError() state.clearColor = old @@ -165,8 +168,9 @@ class LightRenderer(val state: GLStateTracker) { state.programs.hardLightGeometry.use() state.programs.hardLightGeometry.transform.set(stack.last) state.programs.hardLightGeometry.lightPosition.set(position) + state.programs.hardLightGeometry.lightPenetration.set(1f - lightPenetration) - state.blendFunc = BlendFunc.ONLY_ALPHA + state.blendFunc = BlendFunc.ONLY_BLEND_ALPHA for (renderer in geometry) { renderer.renderHardGeometry(this, position, radius, stack, state.programs.hardLightGeometry) @@ -183,7 +187,7 @@ class LightRenderer(val state: GLStateTracker) { builder.quad(position.x - radius, position.y - radius, position.x + radius, position.y + radius, QuadTransformers.uv()) builder.upload() - state.blendFunc = BLEND_MODE + state.blendFunc = BLEND_MODE_INV builder.draw() } finally { state.blendFunc = oldFunc @@ -229,10 +233,15 @@ class LightRenderer(val state: GLStateTracker) { state.blendFunc = BlendFunc.ONLY_BLEND_ALPHA + state.cull = true + state.cullMode = GL_BACK + for (renderer in geometry) { renderer.renderSoftGeometry(this, position, radius, stack, state.programs.softLightGeometry) } + state.cull = false + state.programs.light.use() state.programs.light.transform.set(stack.last) state.programs.light.baselineColor.set(color) @@ -247,6 +256,7 @@ class LightRenderer(val state: GLStateTracker) { state.blendFunc = BLEND_MODE_SOFT builder.draw() } finally { + state.cull = false state.blendFunc = oldFunc framebufferRender.unbind() } @@ -275,6 +285,7 @@ class LightRenderer(val state: GLStateTracker) { } companion object { + val CLEAR_COLOR_HARD = Color(0f, 0f, 0f, 0f) val CLEAR_COLOR_SOFT = Color(0f, 0f, 0f, 0f) val BLEND_MODE = BlendFunc( @@ -284,6 +295,13 @@ class LightRenderer(val state: GLStateTracker) { BlendFunc.Func.ONE, ) + val BLEND_MODE_INV = BlendFunc( + BlendFunc.Func.ONE_MINUS_DST_ALPHA, + BlendFunc.Func.ZERO, + BlendFunc.Func.ZERO, + BlendFunc.Func.ONE, + ) + val BLEND_MODE_SOFT = BlendFunc( BlendFunc.Func.ONE_MINUS_DST_ALPHA, BlendFunc.Func.ZERO, diff --git a/src/main/resources/shaders/hard_light_geometry.fsh b/src/main/resources/shaders/hard_light_geometry.fsh index 78164c03..ce2b12a6 100644 --- a/src/main/resources/shaders/hard_light_geometry.fsh +++ b/src/main/resources/shaders/hard_light_geometry.fsh @@ -5,6 +5,8 @@ uniform vec2 lightPosition; out vec4 resultColor; +uniform float lightPenetration; + void main() { - resultColor = vec4(0.0, 0.0, 0.0, 0.0); + resultColor = vec4(0.0, 0.0, 0.0, lightPenetration); } diff --git a/src/main/resources/shaders/hard_light_geometry.vsh b/src/main/resources/shaders/hard_light_geometry.vsh index 047d6dce..f575a8b9 100644 --- a/src/main/resources/shaders/hard_light_geometry.vsh +++ b/src/main/resources/shaders/hard_light_geometry.vsh @@ -6,9 +6,11 @@ layout (location = 0) in vec2 vertexPos; uniform mat4 transform; uniform mat4 localToWorldTransform; +uniform float lightPenetration; + out vec2 originalPos; void main() { - gl_Position = transform * localToWorldTransform * vec4(vertexPos, 0.0, 1.0); originalPos = (localToWorldTransform * vec4(vertexPos, 0.0, 1.0)).xy; + gl_Position = transform * localToWorldTransform * vec4(vertexPos, 0.0, 1.0); }