mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 19:14:05 +09:00
bayer alpha for particles
This commit is contained in:
6
src/net/torvald/colourutil/OKHsvUtil.kt
Normal file
6
src/net/torvald/colourutil/OKHsvUtil.kt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package net.torvald.colourutil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2024-04-17.
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ import net.torvald.terrarum.*
|
|||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.Hitbox
|
import net.torvald.terrarum.gameactors.Hitbox
|
||||||
import net.torvald.terrarum.gameactors.drawBodyInGoodPosition
|
import net.torvald.terrarum.gameactors.drawBodyInGoodPosition
|
||||||
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,30 +77,29 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, var despawnUponCollision
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun drawBody(frameDelta: Float, batch: SpriteBatch) {
|
open fun drawBody(frameDelta: Float, batch: SpriteBatch) {
|
||||||
if (!flagDespawn) {
|
defaultDrawFun(frameDelta, batch) { x, y -> batch.draw(body, x, y, hitbox.width.toFloat(), hitbox.height.toFloat()) }
|
||||||
batch.color = drawColour
|
|
||||||
drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat()) { x, y ->
|
|
||||||
batch.draw(body, x, y, hitbox.width.toFloat(), hitbox.height.toFloat())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun drawGlow(frameDelta: Float, batch: SpriteBatch) {
|
open fun drawGlow(frameDelta: Float, batch: SpriteBatch) {
|
||||||
if (!flagDespawn && glow != null) {
|
if (glow != null)
|
||||||
batch.color = drawColour
|
defaultDrawFun(frameDelta, batch) { x, y -> batch.draw(glow, x, y, hitbox.width.toFloat(), hitbox.height.toFloat()) }
|
||||||
drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat()) { x, y ->
|
|
||||||
batch.draw(glow, x, y, hitbox.width.toFloat(), hitbox.height.toFloat())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun drawEmissive(frameDelta: Float, batch: SpriteBatch) {
|
open fun drawEmissive(frameDelta: Float, batch: SpriteBatch) {
|
||||||
if (!flagDespawn && emissive != null) {
|
if (emissive != null)
|
||||||
|
defaultDrawFun(frameDelta, batch) { x, y -> batch.draw(emissive, x, y, hitbox.width.toFloat(), hitbox.height.toFloat()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun defaultDrawFun(frameDelta: Float, batch: SpriteBatch, drawJob: (x: Float, y: Float) -> Unit) {
|
||||||
|
val oldColour = batch.color.cpy()
|
||||||
|
if (!flagDespawn) {
|
||||||
|
batch.shader = IngameRenderer.shaderBayerAlpha
|
||||||
batch.color = drawColour
|
batch.color = drawColour
|
||||||
drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat()) { x, y ->
|
drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat()) { x, y ->
|
||||||
batch.draw(emissive, x, y, hitbox.width.toFloat(), hitbox.height.toFloat())
|
drawJob(x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
batch.color = oldColour
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun dispose() {
|
open fun dispose() {
|
||||||
|
|||||||
@@ -88,15 +88,10 @@ class ParticleVanishingText(val text: String, x: Double, y: Double, noCollision:
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun drawBody(frameDelta: Float, batch: SpriteBatch) {
|
override fun drawBody(frameDelta: Float, batch: SpriteBatch) {
|
||||||
if (!flagDespawn) {
|
lines.forEachIndexed { index, line ->
|
||||||
val oldColour = batch.color.cpy()
|
defaultDrawFun(frameDelta, batch) { x, y ->
|
||||||
batch.color = drawColour
|
TinyAlphNum.draw(batch, line, x, y + TinyAlphNum.H * index)
|
||||||
lines.forEachIndexed { index, line ->
|
|
||||||
drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat() + TinyAlphNum.H * index) { x, y ->
|
|
||||||
TinyAlphNum.draw(batch, line, x, y )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
batch.color = oldColour
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,13 +131,6 @@ open class ParticleVanishingSprite(val sprite: TextureRegionPack, val delay: Flo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun drawBody(frameDelta: Float, batch: SpriteBatch) {
|
override fun drawBody(frameDelta: Float, batch: SpriteBatch) {
|
||||||
if (!flagDespawn) {
|
defaultDrawFun(frameDelta, batch) { x, y -> batch.draw(sprite.get(frame, row), x, y) }
|
||||||
val oldColour = batch.color.cpy()
|
|
||||||
batch.color = drawColour
|
|
||||||
drawBodyInGoodPosition(hitbox.startX.toFloat(), hitbox.startY.toFloat()) { x, y ->
|
|
||||||
batch.draw(sprite.get(frame, row), x, y)
|
|
||||||
}
|
|
||||||
batch.color = oldColour
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,6 +102,8 @@ object IngameRenderer : Disposable {
|
|||||||
val shaderForActors: ShaderProgram
|
val shaderForActors: ShaderProgram
|
||||||
val shaderDemultiply: ShaderProgram
|
val shaderDemultiply: ShaderProgram
|
||||||
|
|
||||||
|
val shaderBayerAlpha: ShaderProgram
|
||||||
|
|
||||||
val shaderVibrancy: ShaderProgram
|
val shaderVibrancy: ShaderProgram
|
||||||
|
|
||||||
private val WIDTH = App.scr.width
|
private val WIDTH = App.scr.width
|
||||||
@@ -144,6 +146,7 @@ object IngameRenderer : Disposable {
|
|||||||
shaderBlendGlowTex1Flip = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlowTex1Flip.frag")
|
shaderBlendGlowTex1Flip = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlowTex1Flip.frag")
|
||||||
shaderDemultiply = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/demultiply.frag")
|
shaderDemultiply = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/demultiply.frag")
|
||||||
|
|
||||||
|
shaderBayerAlpha = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/bayeralpha.frag")
|
||||||
|
|
||||||
shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag")
|
shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag")
|
||||||
shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag")
|
shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag")
|
||||||
@@ -1176,6 +1179,8 @@ object IngameRenderer : Disposable {
|
|||||||
shaderForActors.dispose()
|
shaderForActors.dispose()
|
||||||
shaderDemultiply.dispose()
|
shaderDemultiply.dispose()
|
||||||
|
|
||||||
|
shaderBayerAlpha.dispose()
|
||||||
|
|
||||||
shaderVibrancy.dispose()
|
shaderVibrancy.dispose()
|
||||||
|
|
||||||
if (::fboRGBexport.isInitialized) fboRGBexport.tryDispose()
|
if (::fboRGBexport.isInitialized) fboRGBexport.tryDispose()
|
||||||
|
|||||||
@@ -141,18 +141,18 @@ class FixtureMechanicalTines : Electric {
|
|||||||
|
|
||||||
private fun prel(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): List<Long> {
|
private fun prel(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): List<Long> {
|
||||||
return toPianoRoll(
|
return toPianoRoll(
|
||||||
1L shl n1 to TICK_DIVISOR+2, 1L shl n2 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR,
|
1L shl n1 to TICK_DIVISOR+2, 1L shl n2 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR-1,
|
||||||
1L shl n5 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR, 1L shl n5 to TICK_DIVISOR,
|
1L shl n5 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR, 1L shl n5 to TICK_DIVISOR,
|
||||||
1L shl n1 to TICK_DIVISOR, 1L shl n2 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR,
|
1L shl n1 to TICK_DIVISOR, 1L shl n2 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR-1,
|
||||||
1L shl n5 to TICK_DIVISOR-1, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR, 1L shl n5 to TICK_DIVISOR)
|
1L shl n5 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR, 1L shl n5 to TICK_DIVISOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun end1(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int, n6: Int, n7: Int, n8: Int, n9: Int): List<Long> {
|
private fun end1(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int, n6: Int, n7: Int, n8: Int, n9: Int): List<Long> {
|
||||||
return toPianoRoll(
|
return toPianoRoll(
|
||||||
1L shl n1 to TICK_DIVISOR+2, 1L shl n2 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR,
|
1L shl n1 to TICK_DIVISOR+2, 1L shl n2 to TICK_DIVISOR, 1L shl n3 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR-1,
|
||||||
1L shl n5 to TICK_DIVISOR, 1L shl n6 to TICK_DIVISOR, 1L shl n5 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR,
|
1L shl n5 to TICK_DIVISOR, 1L shl n6 to TICK_DIVISOR, 1L shl n5 to TICK_DIVISOR, 1L shl n4 to TICK_DIVISOR,
|
||||||
1L shl n5 to TICK_DIVISOR, 1L shl n7 to TICK_DIVISOR, 1L shl n8 to TICK_DIVISOR, 1L shl n7 to TICK_DIVISOR,
|
1L shl n5 to TICK_DIVISOR, 1L shl n7 to TICK_DIVISOR, 1L shl n8 to TICK_DIVISOR, 1L shl n7 to TICK_DIVISOR-1,
|
||||||
1L shl n8 to TICK_DIVISOR-1, 1L shl n9 to TICK_DIVISOR, 1L shl n8 to TICK_DIVISOR, 1L shl n9 to TICK_DIVISOR)
|
1L shl n8 to TICK_DIVISOR, 1L shl n9 to TICK_DIVISOR, 1L shl n8 to TICK_DIVISOR, 1L shl n9 to TICK_DIVISOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun end2(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int, n6: Int, n7: Int, n8: Int, n9: Int): List<Long> {
|
private fun end2(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int, n6: Int, n7: Int, n8: Int, n9: Int): List<Long> {
|
||||||
@@ -204,7 +204,7 @@ object ParticleMusicalNoteFactory {
|
|||||||
private val noteColours = (0..60).map {
|
private val noteColours = (0..60).map {
|
||||||
val hue = it / 60f * 270f
|
val hue = it / 60f * 270f
|
||||||
val saturation = 100f
|
val saturation = 100f
|
||||||
val lightness = 80f
|
val lightness = 70f
|
||||||
val (r, g, b) = HUSLColorConverter.hsluvToRgb(floatArrayOf(hue, saturation, lightness))
|
val (r, g, b) = HUSLColorConverter.hsluvToRgb(floatArrayOf(hue, saturation, lightness))
|
||||||
Color(r, g, b, 1f)
|
Color(r, g, b, 1f)
|
||||||
}
|
}
|
||||||
@@ -214,13 +214,7 @@ object ParticleMusicalNoteFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun makeRandomParticle(note: Int, pos: Vector2): ParticleVanishingTexture {
|
fun makeRandomParticle(note: Int, pos: Vector2): ParticleVanishingTexture {
|
||||||
val it = object : ParticleVanishingTexture(tex.get(rng.nextInt(3), rng.nextInt(2)), pos.x, pos.y, false) {
|
val it = ParticleVanishingTexture(tex.get(rng.nextInt(3), rng.nextInt(2)), pos.x, pos.y, false)
|
||||||
override fun update(delta: Float) {
|
|
||||||
super.update(delta)
|
|
||||||
|
|
||||||
drawColour.a = ((lifetimeMax - lifetimeCounter) / lifetimeMax).pow(1f / 2.2f).coerceIn(0f, 1f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set flying velocity
|
// set flying velocity
|
||||||
val direction = angles[note]
|
val direction = angles[note]
|
||||||
|
|||||||
28
src/shaders/bayeralpha.frag
Normal file
28
src/shaders/bayeralpha.frag
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in vec4 v_color;
|
||||||
|
in vec2 v_texCoords;
|
||||||
|
|
||||||
|
uniform sampler2D u_texture; // world texture, has alpha value that is meaningful
|
||||||
|
uniform float acount = 2.0;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
const int bayer[4 * 4] = int[](0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5);
|
||||||
|
const float bayerSize = 4.0;
|
||||||
|
const float bayerDivider = bayerSize * bayerSize;
|
||||||
|
|
||||||
|
float nearestAlpha(float alpha) {
|
||||||
|
return min(1.0, floor(alpha + 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 inColor = texture(u_texture, v_texCoords) * v_color;
|
||||||
|
vec2 entry = mod(gl_FragCoord.xy, vec2(bayerSize, bayerSize));
|
||||||
|
|
||||||
|
float alpha = nearestAlpha((inColor.a * 16.0 / 15.0) + (bayer[int(entry.y) * int(bayerSize) + int(entry.x)] / bayerDivider - 0.5));
|
||||||
|
|
||||||
|
fragColor = vec4(inColor.rgb, alpha);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user