Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More work on patch editor #279

Merged
merged 6 commits into from
Aug 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ kotlin {
implementation(npm("resize-observer-polyfill", "^1.5.1"))
implementation(npm("react-ace", "^9.0.0"))
implementation(npm("ace-builds", "^1.4.11"))
implementation(npm("markdown-it", "~11.0.0"))
implementation(npm("normalize.css", "^7.0.0"))
implementation(npm("@blueprintjs/core", "^3.24.0"))
implementation(npm("@blueprintjs/icons", "^3.14.0"))
Expand Down
20 changes: 13 additions & 7 deletions src/commonMain/kotlin/baaahs/glshaders/AutoWirer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@ class AutoWirer(
) {
fun autoWire(
vararg shaders: Shader,
focus: Shader? = null
focus: Shader? = null,
overrides: Map<ContentType, MutableLink.Port> = emptyMap()
): UnresolvedPatch {
val openShaders = shaders.associate { it to glslAnalyzer.openShader(it) }
return autoWire(openShaders.values, focus?.let { openShaders[it] })
return autoWire(openShaders.values, focus?.let { openShaders[it] }, overrides = overrides)
}

fun autoWire(
vararg shaders: OpenShader,
focus: OpenShader? = null
focus: OpenShader? = null,
overrides: Map<ContentType, MutableLink.Port> = emptyMap()
): UnresolvedPatch {
return autoWire(shaders.toList(), focus)
return autoWire(shaders.toList(), focus, overrides = overrides)
}

fun autoWire(
shaders: Collection<OpenShader>,
focus: OpenShader? = null,
shaderChannel: ShaderChannel = ShaderChannel.Main
shaderChannel: ShaderChannel = ShaderChannel.Main,
overrides: Map<ContentType, MutableLink.Port> = emptyMap()
): UnresolvedPatch {
val locallyAvailable: MutableMap<ContentType, MutableSet<MutableLink.Port>> = mutableMapOf()

Expand All @@ -54,6 +57,10 @@ class AutoWirer(
openShader to unresolvedShaderInstance
}

overrides.forEach { (contentType, port) ->
locallyAvailable[contentType] = hashSetOf(port)
}

// Second pass: link datasources/output ports to input ports.
val shaderInstancesOfInterest = if (focus == null) {
shaderInstances
Expand Down Expand Up @@ -270,8 +277,7 @@ class AutoWirer(
?: error(unknown("shader instance editor", fromShader, shaderInstances.keys))
shaderInstance.incomingLinks[toPortId] =
MutableShaderOutPort(
fromShaderInstance,
fromPort.portId
fromShaderInstance
)
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/commonMain/kotlin/baaahs/glshaders/FilterShader.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package baaahs.glshaders

import baaahs.glsl.LinkException
import baaahs.show.Shader
import baaahs.show.ShaderOutPortRef
import baaahs.show.ShaderType
Expand Down Expand Up @@ -38,6 +39,7 @@ class FilterShader(shader: Shader, glslCode: GlslCode) : OpenShader.Base(shader,
resultVar: String,
portMap: Map<String, String>
): String {
return resultVar + " = " + namespace.qualify(entryPoint.name) + "(${portMap["gl_FragColor"]})"
val inVar = portMap["gl_FragColor"] ?: throw LinkException("No input for shader \"$title\"")
return resultVar + " = " + namespace.qualify(entryPoint.name) + "($inVar)"
}
}
4 changes: 2 additions & 2 deletions src/commonMain/kotlin/baaahs/glshaders/GlslAnalyzer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class GlslAnalyzer {
fun import(src: String, defaultTitle: String? = null): Shader {
val glslCode = analyze(src)
val type = ShaderType.values().firstOrNull { it.matches(glslCode) }
?: ShaderType.Color // Reasonable guess?
?: ShaderType.Paint // Reasonable guess?

val title = Regex("^// (.*)").find(src)?.groupValues?.get(1)

Expand Down Expand Up @@ -41,7 +41,7 @@ class GlslAnalyzer {
return when (shader.type) {
ShaderType.Projection -> OpenShader.tryUvTranslatorShader(shader, glslObj)
ShaderType.Distortion -> TODO()
ShaderType.Color -> OpenShader.tryColorShader(shader, glslObj)
ShaderType.Paint -> OpenShader.tryPaintShader(shader, glslObj)
ShaderType.Filter -> OpenShader.tryFilterShader(shader, glslObj)
} ?: throw AnalysisException("Can't open purported ${shader.type} shader \"${shader.title}\"")
}
Expand Down
4 changes: 1 addition & 3 deletions src/commonMain/kotlin/baaahs/glshaders/GlslProgram.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ class GlslProgram(
)

internal val fragShader =
gl.createFragmentShader(
"#version ${gl.glslVersion}\n\n${linkedPatch.toGlsl()}\n"
)
gl.createFragmentShader(linkedPatch.toFullGlsl(gl.glslVersion))

private val bindings: List<Binding>

Expand Down
17 changes: 14 additions & 3 deletions src/commonMain/kotlin/baaahs/glshaders/LinkedPatch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import baaahs.glsl.GlslContext
import baaahs.show.ShaderChannel
import baaahs.show.Surfaces
import baaahs.show.live.LiveShaderInstance
import baaahs.show.live.LiveShaderInstance.DataSourceLink
import baaahs.show.live.LiveShaderInstance.ShaderOutLink
import baaahs.show.live.LiveShaderInstance.*
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set
Expand Down Expand Up @@ -98,7 +97,15 @@ class LinkedPatch(
fromLink.dataSource.getVarName(fromLink.varName)
}
}
else -> logger.warn { "Unexpected incoming link $fromLink for $toPortId" }
is ShaderChannelLink -> {
logger.warn { "Unexpected unresolved $fromLink for $toPortId" }
}
is ConstLink -> {
tmpPortMap[toPortId] = lazy {
"(" + fromLink.glsl + ")"
}
}
is NoOpLink -> {}
}
}

Expand Down Expand Up @@ -195,6 +202,10 @@ class LinkedPatch(
return buf.toString()
}

fun toFullGlsl(glslVersion: String): String {
return "#version ${glslVersion}\n\n${toGlsl()}\n"
}

fun compile(glslContext: GlslContext, resolver: Resolver): GlslProgram =
GlslProgram(glslContext, this, resolver)

Expand Down
10 changes: 4 additions & 6 deletions src/commonMain/kotlin/baaahs/glshaders/OpenShader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ interface OpenShader : RefCounted {
val src: String get() = glslCode.src
val glslCode: GlslCode
val title: String
val description: String?
val shaderType: ShaderType
val entryPoint: GlslFunction
val inputPorts: List<InputPort>
Expand All @@ -33,8 +32,7 @@ interface OpenShader : RefCounted {
final override val shader: Shader,
final override val glslCode: GlslCode
) : OpenShader, RefCounted by RefCounter() {
override val title: String = shader.title
override val description: String? = null
override val title: String get() = shader.title

protected fun toInputPort(it: GlslCode.GlslVar): InputPort {
return InputPort(
Expand Down Expand Up @@ -83,13 +81,13 @@ interface OpenShader : RefCounted {
}

companion object {
fun tryColorShader(shader: Shader, glslCode: GlslCode): ColorShader? {
fun tryPaintShader(shader: Shader, glslCode: GlslCode): PaintShader? {
return when {
glslCode.functionNames.contains("main") ->
GenericColorShader(shader, glslCode)
GenericPaintShader(shader, glslCode)

glslCode.functionNames.contains("mainImage") ->
ShaderToyColorShader(shader, glslCode)
ShaderToyPaintShader(shader, glslCode)

else -> null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import baaahs.show.Shader
import baaahs.show.ShaderOutPortRef
import baaahs.show.ShaderType

abstract class ColorShader(shader: Shader, glslCode: GlslCode) : OpenShader.Base(shader, glslCode) {
override val shaderType: ShaderType = ShaderType.Color
abstract class PaintShader(shader: Shader, glslCode: GlslCode) : OpenShader.Base(shader, glslCode) {
override val shaderType: ShaderType = ShaderType.Paint
}

class ShaderToyColorShader(shader: Shader, glslCode: GlslCode) : ColorShader(shader, glslCode) {
class ShaderToyPaintShader(shader: Shader, glslCode: GlslCode) : PaintShader(shader, glslCode) {
companion object {
val magicUniforms = listOf(
// uniform vec3 iResolution; // viewport resolution (in pixels)
Expand Down Expand Up @@ -89,7 +89,7 @@ class ShaderToyColorShader(shader: Shader, glslCode: GlslCode) : ColorShader(sha
}
}

class GenericColorShader(shader: Shader, glslCode: GlslCode) : ColorShader(shader, glslCode) {
class GenericPaintShader(shader: Shader, glslCode: GlslCode) : PaintShader(shader, glslCode) {
companion object {
val wellKnownInputPorts = listOf(
InputPort("gl_FragCoord", "vec4", "Coordinates", ContentType.UvCoordinate),
Expand Down
9 changes: 0 additions & 9 deletions src/commonMain/kotlin/baaahs/glsl/CompiledShader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ class CompiledShader(
}

private fun compile() {
// logger.warn { "CompiledShader src: ${source}" }

gl.runInContext {
gl.check { shaderSource(shaderId, source) }
gl.check { compileShader(shaderId) }
Expand All @@ -31,13 +29,6 @@ class CompiledShader(
gl.runInContext {
if (gl.check { getShaderParameter(shaderId, GL_COMPILE_STATUS) } != GL_TRUE) {
val infoLog = gl.check { getShaderInfoLog(shaderId) }
logger.warn {
"Failed to compile shader: $infoLog\n" +
"Version: \${gl.getParameter(GL_VERSION)}\n" +
"GLSL Version: \${gl.getParameter(GL_SHADING_LANGUAGE_VERSION)}\n" +
"\n" +
source
}
throw CompilationException(infoLog ?: "huh?")
}
}
Expand Down
63 changes: 63 additions & 0 deletions src/commonMain/kotlin/baaahs/glsl/Shaders.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,71 @@
package baaahs.glsl

import baaahs.glshaders.GlslAnalyzer
import baaahs.show.Shader
import baaahs.show.ShaderType

object Shaders {
val smpteColorBars = Shader("SMTPE Color Bars", ShaderType.Paint, """
// Robby Kraft
// from https://www.shadertoy.com/view/XlGXRz

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float br = 0.75; // a less popular SMPTE version uses 1.0

vec2 st = fragCoord.xy/iResolution.xy;

bool sev1 = bool( step(st.x, 1.0/7.0) );
bool sev2 = bool( step(st.x, 2.0/7.0) );
bool sev3 = bool( step(st.x, 3.0/7.0) );
bool sev4 = bool( step(st.x, 4.0/7.0) );
bool sev5 = bool( step(st.x, 5.0/7.0) );
bool sev6 = bool( step(st.x, 6.0/7.0) );

bool row1 = !bool( step(st.y, 0.3333) );
bool row2 = !bool( step(st.y, 0.25) );

/////////////////////////////////////////
// R : 0.75 1.0 1.0 1.0
// G : 0.75 1.0 1.0 1.0
// B : 0.75 1.0 1.0 1.0
/////////////////////////////////////////
float top_red = br * float((sev6 && !sev4) || sev2 );
float top_green = br * float(sev4);
float top_blue = br * float(!sev6 || (sev5 && !sev4) || (sev3 && !sev2) || sev1 );

/////////////////////////////////////////
// R : 1.0 0.75
// G : 1.0 0.75
// B : 1.0 1.0 1.0 0.75
/////////////////////////////////////////
float mid_red = 0.075*float( (sev6 && !sev5)||(sev4 && !sev3)||(sev2 && !sev1) ) + br * float(!sev6 || (sev3 && !sev2) );
float mid_green = 0.075*float( (sev6 && !sev5)||(sev4 && !sev3)||(sev2 && !sev1) ) + br * float(!sev6 || (sev5 && !sev4) );
float mid_blue = 0.075*float( (sev6 && !sev5)||(sev4 && !sev3)||(sev2 && !sev1) ) + br * float(!sev6 || (sev5 && !sev4) || (sev3 && !sev2) || sev1);

///////////////////////
// R: 0.00 1.0 0.22
// G: 0.24 1.0 0.00
// B: 0.35 1.0 0.5
///////////////////////
bool fourth1 = bool( step(st.x, 1.0*(5.0/7.0)/4.0 ));
bool fourth2 = bool( step(st.x, 2.0*(5.0/7.0)/4.0 ));
bool fourth3 = bool( step(st.x, 3.0*(5.0/7.0)/4.0 ));
bool fourth4 = bool( step(st.x, (5.0/7.0) ));

bool littleThird1 = bool( step(st.x, 5.0/7.0 + 1.0/7.0/3.0) );
bool littleThird2 = bool( step(st.x, 5.0/7.0 + 1.0/7.0/3.0*2.0) );
bool littleThird3 = bool( step(st.x, 5.0/7.0 + 1.0/7.0/3.0*3.0) );

float bottom_red = float(fourth2 && !fourth1) + 0.22*float(fourth3 && !fourth2) + 0.075*float(fourth4 && !fourth3) + 0.075*float(littleThird2 && !littleThird1) + 0.15*float(littleThird3 && !littleThird2) + 0.075*float(!sev6);
float bottom_green = 0.24*float(fourth1) + float(fourth2 && !fourth1) + 0.075*float(fourth4 && !fourth3) + 0.075*float(littleThird2 && !littleThird1) + 0.15*float(littleThird3 && !littleThird2) + 0.075*float(!sev6);
float bottom_blue = 0.35*float(fourth1) + float(fourth2 && !fourth1) + 0.5*float(fourth3 && !fourth2) + 0.075*float(fourth4 && !fourth3) + 0.075*float(littleThird2 && !littleThird1) + 0.15*float(littleThird3 && !littleThird2) + 0.075*float(!sev6);

fragColor = vec4(top_red*float(row1) + mid_red*float(row2 && !row1) + bottom_red*float(!row2),
top_green*float(row1) + mid_green*float(row2 && !row1) + bottom_green*float(!row2),
top_blue*float(row1) + mid_blue*float(row2 && !row1) + bottom_blue*float(!row2),1.);
}
""".trimIndent())

val cylindricalUvMapper = GlslAnalyzer().openShader(
/**language=glsl*/
Expand Down
6 changes: 6 additions & 0 deletions src/commonMain/kotlin/baaahs/glsl/errors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ abstract class GlslException(message: String) : Exception(message) {
abstract val errors: List<GlslError>
}

class LinkException(
message: String, row: Int = -1
) : GlslException("Shader link error: $message") {
override val errors = listOf(GlslError(message, row))
}

class AnalysisException(
message: String, row: Int = -1
) : GlslException("Shader analysis error: $message") {
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/baaahs/show/FixtureShaders.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package baaahs.show
object FixtureShaders {
val fireBallGlsl = Shader(
"Fire Ball",
ShaderType.Color,
ShaderType.Paint,
"""
// Fire Ball
// From http://glslsandbox.com/e#61108.0
Expand Down
15 changes: 8 additions & 7 deletions src/commonMain/kotlin/baaahs/show/PortRef.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,11 @@ interface ShaderPortRef {
}

@Serializable @SerialName("shader-out")
data class ShaderOutPortRef(val shaderInstanceId: String, val portId: String = ReturnValue) : PortRef() {
fun isReturnValue() = portId == ReturnValue
data class ShaderOutPortRef(val shaderInstanceId: String) : PortRef() {

override fun dereference(mutableShow: MutableShow): MutableLink.Port =
MutableShaderOutPort(
mutableShow.shaderInstances.getBang(
shaderInstanceId,
"shader instance"
), portId
)
mutableShow.shaderInstances.getBang(shaderInstanceId, "shader instance"))

companion object {
const val ReturnValue = "_"
Expand All @@ -48,3 +43,9 @@ data class OutputPortRef(val portId: String) : PortRef() {
override fun dereference(mutableShow: MutableShow): MutableLink.Port =
MutableOutputPort(portId)
}

@Serializable @SerialName("const")
data class ConstPortRef(val glsl: String) : PortRef() {
override fun dereference(mutableShow: MutableShow): MutableLink.Port =
MutableConstPort(glsl)
}
8 changes: 4 additions & 4 deletions src/commonMain/kotlin/baaahs/show/SampleData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object SampleData {

private val showDefaultPaint = autoWirer.autoWire(Shader(
"Darkness",
ShaderType.Color,
ShaderType.Paint,
/**language=glsl*/
"""
void main(void) {
Expand All @@ -64,7 +64,7 @@ object SampleData {

vec4 filterImage(vec4 inColor) {
vec4 clampedColor = clamp(inColor, 0., 1.);
return clampedColor * brightness;
return vec4(clampedColor.rgb * brightness, clampedColor.a);
}
""".trimIndent()
))
Expand Down Expand Up @@ -112,7 +112,7 @@ object SampleData {

private val redYellowGreenPatch = autoWirer.autoWire(Shader(
"GLSL Hue Test Pattern",
ShaderType.Color,
ShaderType.Paint,
/**language=glsl*/
"""
uniform vec2 resolution;
Expand All @@ -124,7 +124,7 @@ object SampleData {

private val blueAquaGreenPatch = autoWirer.autoWire(Shader(
"Another GLSL Hue Test Pattern",
ShaderType.Color,
ShaderType.Paint,
/**language=glsl*/
"""
uniform vec2 resolution;
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/baaahs/show/ShaderType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ enum class ShaderType(
}
},

Color(0, mapOf(ContentType.UvCoordinate to ShaderChannel.Main), ContentType.Color, """
Paint(0, mapOf(ContentType.UvCoordinate to ShaderChannel.Main), ContentType.Color, """
uniform vec2 resolution;
uniform float time;

Expand Down
Loading