[orx-shader-phrases] Add shader embedding

This commit is contained in:
Edwin Jakobs
2021-06-25 09:55:35 +02:00
parent 4e1a2cf930
commit 4f0de6a39b
22 changed files with 111 additions and 479 deletions

View File

@@ -1,20 +1,11 @@
# orx-shader-phrases
A library that provides a `#pragma import` statement for shaders by using the JVM class loader.
A library that provides a `#pragma import` statement for shaders.
## Usage
Given a shader source:
Work in progress.
````glsl
#version 330
// -- this imports all phrases in Dummy
#pragma import org.openrndr.extra.shaderphrases.phrases.Dummy.*
void main() {
float a = dummy();
}
````
We can use the `preprocessShader()` function to resolve `#pragma import` statements.
@@ -28,20 +19,3 @@ Alternatively loading and preprocessing can be combined in a single function cal
val preprocessedSource = preprocessShaderFromUrl(resourceUrl("/some-shader.frag"))
```
To create importable shader phrases one creates a Kotlin class and adds the `ShaderPhrases` annotation.
For example the `dummy` phrase in our example is made available as follows:
```kotlin
// -- force the class name to be Dummy on the JVM
@file:JvmName("Dummy")
@file:ShaderPhrases
package org.openrndr.extra.shaderphrases.phrases
import org.openrndr.extra.shaderphrases.annotations.ShaderPhrases
// -- the shader phrase
const val dummy = """
float dummy() {
return 0.0;
}
"""
```

View File

@@ -1,6 +1,9 @@
import Orx_embed_shaders_gradle.EmbedShadersTask
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
id("orx.embed-shaders")
}
val kotlinxSerializationVersion: String by rootProject.extra
@@ -40,14 +43,15 @@ kotlin {
useJUnitPlatform()
}
}
js(IR) {
browser()
nodejs()
}
sourceSets {
val shaderKotlin by creating {
this.kotlin.srcDir("$projectDir/build/generated/shaderKotlin")
}
@Suppress("UNUSED_VARIABLE")
val commonMain by getting {
dependencies {
@@ -56,9 +60,10 @@ kotlin {
implementation("org.openrndr:openrndr-draw:$openrndrVersion")
implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
implementation("io.github.microutils:kotlin-logging:$kotlinLoggingVersion")
api(shaderKotlin.kotlin)
}
}
commonMain.dependsOn(shaderKotlin)
@Suppress("UNUSED_VARIABLE")
val commonTest by getting {
dependencies {
@@ -68,7 +73,6 @@ kotlin {
implementation("io.kotest:kotest-assertions-core:$kotestVersion")
}
}
@Suppress("UNUSED_VARIABLE")
val jvmMain by getting
@@ -97,3 +101,12 @@ kotlin {
}
}
}
val embedShaders = tasks.register<EmbedShadersTask>("embedShaders") {
inputDir.set(file("$projectDir/src/shaders/glsl"))
outputDir.set(file("$buildDir/generated/shaderKotlin"))
defaultPackage.set("org.openrndr.shaderphrases.phrases")
}.get()
tasks.getByName("compileKotlinJvm").dependsOn(embedShaders)
tasks.getByName("compileKotlinJs").dependsOn(embedShaders)

View File

@@ -2,9 +2,9 @@ package org.openrndr.extra.shaderphrases
import mu.KotlinLogging
import org.openrndr.draw.Shader
//import org.openrndr.extra.shaderphrases.phrases.phraseTbnMatrix
import org.openrndr.utils.url.textFromURL
private val logger = KotlinLogging.logger {}
/**
@@ -115,7 +115,6 @@ fun Shader.Companion.preprocessedFromUrls(
gsUrl: String? = null,
fsUrl: String
): Shader {
val vsCode = textFromURL(vsUrl).preprocess()
val tcsCode = tcsUrl?.let { textFromURL(it) }?.preprocess()
val tesCode = tesUrl?.let { textFromURL(it) }?.preprocess()

View File

@@ -1,3 +0,0 @@
package org.openrndr.extra.shaderphrases.phrases
val phraseTbnMatrix = """"""

View File

@@ -0,0 +1,3 @@
float hash21(vec2 p) {
return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x))));
}

View File

@@ -0,0 +1,6 @@
#define MOD3 vec3(.1031,.11369,.13787)
vec3 hash33(vec3 p3) {
p3 = fract(p3 * MOD3);
p3 += dot(p3, p3.yxz+19.19);
return -1.0 + 2.0 * fract(vec3((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y, (p3.y+p3.z)*p3.x));
}

View File

@@ -0,0 +1,5 @@
vec3 projectionToViewCoordinate(vec2 uv, float projectionDepth, mat4 projectionInverse) {
vec4 projectionCoordinate = vec4(uv * 2.0 - 1.0, projectionDepth*2.0-1.0, 1.0);
vec4 viewCoordinate = projectionInverse * projectionCoordinate;
return viewCoordinate.xyz / viewCoordinate.w;
}

View File

@@ -0,0 +1,5 @@
float projectionToViewDepth(float projectionDepth, mat4 projectionInverse) {
float z = (projectionDepth*2.0-1.0) * projectionInverse[2].z + projectionInverse[3].z;
float w = (projectionDepth*2.0-1.0) * projectionInverse[2].w + projectionInverse[3].w;
return z / w;
}

View File

@@ -0,0 +1,22 @@
#pragma import phraseHash33;
float simplex31(vec3 p) {
const float K1 = 0.333333333;
const float K2 = 0.166666667;
vec3 i = floor(p + (p.x + p.y + p.z) * K1);
vec3 d0 = p - (i - (i.x + i.y + i.z) * K2);
// thx nikita: https://www.shadertoy.com/view/XsX3zB
vec3 e = step(vec3(0.0), d0 - d0.yzx);
vec3 i1 = e * (1.0 - e.zxy);
vec3 i2 = 1.0 - e.zxy * (1.0 - e);
vec3 d1 = d0 - (i1 - 1.0 * K2);
vec3 d2 = d0 - (i2 - 2.0 * K2);
vec3 d3 = d0 - (1.0 - 3.0 * K2);
vec4 h = max(0.6 - vec4(dot(d0, d0), dot(d1, d1), dot(d2, d2), dot(d3, d3)), 0.0);
vec4 n = h * h * h * h * vec4(dot(d0, hash33(i)), dot(d1, hash33(i + i1)), dot(d2, hash33(i + i2)), dot(d3, hash33(i + 1.0)));
return dot(vec4(31.316), n);
}

View File

@@ -0,0 +1,5 @@
#pragma package org.openrndr.extra.shaderphrases.phrases
mat3 tbnMatrix(vec4 tangent, vec3 normal) {
vec3 bitangent = cross(normal, tangent.xyz) * tangent.w;
return mat3(tangent.xyz, bitangent, normal);
}

View File

@@ -0,0 +1,14 @@
#pragma import phraseHash21
float valueNoise21(vec2 x) {
vec2 i = floor(x);
vec2 f = fract(x);
float a = hash21(i);
float b = hash21(i + vec2(1.0, 0.0));
float c = hash21(i + vec2(0.0, 1.0));
float d = hash21(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

View File

@@ -0,0 +1,5 @@
float viewToProjectionDepth(float viewDepth, mat4 projection) {
float z = viewDepth * projection[2].z + projection[3].z;
float w = viewDepth * projection[2].w + projection[3].w;
return z / w;
}