[orx-shader-phrases] Add shader embedding
This commit is contained in:
@@ -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;
|
||||
}
|
||||
"""
|
||||
```
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
package org.openrndr.extra.shaderphrases.phrases
|
||||
|
||||
val phraseTbnMatrix = """"""
|
||||
3
orx-shader-phrases/src/shaders/glsl/phraseHash21.shader
Normal file
3
orx-shader-phrases/src/shaders/glsl/phraseHash21.shader
Normal 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))));
|
||||
}
|
||||
6
orx-shader-phrases/src/shaders/glsl/phraseHash33.shader
Normal file
6
orx-shader-phrases/src/shaders/glsl/phraseHash33.shader
Normal 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));
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
22
orx-shader-phrases/src/shaders/glsl/phraseSimplex31.shader
Normal file
22
orx-shader-phrases/src/shaders/glsl/phraseSimplex31.shader
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user