un-hardcode fog config

This commit is contained in:
2023-08-17 21:17:28 +10:00
parent 2c5547320d
commit d045560ef5
7 changed files with 218 additions and 63 deletions

View File

@ -0,0 +1,71 @@
package gay.pizza.CavesOfJolk
import com.badlogic.gdx.graphics.g3d.Attributes
import com.badlogic.gdx.graphics.g3d.Renderable
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute
import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader
class CustomDefaultShader(renderable: Renderable, config: Config):
DefaultShader(renderable, config, createPrefix(renderable, config))
{
companion object
{
fun createPrefix(renderable: Renderable, config: Config): String
{
var prefix = DefaultShader.createPrefix(renderable, config)
val attribs = Attributes()
renderable.environment.let { attribs.set(it) }
renderable.material.let { attribs.set(it) }
if (attribs.has(ColorAttribute.Fog))
{
prefix += "#define fog${
when (attribs.get<CustomIntAttribute>(CustomIntAttribute.FogMode)?.value
?: CustomIntAttribute.FogModes.Distance.toInt()) {
CustomIntAttribute.FogModes.Distance.toInt() -> "Distance"
CustomIntAttribute.FogModes.Depth.toInt() -> "Depth"
else -> throw IndexOutOfBoundsException()
}
}Flag\n"
prefix += "#define fog${
when (attribs.get<CustomIntAttribute>(CustomIntAttribute.FogType)?.value
?: CustomIntAttribute.FogTypes.Original.toInt()) {
CustomIntAttribute.FogTypes.Original.toInt() -> "Original"
CustomIntAttribute.FogTypes.Linear.toInt() -> "Linear"
CustomIntAttribute.FogTypes.Smooth.toInt() -> "Smooth"
CustomIntAttribute.FogTypes.InvSquare.toInt() -> "InvSquare"
CustomIntAttribute.FogTypes.Exp.toInt() -> "Exp"
CustomIntAttribute.FogTypes.Exp2.toInt() -> "Exp2"
else -> throw IndexOutOfBoundsException()
}
}Flag\n"
}
return prefix
}
object Inputs
{
val fogNear = Uniform("u_fogNear")
val fogFar = Uniform("u_fogFar")
val fogDensity = Uniform("u_fogDensity")
}
}
private val u_fogNear = register(Inputs.fogNear)
private val u_fogFar = register(Inputs.fogFar)
private val u_fogDensity = register(Inputs.fogDensity)
override fun bindLights(renderable: Renderable?, attributes: Attributes?)
{
if (attributes == null)
return
attributes.get<CustomFloatAttribute>(CustomFloatAttribute.FogNear)?.let { set(u_fogNear, it.value) }
attributes.get<CustomFloatAttribute>(CustomFloatAttribute.FogFar)?.let { set(u_fogFar, it.value) }
attributes.get<CustomFloatAttribute>(CustomFloatAttribute.FogDensity)?.let { set(u_fogDensity, it.value) }
super.bindLights(renderable, attributes)
}
}

View File

@ -0,0 +1,34 @@
package gay.pizza.CavesOfJolk
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g3d.Renderable
import com.badlogic.gdx.graphics.g3d.Shader
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute
import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader
import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider
class CustomDefaultShaderProvider(config: DefaultShader.Config): DefaultShaderProvider(config)
{
init
{
if (config.vertexShader == null)
config.vertexShader = Gdx.files.internal("lit.vert.glsl").readString()
if (config.fragmentShader == null)
config.fragmentShader = Gdx.files.internal("lit.frag.glsl").readString()
}
override fun createShader(renderable: Renderable): Shader
{
val renderableMask = renderable.environment.mask or renderable.material.mask
val fogMask =
CustomIntAttribute.FogMode or
CustomIntAttribute.FogType or
CustomFloatAttribute.FogNear or
CustomFloatAttribute.FogFar or
CustomFloatAttribute.FogDensity
if ((renderableMask and ColorAttribute.Fog == ColorAttribute.Fog) && (renderableMask and fogMask != 0L))
return CustomDefaultShader(renderable, config)
return super.createShader(renderable)
}
}

View File

@ -0,0 +1,21 @@
package gay.pizza.CavesOfJolk
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute
class CustomFloatAttribute private constructor(type: Long, value: Float): FloatAttribute(type, value)
{
companion object
{
const val FogNearAlias = "fogNear"
val FogNear = register(FogNearAlias)
fun createFogNear(value: Float) = CustomFloatAttribute(FogNear, value)
const val FogFarAlias = "fogFar"
val FogFar = register(FogFarAlias)
fun createFogFar(value: Float) = CustomFloatAttribute(FogFar, value)
const val FogDensityAlias = "fogDensity"
val FogDensity = register(FogDensityAlias)
fun createFogDensity(value: Float) = CustomFloatAttribute(FogDensity, value)
}
}

View File

@ -0,0 +1,37 @@
package gay.pizza.CavesOfJolk
import com.badlogic.gdx.graphics.g3d.attributes.IntAttribute
class CustomIntAttribute private constructor(type: Long, value: Int): IntAttribute(type, value)
{
enum class FogModes(private val value: Int)
{
Distance(0),
Depth(1);
fun toInt() = value
}
enum class FogTypes(private val value: Int)
{
Original(0),
Linear(1),
Smooth(2),
InvSquare(3),
Exp(4),
Exp2(5);
fun toInt() = value
}
companion object
{
const val FogModeAlias = "fogMode"
val FogMode = register(FogModeAlias)
fun createFogMode(value: FogModes) = CustomIntAttribute(FogMode, value.toInt())
const val FogTypeAlias = "fogType"
val FogType = register(FogTypeAlias)
fun createFogType(value: FogTypes) = CustomIntAttribute(FogType, value.toInt())
}
}

View File

@ -2,7 +2,6 @@ package gay.pizza.CavesOfJolk
import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.audio.Sound
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.BitmapFont
import com.badlogic.gdx.graphics.g2d.SpriteBatch
@ -13,7 +12,6 @@ import com.badlogic.gdx.graphics.g3d.attributes.IntAttribute
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight
import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader
import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder
import com.badlogic.gdx.graphics.g3d.utils.TextureDescriptor
import com.badlogic.gdx.math.*
@ -24,7 +22,6 @@ class Game: ApplicationAdapter()
{
private lateinit var texJolk: Texture
private lateinit var fntComic: BitmapFont
private lateinit var nut: Sound
private lateinit var cube: Model
private lateinit var floor: Model
@ -95,18 +92,28 @@ class Game: ApplicationAdapter()
spriteBatch = SpriteBatch()
env = Environment()
env.set(IntAttribute.createCullFace(GL20.GL_BACK))
env.set(ColorAttribute.createAmbientLight(XnaColor.DarkSlateGray.lighten(-0.6)))
env.set(ColorAttribute.createFog(XnaColor.CornflowerBlue))
env.set(
IntAttribute.createCullFace(GL20.GL_BACK),
ColorAttribute.createAmbientLight(XnaColor.DarkSlateGray.lighten(-0.6)),
ColorAttribute.createFog(XnaColor.CornflowerBlue))
env.set(
CustomIntAttribute.createFogMode(CustomIntAttribute.FogModes.Depth),
CustomIntAttribute.createFogType(CustomIntAttribute.FogTypes.Smooth),
CustomFloatAttribute.createFogNear(0.75f),
CustomFloatAttribute.createFogFar(20.5f))
/*
env.set(
CustomIntAttribute.createFogMode(CustomIntAttribute.FogModes.Distance),
CustomIntAttribute.createFogType(CustomIntAttribute.FogTypes.Exp2),
CustomFloatAttribute.createFogDensity(0.1f))
*/
env.add(DirectionalLight().set(XnaColor.White, Vector3(1.0f, -1.0f, -1.0f).nor()))
val shaderConfig = DefaultShader.Config(
Gdx.files.internal("lit.vert.glsl").readString(),
Gdx.files.internal("lit.frag.glsl").readString())
val shaderConfig = DefaultShader.Config()
shaderConfig.numDirectionalLights = 1
shaderConfig.numPointLights = 0
shaderConfig.numBones = 0
modelBatch = ModelBatch(DefaultShaderProvider(shaderConfig))
modelBatch = ModelBatch(CustomDefaultShaderProvider(shaderConfig))
colin = Colin()
@ -136,9 +143,7 @@ class Game: ApplicationAdapter()
val deltaTime = Gdx.graphics.deltaTime
update(deltaTime)
val fogColour = XnaColor.CornflowerBlue.lighten(Math.sin(0.056 * jolkRot.toDouble()) * 0.15 - 0.15)
ScreenUtils.clear(fogColour, true)
env.set(ColorAttribute.createFog(fogColour))
ScreenUtils.clear(XnaColor.CornflowerBlue, true)
val jolkPos = Vector3(0.0f, 1.0f + MathUtils.sin(jolkRot * 0.25f) * 0.25f, -4.0f)
val world = Matrix4()

View File

@ -1,6 +1,8 @@
package gay.pizza.CavesOfJolk
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g3d.Attribute
import com.badlogic.gdx.graphics.g3d.Attributes
import com.badlogic.gdx.math.MathUtils
import com.badlogic.gdx.math.Vector2
import ktx.math.div
@ -58,3 +60,7 @@ fun Color.mix(rhs: Color, x: Float) = Color(
MathUtils.lerp(this.g, rhs.g, x),
MathUtils.lerp(this.b, rhs.b, x),
MathUtils.lerp(this.a, rhs.a, x))
//FIXME: find some way to get rid of these warnings
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "UNCHECKED_CAST")
fun <T: Attribute> Attributes.get(type: Long) = get(type) as? T

View File

@ -88,7 +88,14 @@ uniform vec4 u_cameraPosition;
#ifdef fogFlag
uniform vec4 u_fogColor;
varying float v_fog;
#if defined(fogLinearFlag) || defined(fogSmoothFlag) || defined(fogInvSquareFlag)
uniform float u_fogNear;
uniform float u_fogFar;
#elif defined(fogExpFlag) || defined(fogExp2Flag)
uniform float u_fogDensity;
#endif
#endif // fogFlag
uniform mat4 u_projViewTrans;
@ -174,68 +181,42 @@ void main()
fragment = diffuse.rgb;
#endif // lightingFlag
#ifdef fogFlag
#define fogDistance
//#define fogDepth
#ifdef fogOriginalFlag
vec3 fogVec = u_cameraPosition.xyz - v_worldPosition.xyz;
float fogDist = dot(fogVec, fogVec);
float fog = min(fogDist * u_cameraPosition.w, 1.0);
#elif defined(fogDistanceFlag)
float fogDist = length(v_worldPosition.xyz - u_cameraPosition.xyz);
#elif defined(fogDepthFlag)
float fogDist = gl_FragCoord.z / gl_FragCoord.w;
#endif // fogOriginalFlag || fogDistanceFlag || fogDepthFlag
//#define fogOriginal
//#define fogLinear
#define fogSmooth
//#define fogInvSquare
//#define fogExp
//#define fogExp2
#if defined(fogLinear) || defined(fogSmooth) || defined(fogInvSquare)
float near = 1.5;
float far = 20.5;
#elif defined(fogExp) || defined(fogExp2)
float density = 0.12;
#endif
#ifdef fogOriginal
vec3 fvec = u_cameraPosition.xyz - v_worldPosition.xyz;
float flen = dot(fvec, fvec);
float fog = min(flen * u_cameraPosition.w, 1.0);
#elif defined(fogDistance)
float flen = length(v_worldPosition.xyz - u_cameraPosition.xyz);
#elif defined(fogDepth)
float flen = gl_FragCoord.z / gl_FragCoord.w;
#endif // fogOriginal || fogDistance || fogDepth
#ifdef fogLinear
#ifdef fogLinearFlag
// fog = saturate(linearstep(near, far, x))
float fog = clamp((flen - near) / (far - near), 0.0, 1.0);
#elif defined(fogSmooth)
float fog = clamp((fogDist - u_fogNear) / (u_fogFar - u_fogNear), 0.0, 1.0);
#elif defined(fogSmoothFlag)
// fog = smoothstep(saturate(linearstep(near, far, x)))
float fog = clamp((flen - near) / (far - near), 0.0, 1.0);
float fog = clamp((fogDist - u_fogNear) / (u_fogFar - u_fogNear), 0.0, 1.0);
fog = fog * fog * (3.0 - 2.0 * fog);
//fog = fog * fog * fog * (fog * (6.0 * fog - 15.0) + 10.0);
#elif defined(fogInvSquare)
#elif defined(fogInvSquareFlag)
// fog = isqstep(saturate(linearstep(near, far, x)))
float fog = clamp((flen - near) / (far - near), 0.0, 1.0);
float fog = clamp((fogDist - u_fogNear) / (u_fogFar - u_fogNear), 0.0, 1.0);
fog = 1.0 - fog;
fog = 1.0 - fog * fog;
#elif defined(fogExp)
float fog = max(1.0 - exp(-density * flen), 0.0);
#elif defined(fogExp2)
float dz = density * flen;
#elif defined(fogExpFlag)
// todo: can precompute some stuff in uniforms
float fog = max(1.0 - exp(-u_fogDensity * fogDist), 0.0);
#elif defined(fogExp2Flag)
// todo: can precompute some stuff in uniforms
float dz = u_fogDensity * fogDist;
float fog = max(1.0 - exp(-dz * dz), 0.0);
#endif // fogLinear || fogSmooth || fogInvSquare || fogExp || fogExp2
#endif // fogLinearFlag || fogSmoothFlag || fogInvSquareFlag || fogExpFlag || fogExp2Flag
#ifdef fogFlag
vec3 fogColor = u_fogColor.rgb;
fogColor = linearEncode(fogColor);
fragment = mix(fragment, fogColor, fog);
#endif // fogFlag
gl_FragColor = vec4(linearDecode(fragment), diffuse.a);
/*
if (gl_FragCoord.x > 1280.0)
{
if (fog <= 0.0)
gl_FragColor = vec4(1.0, 0.0, 1.0, diffuse.a);
else if (fog >= 1.0)
gl_FragColor = vec4(1.0, 0.0, 0.0, diffuse.a);
else
gl_FragColor = vec4(fog, fog, 0.0, diffuse.a);
}
*/
}