package org.openrndr.extra.dnk3 val shaderNoRepetition = """ // -- shaderNoRepetition float sum( vec3 v ) { return v.x+v.y+v.z; } // based on https://www.shadertoy.com/view/Xtl3zf vec4 textureNoTile(in sampler2D noiseTex, in sampler2D tex, in vec2 noiseOffset, in vec2 x) { float v = 1.0; float k = texture(noiseTex, noiseOffset + x*0.01 ).x; // cheap (cache friendly) lookup vec2 duvdx = dFdx( x ); vec2 duvdy = dFdx( x ); float l = k*8.0; float f = fract(l); #if 0 float ia = floor(l); // my method float ib = ia + 1.0; #else float ia = floor(l+0.5); // suslik's method (see comments) float ib = floor(l); f = min(f, 1.0-f)*2.0; #endif vec2 offa = sin(vec2(3.0,7.0)*ia); // can replace with any other hash vec2 offb = sin(vec2(3.0,7.0)*ib); // can replace with any other hash vec3 cola = textureGrad( tex, x + v*offa, duvdx, duvdy ).xyz; vec3 colb = textureGrad( tex, x + v*offb, duvdx, duvdy ).xyz; return vec4(mix( cola, colb, smoothstep(0.2,0.8,f-0.1*sum(cola-colb)) ), 1.0); } """ val shaderNoRepetitionVert = """ // -- shaderNoRepetitionVert float sum( vec3 v ) { return v.x+v.y+v.z; } // based on https://www.shadertoy.com/view/Xtl3zf vec4 textureNoTile(in sampler2D tex, in vec2 noiseOffset, in vec2 x) { float v = 1.0; float k = texture(tex, noiseOffset + 0.005*x ).x; // cheap (cache friendly) lookup float l = k*8.0; float f = fract(l); #if 0 float ia = floor(l); // my method float ib = ia + 1.0; #else float ia = floor(l+0.5); // suslik's method (see comments) float ib = floor(l); f = min(f, 1.0-f)*2.0; #endif vec2 offa = sin(vec2(3.0,7.0)*ia); // can replace with any other hash vec2 offb = sin(vec2(3.0,7.0)*ib); // can replace with any other hash vec3 cola = texture( tex, x + v*offa).xyz; vec3 colb = texture( tex, x + v*offb).xyz; return vec4(mix( cola, colb, smoothstep(0.2,0.8,f-0.1*sum(cola-colb)) ), 1.0); } """ val shaderProjectOnPlane = """ // -- shaderProjectOnPlane vec3 projectOnPlane(vec3 p, vec3 pc, vec3 pn) { float distance = dot(pn, p-pc); return p - distance * pn; } """.trimIndent() val shaderSideOfPlane = """ // -- shaderSideOfPlane int sideOfPlane(in vec3 p, in vec3 pc, in vec3 pn){ if (dot(p-pc,pn) >= 0.0) return 1; else return 0; } """.trimIndent() val shaderLinePlaneIntersect = """ // -- shaderLinePlaneIntersect vec3 linePlaneIntersect(in vec3 lp, in vec3 lv, in vec3 pc, in vec3 pn){ return lp+lv*(dot(pn,pc-lp)/dot(pn,lv)); } """.trimIndent() val shaderVSM = """ |// -- shaderVSM |float linstep(float min, float max, float v) |{ | return clamp((v - min) / (max - min), 0.0, 1.0); |} |// https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch08.html |float chebyshevUpperBound(vec2 moments, float t, float minVariance) { | // One-tailed inequality valid if t > Moments.x | float p = (t <= moments.x) ? 1.0 : 0.0; | // Compute variance. | float variance = moments.y - (moments.x * moments.x); | variance = max(variance, minVariance); | // Compute probabilistic upper bound. | float d = t - moments.x; | float p_max = variance / (variance + d*d); | p_max = smoothstep(0.6, 1.0, p_max); | return max(p, p_max); } """.trimIndent() /* N - world space normal V - eye - world vertex position L - world light pos - world vertex position */ val shaderGGX = """ // -- shaderGGX #define bias 0.125 #define HASHSCALE 443.8975 vec2 hash22(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * HASHSCALE); p3 += dot(p3, p3.yzx+19.19); return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y)); } #define PI 3.1415926535 float pow5(float x) { float x2 = x * x; return x2 * x2 * x; } float D_GGX(float linearRoughness, float NoH, const vec3 h) { // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces" float oneMinusNoHSquared = 1.0 - NoH * NoH; float a = NoH * linearRoughness; float k = linearRoughness / (oneMinusNoHSquared + a * a); float d = k * k * (1.0 / PI); return d; } float D_GGXm(float linearRoughness, float NoH, const vec3 h, const vec3 n) { vec3 NxH = cross(n, h); float oneMinusNoHSquared = dot(NxH, NxH); // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces" //float oneMinusNoHSquared = 1.0 - NoH * NoH; float a = NoH * linearRoughness; float k = linearRoughness / (oneMinusNoHSquared + a * a); float d = k * k * (1.0 / PI); return d; } float V_SmithGGXCorrelated(float linearRoughness, float NoV, float NoL) { // Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs" float a2 = linearRoughness * linearRoughness; float GGXV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2); float GGXL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2); return 0.5 / (GGXV + GGXL); } vec3 F_Schlick(const vec3 f0, float VoH) { // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering" return f0 + (vec3(1.0) - f0) * pow5(1.0 - VoH); } vec3 F_SchlickRoughness(vec3 F0, float roughness, float VoH) { return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - VoH, 5.0); } float F_Schlick(float f0, float f90, float VoH) { return f0 + (f90 - f0) * pow5(1.0 - VoH); } float Fd_Burley(float linearRoughness, float NoV, float NoL, float LoH) { // Burley 2012, "Physically-Based Shading at Disney" float f90 = 0.5 + 2.0 * linearRoughness * LoH * LoH; float lightScatter = F_Schlick(1.0, f90, NoL); float viewScatter = F_Schlick(1.0, f90, NoV); return lightScatter * viewScatter * (1.0 / PI); } vec2 PrefilteredDFG_Karis(float roughness, float NoV) { //https://www.shadertoy.com/view/XlKSDR // Karis 2014, "Physically Based Material on Mobile" const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); const vec4 c1 = vec4( 1.0, 0.0425, 1.040, -0.040); vec4 r = roughness * c0 + c1; float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; return vec2(-1.04, 1.04) * a004 + r.zw; } float saturate(float x) { return clamp(x, 0.0, 1.0); } float G1V(float dotNV, float k) { return 1.0f/(dotNV*(1.0f-k)+k); } float ggx(vec3 N, vec3 V, vec3 L, float roughness, float F0) { float alpha = roughness*roughness; vec3 H = normalize(V+L); float dotNL = saturate(dot(N,L)); float dotNV = saturate(dot(N,V)); float dotNH = saturate(dot(N,H)); float dotLH = saturate(dot(L,H)); float F, D, vis; // D float alphaSqr = alpha*alpha; float pi = 3.14159f; float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f; D = alphaSqr/(pi * denom * denom); // F float dotLH5 = pow(1.0f-dotLH,5.0); F = F0 + (1.0-F0)*(dotLH5); // V float k = alpha/2.0f; vis = G1V(dotNL,k)*G1V(dotNV,k); float specular = dotNL * D * F * vis; return specular; } """.trimIndent()