UNPKG

@threlte/extras

Version:

Utilities, abstractions and plugins for your Threlte apps

170 lines (143 loc) 4.44 kB
import { revision } from '../../lib/revision'; export const vertexShader = /* glsl */ ` varying vec2 vUv; varying vec2 vPos; void main () { gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0); vUv = uv; vPos = position.xy; } `; export const fragmentShader = /* glsl */ ` // Majority from https://gist.github.com/statico/df64c5d167362ecf7b34fca0b1459a44 varying vec2 vUv; varying vec2 vPos; uniform vec2 scale; uniform vec2 imageBounds; uniform float resolution; uniform vec3 color; uniform sampler2D map; uniform sampler2D colorProccessingTexture; uniform float radius; uniform float zoom; uniform float alphaThreshold; uniform float alphaSmoothing; uniform float brightness; uniform float contrast; uniform float monochromeStrength; uniform vec3 monochromeColor; uniform float negative; uniform vec3 hsl; uniform float grayscale; uniform float opacity; uniform int colorProcessingEnabled; uniform int colorProcessingTextureOverride; #define PI 3.14159265; vec2 aspect(vec2 size) { return size / min(size.x, size.y); } // from https://iquilezles.org/articles/distfunctions float udRoundBox(vec2 p, vec2 b, float r) { return length(max(abs(p) - b + r, 0.0)) - r; } float hueToRgb(float p, float q, float t) { if (t < 0.0f) t += 1.0f; if (t > 1.0f) t -= 1.0f; if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t; if (t < 1.0f / 2.0f) return q; if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f; return p; } vec3 rgbToHsl(vec3 color) { float max = max(max(color.r, color.g), color.b); float min = min(min(color.r, color.g), color.b); float h, s, l = (max + min) / 2.0f; if (max == min) { h = s = 0.0f; } else { float d = max - min; s = l > 0.5f ? d / (2.0f - max - min) : d / (max + min); if (max == color.r) { h = (color.g - color.b) / d + (color.g < color.b ? 6.0f : 0.0f); } else if (max == color.g) { h = (color.b - color.r) / d + 2.0f; } else if (max == color.b) { h = (color.r - color.g) / d + 4.0f; } h /= 6.0f; } return vec3(h, s, l); } vec3 hslToRgb(vec3 hsl) { float h = hsl.x; float s = hsl.y; float l = hsl.z; float r, g, b; if (s == 0.0f) { r = g = b = l; } else { float q = l < 0.5f ? l * (1.0f + s) : l + s - l * s; float p = 2.0f * l - q; r = hueToRgb(p, q, h + 1.0f / 3.0f); g = hueToRgb(p, q, h); b = hueToRgb(p, q, h - 1.0f / 3.0f); } return vec3(r, g, b); } vec3 monochrome(float x, vec3 col) { return col * exp(4.0 * x - 1.0); } void processColors (inout vec4 colors) { vec4 strength = vec4(1.0); if (colorProcessingTextureOverride == 1) { strength = texture2D(colorProccessingTexture, vUv); float smoothedAlpha = smoothstep(1.0 - alphaThreshold - alphaSmoothing, 1.0 - alphaThreshold, strength.a + 0.0001); colors.a *= smoothedAlpha; if (gl_FragColor.a == 0.0) { discard; return; } } // BRIGHTNESS colors.rgb = max(colors.rgb + brightness, 0.0); // CONTRAST colors.rgb = max(((colors.rgb - 0.5) * max(contrast + 1.0, 0.0)) + 0.5, 0.0); // HSL vec3 hslColor = rgbToHsl(colors.rgb); hslColor.x = mod(hslColor.x + hsl.x * strength.r ,1.0); hslColor.y *= (1.0 + hsl.y * strength.g); hslColor.z += hsl.z * strength.b; colors.rgb = max(hslToRgb(hslColor), vec3(0.0)); // MONOCHROME colors.rgb = mix(colors.rgb, monochrome(hslColor.z, monochromeColor), monochromeStrength); } void main() { vec2 s = aspect(scale); vec2 i = aspect(imageBounds); float rs = s.x / s.y; float ri = i.x / i.y; vec2 new = rs < ri ? vec2(i.x * s.y / i.y, s.y) : vec2(s.x, i.y * s.x / i.x); vec2 offset = (rs < ri ? vec2((new.x - s.x) / 2.0, 0.0) : vec2(0.0, (new.y - s.y) / 2.0)) / new; vec2 uv = vUv * s / new + offset; vec2 zUv = (uv - vec2(0.5, 0.5)) / zoom + vec2(0.5, 0.5); vec2 res = vec2(scale * resolution); vec2 halfRes = 0.5 * res; float b = udRoundBox(vUv.xy * res - halfRes, halfRes, resolution * radius); vec3 a = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), smoothstep(0.0, 1.0, b)); gl_FragColor = texture2D(map, zUv) * vec4(color, opacity * a); if (colorProcessingEnabled == 1) { processColors(gl_FragColor); } if (gl_FragColor.a == 0.0) { discard; } #include <tonemapping_fragment> #include <${revision >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}> gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(1.0) - gl_FragColor.rgb, negative); } `;