Skip to content

Commit

Permalink
refactored render pass config
Browse files Browse the repository at this point in the history
  • Loading branch information
fabmax committed Feb 5, 2025
1 parent 63dedcd commit d52410d
Show file tree
Hide file tree
Showing 73 changed files with 574 additions and 634 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ package de.fabmax.kool.modules.atmosphere
import de.fabmax.kool.math.Vec2i
import de.fabmax.kool.modules.ksl.KslShader
import de.fabmax.kool.modules.ksl.lang.*
import de.fabmax.kool.pipeline.Attribute
import de.fabmax.kool.pipeline.FullscreenShaderUtil
import de.fabmax.kool.pipeline.*
import de.fabmax.kool.pipeline.FullscreenShaderUtil.fullscreenQuadVertexStage
import de.fabmax.kool.pipeline.FullscreenShaderUtil.generateFullscreenQuad
import de.fabmax.kool.pipeline.OffscreenPass2d
import de.fabmax.kool.pipeline.TexFormat
import de.fabmax.kool.scene.Node
import de.fabmax.kool.scene.addMesh
import de.fabmax.kool.util.logI

class OpticalDepthLutPass :
OffscreenPass2d(
Node(),
attachmentConfig = colorAttachmentNoDepth(TexFormat.RG_F16),
drawNode = Node(),
attachmentConfig = AttachmentConfig.singleColorNoDepth(TexFormat.RG_F16),
initialSize = Vec2i(LUT_SIZE),
name = "optical-depth-lut"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ data class GltfTexture(
val generateMipMaps = samplerSettings.minFilter != FilterMethod.NEAREST

createdTex = Texture2d(
TextureProps(generateMipMaps = generateMipMaps, defaultSamplerSettings = samplerSettings),
TextureProps(isMipMapped = generateMipMaps, defaultSamplerSettings = samplerSettings),
name
) {
if (uri != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class ShadowData(val shadowCfg: LightingConfig, program: KslProgram) : KslDataBl
override fun onShaderCreated(shader: ShaderBase<*>) {
uShadowMapViewProjMats = shader.uniformMat4fv(UNIFORM_NAME_SHADOW_VP_MATS)
subMaps.forEachIndexed { i, shadowMap ->
shader.texture2d(samplerName(i), shadowMap.depthTexture)
shader.texture2d(samplerName(i), shadowMap.shadowMap)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import de.fabmax.kool.util.UniqueId

open class DepthMapPass(
drawNode: Node,
attachmentConfig: AttachmentConfig = defaultRenderPassAttachmentConfig,
attachmentConfig: AttachmentConfig = AttachmentConfig { setDefaultDepth() },
initialSize: Vec2i = Vec2i(128, 128),
name: String = UniqueId.nextId("depth-map-pass")
) :
Expand Down Expand Up @@ -86,22 +86,17 @@ open class DepthMapPass(
val instanceLayout: List<Attribute>,
val shaderCfg: DepthShader.Config
)

companion object {
val defaultRenderPassAttachmentConfig = AttachmentConfig(
ColorAttachmentNone,
DepthAttachmentTexture()
)
}
}

class NormalLinearDepthMapPass(
drawNode: Node,
attachmentConfig: AttachmentConfig = defaultRenderPassAttachmentConfig,
attachmentConfig: AttachmentConfig = AttachmentConfig.singleColorDefaultDepth(TexFormat.RGBA_F16),
initialSize: Vec2i = Vec2i(128, 128),
name: String = UniqueId.nextId("normal-linear-depth-map-pass")
) : DepthMapPass(drawNode, attachmentConfig, initialSize, name) {

val normalDepthMap: Texture2d get() = colors[0].texture

init {
mirrorIfInvertedClipY()
}
Expand Down Expand Up @@ -131,10 +126,4 @@ class NormalLinearDepthMapPass(
)
return depthShaders.getOrPut(key) { DepthShader(cfg) }
}

companion object {
val defaultRenderPassAttachmentConfig = AttachmentConfig(
ColorAttachmentTextures(listOf(TextureAttachmentConfig(textureFormat = TexFormat.RGBA_F16)))
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,21 @@ class FrameCopy(
val tex = Texture2d(
TextureProps(
format = TexFormat.RGBA,
generateMipMaps = false,
isMipMapped = false,
defaultSamplerSettings = SamplerSettings().nearest().clamped()
),
"${renderPass.parentScene}:color-copy"
)
add(tex)
}
is OffscreenPass2d -> {
if (renderPass.colorAttachments is OffscreenPass.ColorAttachmentTextures) {
renderPass.colorTextures.forEach {
add(Texture2d(it.props, "${it.name}:copy"))
}
} else {
error("Render pass ${renderPass.name} needs a ColorAttachmentTextures to copy from")
renderPass.colors.forEach {
add(Texture2d(it.texture.props, "${it.texture.name}:copy"))
}
}
is OffscreenPassCube -> {
if (renderPass.colorAttachments is OffscreenPass.ColorAttachmentTextures) {
renderPass.colorTextures.forEach {
add(TextureCube(it.props, "${it.name}:copy"))
}
} else {
error("Render pass ${renderPass.name} needs a ColorAttachmentTextures to copy from")
renderPass.colors.forEach {
add(TextureCube(it.texture.props, "${it.texture.name}:copy"))
}
}
else -> error("Invalid render pass type: $renderPass")
Expand All @@ -65,27 +57,17 @@ class FrameCopy(
Texture2d(
TextureProps(
format = TexFormat.R_F32,
generateMipMaps = false,
isMipMapped = false,
defaultSamplerSettings = SamplerSettings().nearest().clamped()
),
"${renderPass.parentScene}:depth-copy"
)
}
is OffscreenPass2d -> {
if (renderPass.depthAttachment is OffscreenPass.DepthAttachmentTexture) {
val depthTex = renderPass.depthTexture!!
Texture2d(depthTex.props, "${depthTex.name}:copy")
} else {
error("Render pass ${renderPass.name} needs a DepthAttachmentTexture to copy from")
}
renderPass.depth?.let { Texture2d(it.texture.props, "${it.texture.name}:copy") }
}
is OffscreenPassCube -> {
if (renderPass.depthAttachment is OffscreenPass.DepthAttachmentTexture) {
val depthTex = renderPass.depthTexture!!
TextureCube(depthTex.props, "${depthTex.name}:copy")
} else {
error("Render pass ${renderPass.name} needs a DepthAttachmentTexture to copy from")
}
renderPass.depth?.let { TextureCube(it.texture.props, "${it.texture.name}:copy") }
}
else -> error("Invalid render pass type: $renderPass")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,19 @@ import de.fabmax.kool.util.Color
import de.fabmax.kool.util.logT

abstract class OffscreenPass(
attachmentConfig: AttachmentConfig,
numSamples: Int,
mipMode: MipMode,
initialSize: Vec3i,
name: String
) : RenderPass(name, attachmentConfig.mipLevels) {
) : RenderPass(numSamples, mipMode, name) {

private val _size = MutableVec3i(initialSize)
override val size: Vec3i get() = _size

val colorAttachments: ColorAttachment = attachmentConfig.colorAttachments
val depthAttachment: DepthAttachment = attachmentConfig.depthAttachment

override val numSamples: Int = 1
val numColorAttachments: Int
get() = if (colorAttachments is ColorAttachmentTextures) colorAttachments.attachments.size else 1

override val clearColors = MutableList<ClearColor>(numColorAttachments) { ClearColorFill(Color.BLACK) }
override var clearDepth: ClearDepth = ClearDepthFill

fun createColorTextureProps(attachment: Int = 0): TextureProps {
check(colorAttachments is ColorAttachmentTextures)
return colorAttachments.attachments[attachment]
.createTextureProps(mipMode.hasMipLevels)
}

fun createDepthTextureProps(): TextureProps {
check(depthAttachment is DepthAttachmentTexture)
return depthAttachment.attachment
.createTextureProps(mipMode.hasMipLevels)
}

protected fun View.setFullscreenViewport() {
viewport.set(0, 0, width, height)
}

protected fun setSize(width: Int, height: Int, depth: Int) {
if (width != this.width || height != this.height || depth != this.depth) {
logT { "OffscreenPass $name resized to $width x $height x $depth" }
applySize(width, height, depth)
protected fun setSize(width: Int, height: Int, layers: Int) {
if (width != this.width || height != this.height || layers != this.layers) {
logT { "Resizing OffscreenPass $name to $width x $height x $layers" }
applySize(width, height, layers)

// fixme: resetting all viewports is probably not always right
for (v in views) {
Expand All @@ -52,92 +27,106 @@ abstract class OffscreenPass(
}
}

protected open fun applySize(width: Int, height: Int, depth: Int) {
_size.set(width, height, depth)
protected open fun applySize(width: Int, height: Int, layers: Int) {
_size.set(width, height, layers)
}

override fun release() {
super.release()

views.forEach {
if (it.isReleaseDrawNode && !it.drawNode.isReleased) {
it.drawNode.release()
}
}
}
}

fun AttachmentConfig(block: AttachmentConfig.Builder.() -> Unit): AttachmentConfig {
return AttachmentConfig.Builder().apply(block).build()
}

data class AttachmentConfig(
val colors: List<TextureAttachmentConfig>,
val depth: TextureAttachmentConfig?
) {
companion object {
fun ColorAttachmentTextures(vararg textureFormats: TexFormat) =
ColorAttachmentTextures(textureFormats.map { TextureAttachmentConfig(it) })

fun colorAttachmentDefaultDepth(vararg textureFormats: TexFormat): AttachmentConfig =
AttachmentConfig(ColorAttachmentTextures(*textureFormats))

fun colorAttachmentTextureDepth(vararg textureFormats: TexFormat): AttachmentConfig =
AttachmentConfig(
ColorAttachmentTextures(*textureFormats),
DepthAttachmentTexture()
)

fun colorAttachmentNoDepth(vararg textureFormats: TexFormat): AttachmentConfig =
AttachmentConfig(
ColorAttachmentTextures(*textureFormats),
DepthAttachmentNone
)
fun singleColorNoDepth(texFormat: TexFormat, clearColor: ClearColor = ClearColorFill(Color.BLACK)): AttachmentConfig {
return AttachmentConfig {
addColor(texFormat)
noDepth()
}
}

fun singleColorDefaultDepth(texFormat: TexFormat, clearColor: ClearColor = ClearColorFill(Color.BLACK)): AttachmentConfig {
return AttachmentConfig {
addColor(texFormat)
setDefaultDepth()
}
}
}

data class AttachmentConfig(
val colorAttachments: ColorAttachment,
val depthAttachment: DepthAttachment = DepthAttachmentRender,
val mipLevels: MipMode = MipMode.None
)
class Builder {
val colors = mutableListOf<TextureAttachmentConfig>()
var depth: TextureAttachmentConfig? = null

sealed interface ColorAttachment
init {
setDefaultDepth()
}

/**
* Render pass texture color attachment. The color texture(s) can be used by other passes after the render pass is
* rendered.
*/
data class ColorAttachmentTextures(val attachments: List<TextureAttachmentConfig>) : ColorAttachment
fun addColor(block: TextureAttachmentConfig.Builder.() -> Unit) {
colors += TextureAttachmentConfig.Builder().apply(block).build()
}

/**
* Discard the color output.
*/
data object ColorAttachmentNone : ColorAttachment
fun addColor(texFormat: TexFormat, clearColor: ClearColor = ClearColorFill(Color.BLACK)) {
addColor {
this.textureFormat = texFormat
this.clearColor = clearColor
}
}

sealed interface DepthAttachment
fun setDepth(block: TextureAttachmentConfig.Builder.() -> Unit) {
depth = TextureAttachmentConfig.Builder().apply(block).build()
}

/**
* Render pass texture depth attachment. The depth texture can be used by other passes after the render pass is
* rendered.
*/
class DepthAttachmentTexture(
val attachment: TextureAttachmentConfig = TextureAttachmentConfig(
textureFormat = TexFormat.R_F32,
fun setDefaultDepth() = setDepth {
textureFormat = TexFormat.R_F32
defaultSamplerSettings = SamplerSettings().clamped().nearest()
)
) : DepthAttachment

/**
* Default depth attachment, cannot be used by other render passes but provides the usual depth testing
* functionality inside the render pass.
*/
data object DepthAttachmentRender : DepthAttachment

/**
* Don't use any depth attachment. This means there is no depth testing available inside this render pass, which
* is fine for things like single full-screen quads used by many filter shaders, etc.
*/
data object DepthAttachmentNone : DepthAttachment

data class TextureAttachmentConfig(
val textureFormat: TexFormat = TexFormat.RGBA,
val defaultSamplerSettings: SamplerSettings = SamplerSettings().clamped(),
) {
fun createTextureProps(generateMipMaps: Boolean) = TextureProps(
format = textureFormat,
generateMipMaps = generateMipMaps,
defaultSamplerSettings = defaultSamplerSettings
)
}

fun noDepth() {
depth = null
}

fun build(): AttachmentConfig {
return AttachmentConfig(colors.toList(), depth)
}
}
}

fun TextureAttachmentConfig(block: TextureAttachmentConfig.Builder.() -> Unit): TextureAttachmentConfig {
return TextureAttachmentConfig.Builder().apply(block).build()
}

data class TextureAttachmentConfig(
val textureFormat: TexFormat,
val defaultSamplerSettings: SamplerSettings,
val clearColor: ClearColor,
val clearDepth: ClearDepth
) {
fun createTextureProps(isMipMapped: Boolean) = TextureProps(
format = textureFormat,
isMipMapped = isMipMapped,
defaultSamplerSettings = defaultSamplerSettings
)

class Builder {
var textureFormat: TexFormat = TexFormat.RGBA
var defaultSamplerSettings = SamplerSettings().clamped()
var clearColor: ClearColor = ClearColorFill(Color.BLACK)
var clearDepth: ClearDepth = ClearDepthFill

fun build(): TextureAttachmentConfig {
return TextureAttachmentConfig(textureFormat, defaultSamplerSettings, clearColor, clearDepth)
}
}
}
Loading

0 comments on commit d52410d

Please sign in to comment.