From 5b8e8413a3e33b83e8dea731cbae751a053e279a Mon Sep 17 00:00:00 2001 From: JannisX11 Date: Thu, 6 Mar 2025 22:42:41 +0100 Subject: [PATCH] Move shaders to separate files --- build.js | 11 +- js/preview/canvas.js | 473 ++------------------------ js/shaders/brush_outline.frag.glsl | 61 ++++ js/shaders/brush_outline.vert.glsl | 7 + js/shaders/direction_helper.frag.glsl | 33 ++ js/shaders/direction_helper.vert.glsl | 36 ++ js/shaders/layered.frag.glsl | 33 ++ js/shaders/layered.vert.glsl | 41 +++ js/shaders/marker.frag.glsl | 26 ++ js/shaders/marker.vert.glsl | 40 +++ js/shaders/shader.ts | 11 + js/shaders/solid.frag.glsl | 26 ++ js/shaders/solid.vert.glsl | 37 ++ js/shaders/texture.frag.glsl | 41 +++ js/shaders/texture.vert.glsl | 65 ++++ js/shaders/uv_helper.frag.glsl | 28 ++ js/shaders/uv_helper.vert.glsl | 42 +++ js/texturing/textures.js | 115 +------ js/types.d.ts | 6 +- package-lock.json | 14 + package.json | 1 + 21 files changed, 587 insertions(+), 560 deletions(-) create mode 100644 js/shaders/brush_outline.frag.glsl create mode 100644 js/shaders/brush_outline.vert.glsl create mode 100644 js/shaders/direction_helper.frag.glsl create mode 100644 js/shaders/direction_helper.vert.glsl create mode 100644 js/shaders/layered.frag.glsl create mode 100644 js/shaders/layered.vert.glsl create mode 100644 js/shaders/marker.frag.glsl create mode 100644 js/shaders/marker.vert.glsl create mode 100644 js/shaders/shader.ts create mode 100644 js/shaders/solid.frag.glsl create mode 100644 js/shaders/solid.vert.glsl create mode 100644 js/shaders/texture.frag.glsl create mode 100644 js/shaders/texture.vert.glsl create mode 100644 js/shaders/uv_helper.frag.glsl create mode 100644 js/shaders/uv_helper.vert.glsl diff --git a/build.js b/build.js index c60180e8..c03cadb1 100644 --- a/build.js +++ b/build.js @@ -1,4 +1,5 @@ import * as esbuild from 'esbuild' +import { glsl } from "esbuild-plugin-glsl"; import { createRequire } from "module"; import commandLineArgs from 'command-line-args' import path from 'path'; @@ -23,7 +24,9 @@ function conditionalImportPlugin(config) { }; }; -let isApp = options.target == 'electron'; +const isApp = options.target == 'electron'; +const dev_mode = options.watch || options.serve; +const minify = !dev_mode; /** * @typedef {esbuild.BuildOptions} BuildOptions @@ -38,7 +41,7 @@ const config = { target: 'es2020', format: 'esm', bundle: true, - minify: false, + minify, outfile: './dist/bundle.js', mainFields: ['module', 'main'], external: [ @@ -47,6 +50,9 @@ const config = { plugins: [ conditionalImportPlugin({ file: isApp ? 'desktop.js' : 'web.js' + }), + glsl({ + minify }) ], sourcemap: true, @@ -67,7 +73,6 @@ if (options.watch || options.serve) { console.log(`Hosting app at http://${host}:${port}`) } } else { - config.minify = true; if (options.analyze) config.metafile = true; let result = await esbuild.build(config); if (options.analyze) { diff --git a/js/preview/canvas.js b/js/preview/canvas.js index e75dd568..545317bb 100644 --- a/js/preview/canvas.js +++ b/js/preview/canvas.js @@ -1,3 +1,16 @@ +import SolidMaterialVertShader from './../shaders/solid.vert.glsl' +import SolidMaterialFragShader from './../shaders/solid.frag.glsl' +import MarkerVertShader from './../shaders/marker.vert.glsl' +import MarkerFragShader from './../shaders/marker.frag.glsl' +import LayeredVertShader from './../shaders/layered.vert.glsl' +import LayeredFragShader from './../shaders/layered.frag.glsl' +import DirectionHelperVertShader from './../shaders/direction_helper.vert.glsl' +import DirectionHelperFragShader from './../shaders/direction_helper.frag.glsl' +import UVHelperVertShader from './../shaders/uv_helper.vert.glsl' +import UVHelperFragShader from './../shaders/uv_helper.frag.glsl' +import BrushOutlineVertShader from './../shaders/brush_outline.vert.glsl' +import BrushOutlineFragShader from './../shaders/brush_outline.frag.glsl' +import { prepareShader } from '../shaders/shader'; export function getRescalingFactor(angle) { switch (Math.abs(angle)) { @@ -36,77 +49,6 @@ export const Reusable = { euler2: new THREE.Euler(), } -// Aza note: -// --------------------------------------- -// Not sure about the pertinence of doing this, but my reasoning is that it saves us -// from copying the exact same shaders twice for both solid view mode variants (monochromatic & colored). -export const SolidMaterialShaders = { - vertShader: ` - attribute float highlight; - - uniform bool SHADE; - - varying float light; - varying float lift; - - float AMBIENT = 0.1; - float XFAC = -0.05; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelViewMatrix * vec4(normal, 0.0) ) ); - - light = (0.2 + abs(N.z) * 0.8) * (1.0-AMBIENT) + N.x*N.x * XFAC + N.y*N.y * ZFAC + AMBIENT; - - } else { - - light = 1.0; - - } - - if (highlight == 2.0) { - lift = 0.3; - } else if (highlight == 1.0) { - lift = 0.12; - } else { - lift = 0.0; - } - - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }`, - fragShader: ` - #ifdef GL_ES - precision ${isApp ? 'highp' : 'mediump'} float; - #endif - - uniform bool SHADE; - uniform float BRIGHTNESS; - uniform vec3 base; - - varying float light; - varying float lift; - - void main(void) - { - - gl_FragColor = vec4(lift + base * light * BRIGHTNESS, 1.0); - - if (lift > 0.1) { - gl_FragColor.b = gl_FragColor.b * 1.16; - gl_FragColor.g = gl_FragColor.g * 1.04; - } - if (lift > 0.2) { - gl_FragColor.r = gl_FragColor.r * 0.6; - gl_FragColor.g = gl_FragColor.g * 0.7; - } - - }` -} export const Canvas = { // Stores various colors for the 3D scene @@ -141,90 +83,18 @@ export const Canvas = { BRIGHTNESS: {type: 'bool', value: settings.brightness.value / 50}, base: {value: gizmo_colors.solid} }, - vertexShader: SolidMaterialShaders.vertShader, - fragmentShader: SolidMaterialShaders.fragShader, + vertexShader: prepareShader(SolidMaterialVertShader), + fragmentShader: prepareShader(SolidMaterialFragShader), side: THREE.DoubleSide }); })(), normalHelperMaterial: (function() { - var vertShader = ` - attribute float highlight; - - uniform bool SHADE; - - varying float light; - varying float lift; - - float AMBIENT = 0.1; - float XFAC = -0.05; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelViewMatrix * vec4(normal, 0.0) ) ); - light = (0.2 + abs(N.z) * 0.8) * (1.0-AMBIENT) + N.x*N.x * XFAC + N.y*N.y * ZFAC + AMBIENT; - - } else { - - light = 1.0; - } - - - if (highlight == 2.0) { - lift = 0.3; - } else if (highlight == 1.0) { - lift = 0.12; - } else { - lift = 0.0; - } - - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }` - var fragShader = ` - #ifdef GL_ES - precision ${isApp ? 'highp' : 'mediump'} float; - #endif - - varying float light; - varying float lift; - - void main(void) - { - if (gl_FrontFacing) { - gl_FragColor = vec4(vec3(0.20, 0.68, 0.32) * light, 1.0); - } else { - gl_FragColor = vec4(vec3(0.76, 0.21, 0.20) * light, 1.0); - } - - if (lift > 0.1) { - gl_FragColor.r = gl_FragColor.r * 1.16; - gl_FragColor.g = gl_FragColor.g * 1.16; - gl_FragColor.b = gl_FragColor.b * 1.16; - } - if (lift > 0.2) { - if (gl_FrontFacing) { - gl_FragColor.r = gl_FragColor.r * 0.8; - gl_FragColor.g = gl_FragColor.g * 0.9; - gl_FragColor.b = gl_FragColor.g * 1.5; - } else { - gl_FragColor.r = gl_FragColor.r * 0.9; - gl_FragColor.g = gl_FragColor.g * 2.0; - gl_FragColor.b = gl_FragColor.g * 3.0; - } - } - - }` - return new THREE.ShaderMaterial({ uniforms: { SHADE: {type: 'bool', value: settings.shading.value} }, - vertexShader: vertShader, - fragmentShader: fragShader, + vertexShader: prepareShader(DirectionHelperVertShader), + fragmentShader: prepareShader(DirectionHelperFragShader), side: THREE.DoubleSide }); })(), @@ -239,78 +109,6 @@ export const Canvas = { img.onload = function() { this.tex.needsUpdate = true; } - var vertShader = ` - attribute float highlight; - - uniform bool SHADE; - uniform float DENSITY; - - ${settings.antialiasing_bleed_fix.value ? 'centroid' : ''} varying vec2 vUv; - varying float light; - varying float lift; - - float AMBIENT = 0.1; - float XFAC = -0.05; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelViewMatrix * vec4(normal, 0.0) ) ); - - light = (0.2 + abs(N.z) * 0.8) * (1.0-AMBIENT) + N.x*N.x * XFAC + N.y*N.y * ZFAC + AMBIENT; - - } else { - - light = 1.0; - - } - - if (highlight == 2.0) { - lift = 0.3; - } else if (highlight == 1.0) { - lift = 0.12; - } else { - lift = 0.0; - } - - vUv = uv; - vUv.x = vUv.x * DENSITY; - vUv.y = vUv.y * DENSITY; - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }` - var fragShader = ` - #ifdef GL_ES - precision ${isApp ? 'highp' : 'mediump'} float; - #endif - - uniform sampler2D map; - - uniform bool SHADE; - - ${settings.antialiasing_bleed_fix.value ? 'centroid' : ''} varying vec2 vUv; - varying float light; - varying float lift; - - void main(void) - { - - vec4 color = texture2D(map, vUv); - - if (color.a < 0.01) discard; - - gl_FragColor = vec4(lift + color.rgb * light, color.a); - - - if (lift > 0.2) { - gl_FragColor.r = gl_FragColor.r * 0.6; - gl_FragColor.g = gl_FragColor.g * 0.7; - } - - }` return new THREE.ShaderMaterial({ uniforms: { @@ -318,8 +116,8 @@ export const Canvas = { SHADE: {type: 'bool', value: settings.shading.value}, DENSITY: {type: 'float', value: 4} }, - vertexShader: vertShader, - fragmentShader: fragShader, + vertexShader: prepareShader(UVHelperVertShader), + fragmentShader: prepareShader(UVHelperFragShader), side: THREE.DoubleSide, }) })(), @@ -336,76 +134,7 @@ export const Canvas = { img.onload = function() { this.tex.needsUpdate = true; } - var vertShader = ` - attribute float highlight; - uniform bool SHADE; - - varying vec2 vUv; - varying float light; - varying float lift; - - float AMBIENT = 0.5; - float XFAC = -0.15; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); - - float yLight = (1.0+N.y) * 0.5; - light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; - - } else { - - light = 1.0; - - } - - if (highlight == 2.0) { - lift = 0.22; - } else if (highlight == 1.0) { - lift = 0.1; - } else { - lift = 0.0; - } - - vUv = uv; - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }` - var fragShader = ` - #ifdef GL_ES - precision ${isApp ? 'highp' : 'mediump'} float; - #endif - - uniform sampler2D map; - - uniform bool SHADE; - uniform float BRIGHTNESS; - uniform vec3 base; - - varying vec2 vUv; - varying float light; - varying float lift; - - void main(void) - { - vec4 color = texture2D(map, vUv); - - gl_FragColor = vec4(lift + color.rgb * base * light * BRIGHTNESS, 1.0); - - if (lift > 0.2) { - gl_FragColor.r = gl_FragColor.r * 0.6; - gl_FragColor.g = gl_FragColor.g * 0.7; - } - - }` - - markerColors.forEach(function(color, i) { if (Canvas.emptyMaterials[i]) return; @@ -422,16 +151,16 @@ export const Canvas = { map: {type: 't', value: tex}, ...commonUniforms }, - vertexShader: vertShader, - fragmentShader: fragShader, + vertexShader: prepareShader(MarkerVertShader), + fragmentShader: prepareShader(MarkerFragShader), side: THREE.DoubleSide, }) // Colored solid materials Canvas.coloredSolidMaterials[i] = new THREE.ShaderMaterial({ uniforms: commonUniforms, - vertexShader: SolidMaterialShaders.vertShader, - fragmentShader: SolidMaterialShaders.fragShader, + vertexShader: prepareShader(SolidMaterialVertShader), + fragmentShader: prepareShader(SolidMaterialFragShader), side: THREE.DoubleSide }); }) @@ -696,78 +425,8 @@ export const Canvas = { SHAPE: { value: 0 }, }, - vertexShader: ` - varying vec2 vUv; - void main() - { - vUv = uv; - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }`, - - fragmentShader: ` - uniform int SHAPE; - - uniform vec3 color; - uniform float width; - - varying vec2 vUv; - - float drawSquareOutline(vec2 shapeUv, float width) - { - vec2 shapeUvX = shapeUv - dFdx(shapeUv); - vec2 shapeUvY = shapeUv - dFdy(shapeUv); - - vec2 squareDist = 1. - abs(shapeUv); - vec2 squareDistX = 1. - abs(shapeUvX); - vec2 squareDistY = 1. - abs(shapeUvY); - vec2 squareDxX = squareDistX - squareDist; - vec2 squareDxY = squareDistY - squareDist; - - vec2 squareSliceAA = squareDist / vec2(length(vec2(squareDxX.x, squareDxY.x)), length(vec2(squareDxX.y, squareDxY.y))); - - float squareOuterAA = min(squareSliceAA.x, squareSliceAA.y); - float squareInnerAA = min(squareSliceAA.x - width, squareSliceAA.y - width); - squareOuterAA = clamp(squareOuterAA, 0., 1.); - squareInnerAA = clamp(squareInnerAA, 0., 1.); - - return squareOuterAA - squareInnerAA; - } - - float drawCircleOutline(vec2 shapeUv, float width) - { - vec2 shapeUvX = shapeUv - dFdx(shapeUv); - vec2 shapeUvY = shapeUv - dFdy(shapeUv); - - float circleDist = 1. - length(shapeUv); - float circleDistX = 1. - length(shapeUvX); - float circleDistY = 1. - length(shapeUvY); - float circleDx = circleDistX - circleDist; - float circleDy = circleDistY - circleDist; - - float circleOuterAA = circleDist / length(vec2(circleDx, circleDy)); - float circleInnerAA = circleOuterAA - width; - circleOuterAA = clamp(circleOuterAA, 0., 1.); - circleInnerAA = clamp(circleInnerAA, 0., 1.); - - return circleOuterAA - circleInnerAA; - } - - void main(void) - { - vec2 shapeUv = vUv.xy * 2. - 1.; - - vec4 finalColor = vec4(color, 1.); - if (SHAPE == 0) - finalColor.a = drawSquareOutline(shapeUv, width); - else if (SHAPE == 1) - finalColor.a = drawCircleOutline(shapeUv, width); - - if (finalColor.a < 0.01) discard; - - gl_FragColor = finalColor; - } - `, + vertexShader: prepareShader(BrushOutlineVertShader), + fragmentShader: prepareShader(BrushOutlineFragShader), }) Canvas.brush_outline = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), brush_outline_material); Canvas.brush_outline.matrixAutoUpdate = false; @@ -1202,83 +861,6 @@ export const Canvas = { getLayeredMaterial(layers) { if (Canvas.layered_material && !layers) return Canvas.layered_material; // https://codepen.io/Fyrestar/pen/YmpXYr - var vertShader = ` - attribute float highlight; - - uniform bool SHADE; - - varying vec2 vUv; - varying float light; - varying float lift; - - float AMBIENT = 0.5; - float XFAC = -0.15; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); - - - float yLight = (1.0+N.y) * 0.5; - light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; - - } else { - - light = 1.0; - - } - - if (highlight == 2.0) { - lift = 0.22; - } else if (highlight == 1.0) { - lift = 0.1; - } else { - lift = 0.0; - } - - vUv = uv; - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }` - var fragShader = ` - #ifdef GL_ES - precision ${isApp ? 'highp' : 'mediump'} float; - #endif - - uniform sampler2D t0; - uniform sampler2D t1; - uniform sampler2D t2; - - uniform bool SHADE; - - varying vec2 vUv; - varying float light; - varying float lift; - - void main(void) - { - vec4 Ca = texture2D(t0, vUv); - vec4 Cb = texture2D(t1, vUv); - vec4 Cc = texture2D(t2, vUv); - - vec3 ctemp = Ca.rgb * Ca.a + Cb.rgb * Cb.a * (1.0 - Ca.a); - vec4 ctemp4 = vec4(ctemp, Ca.a + (1.0 - Ca.a) * Cb.a); - - vec3 c = ctemp4.rgb + Cc.rgb * Cc.a * (1.0 - ctemp4.a); - gl_FragColor= vec4(lift + c * light, ctemp4.a + (1.0 - ctemp4.a) * Cc.a); - - if (lift > 0.2) { - gl_FragColor.r = gl_FragColor.r * 0.6; - gl_FragColor.g = gl_FragColor.g * 0.7; - } - - if (gl_FragColor.a < 0.05) discard; - }` - var uniforms = { SHADE: {type: 'bool', value: settings.shading.value}, t0: {type: 't', value: null}, @@ -1296,8 +878,8 @@ export const Canvas = { var material_shh = new THREE.ShaderMaterial({ uniforms: uniforms, - vertexShader: vertShader, - fragmentShader: fragShader, + vertexShader: prepareShader(LayeredVertShader), + fragmentShader: prepareShader(LayeredFragShader), side: Canvas.getRenderSide(), transparent: true }); @@ -1414,7 +996,6 @@ Canvas.gizmos.push(Canvas.pivot_marker); Object.assign(window, { getRescalingFactor, Reusable, - SolidMaterialShaders, Canvas, buildGrid: Canvas.buildGrid }); diff --git a/js/shaders/brush_outline.frag.glsl b/js/shaders/brush_outline.frag.glsl new file mode 100644 index 00000000..cb17f60e --- /dev/null +++ b/js/shaders/brush_outline.frag.glsl @@ -0,0 +1,61 @@ +uniform int SHAPE; + +uniform vec3 color; +uniform float width; + +varying vec2 vUv; + +float drawSquareOutline(vec2 shapeUv, float width) +{ + vec2 shapeUvX = shapeUv - dFdx(shapeUv); + vec2 shapeUvY = shapeUv - dFdy(shapeUv); + + vec2 squareDist = 1. - abs(shapeUv); + vec2 squareDistX = 1. - abs(shapeUvX); + vec2 squareDistY = 1. - abs(shapeUvY); + vec2 squareDxX = squareDistX - squareDist; + vec2 squareDxY = squareDistY - squareDist; + + vec2 squareSliceAA = squareDist / vec2(length(vec2(squareDxX.x, squareDxY.x)), length(vec2(squareDxX.y, squareDxY.y))); + + float squareOuterAA = min(squareSliceAA.x, squareSliceAA.y); + float squareInnerAA = min(squareSliceAA.x - width, squareSliceAA.y - width); + squareOuterAA = clamp(squareOuterAA, 0., 1.); + squareInnerAA = clamp(squareInnerAA, 0., 1.); + + return squareOuterAA - squareInnerAA; +} + +float drawCircleOutline(vec2 shapeUv, float width) +{ + vec2 shapeUvX = shapeUv - dFdx(shapeUv); + vec2 shapeUvY = shapeUv - dFdy(shapeUv); + + float circleDist = 1. - length(shapeUv); + float circleDistX = 1. - length(shapeUvX); + float circleDistY = 1. - length(shapeUvY); + float circleDx = circleDistX - circleDist; + float circleDy = circleDistY - circleDist; + + float circleOuterAA = circleDist / length(vec2(circleDx, circleDy)); + float circleInnerAA = circleOuterAA - width; + circleOuterAA = clamp(circleOuterAA, 0., 1.); + circleInnerAA = clamp(circleInnerAA, 0., 1.); + + return circleOuterAA - circleInnerAA; +} + +void main(void) +{ + vec2 shapeUv = vUv.xy * 2. - 1.; + + vec4 finalColor = vec4(color, 1.); + if (SHAPE == 0) + finalColor.a = drawSquareOutline(shapeUv, width); + else if (SHAPE == 1) + finalColor.a = drawCircleOutline(shapeUv, width); + + if (finalColor.a < 0.01) discard; + + gl_FragColor = finalColor; +} \ No newline at end of file diff --git a/js/shaders/brush_outline.vert.glsl b/js/shaders/brush_outline.vert.glsl new file mode 100644 index 00000000..1e0ea247 --- /dev/null +++ b/js/shaders/brush_outline.vert.glsl @@ -0,0 +1,7 @@ +varying vec2 vUv; +void main() +{ + vUv = uv; + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} diff --git a/js/shaders/direction_helper.frag.glsl b/js/shaders/direction_helper.frag.glsl new file mode 100644 index 00000000..067fdca0 --- /dev/null +++ b/js/shaders/direction_helper.frag.glsl @@ -0,0 +1,33 @@ +#ifdef GL_ES +precision highp float; +#endif + +varying float light; +varying float lift; + +void main(void) +{ + if (gl_FrontFacing) { + gl_FragColor = vec4(vec3(0.20, 0.68, 0.32) * light, 1.0); + } else { + gl_FragColor = vec4(vec3(0.76, 0.21, 0.20) * light, 1.0); + } + + if (lift > 0.1) { + gl_FragColor.r = gl_FragColor.r * 1.16; + gl_FragColor.g = gl_FragColor.g * 1.16; + gl_FragColor.b = gl_FragColor.b * 1.16; + } + if (lift > 0.2) { + if (gl_FrontFacing) { + gl_FragColor.r = gl_FragColor.r * 0.8; + gl_FragColor.g = gl_FragColor.g * 0.9; + gl_FragColor.b = gl_FragColor.g * 1.5; + } else { + gl_FragColor.r = gl_FragColor.r * 0.9; + gl_FragColor.g = gl_FragColor.g * 2.0; + gl_FragColor.b = gl_FragColor.g * 3.0; + } + } + +} \ No newline at end of file diff --git a/js/shaders/direction_helper.vert.glsl b/js/shaders/direction_helper.vert.glsl new file mode 100644 index 00000000..d3b0bc3d --- /dev/null +++ b/js/shaders/direction_helper.vert.glsl @@ -0,0 +1,36 @@ +attribute float highlight; + +uniform bool SHADE; + +varying float light; +varying float lift; + +float AMBIENT = 0.1; +float XFAC = -0.05; +float ZFAC = 0.05; + +void main() +{ + + if (SHADE) { + + vec3 N = normalize( vec3( modelViewMatrix * vec4(normal, 0.0) ) ); + light = (0.2 + abs(N.z) * 0.8) * (1.0-AMBIENT) + N.x*N.x * XFAC + N.y*N.y * ZFAC + AMBIENT; + + } else { + + light = 1.0; + } + + + if (highlight == 2.0) { + lift = 0.3; + } else if (highlight == 1.0) { + lift = 0.12; + } else { + lift = 0.0; + } + + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} \ No newline at end of file diff --git a/js/shaders/layered.frag.glsl b/js/shaders/layered.frag.glsl new file mode 100644 index 00000000..a43d6e78 --- /dev/null +++ b/js/shaders/layered.frag.glsl @@ -0,0 +1,33 @@ +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D t0; +uniform sampler2D t1; +uniform sampler2D t2; + +uniform bool SHADE; + +varying vec2 vUv; +varying float light; +varying float lift; + +void main(void) +{ + vec4 Ca = texture2D(t0, vUv); + vec4 Cb = texture2D(t1, vUv); + vec4 Cc = texture2D(t2, vUv); + + vec3 ctemp = Ca.rgb * Ca.a + Cb.rgb * Cb.a * (1.0 - Ca.a); + vec4 ctemp4 = vec4(ctemp, Ca.a + (1.0 - Ca.a) * Cb.a); + + vec3 c = ctemp4.rgb + Cc.rgb * Cc.a * (1.0 - ctemp4.a); + gl_FragColor= vec4(lift + c * light, ctemp4.a + (1.0 - ctemp4.a) * Cc.a); + + if (lift > 0.2) { + gl_FragColor.r = gl_FragColor.r * 0.6; + gl_FragColor.g = gl_FragColor.g * 0.7; + } + + if (gl_FragColor.a < 0.05) discard; +} \ No newline at end of file diff --git a/js/shaders/layered.vert.glsl b/js/shaders/layered.vert.glsl new file mode 100644 index 00000000..ebc3cb02 --- /dev/null +++ b/js/shaders/layered.vert.glsl @@ -0,0 +1,41 @@ +attribute float highlight; + +uniform bool SHADE; + +varying vec2 vUv; +varying float light; +varying float lift; + +float AMBIENT = 0.5; +float XFAC = -0.15; +float ZFAC = 0.05; + +void main() +{ + + if (SHADE) { + + vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); + + + float yLight = (1.0+N.y) * 0.5; + light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; + + } else { + + light = 1.0; + + } + + if (highlight == 2.0) { + lift = 0.22; + } else if (highlight == 1.0) { + lift = 0.1; + } else { + lift = 0.0; + } + + vUv = uv; + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} \ No newline at end of file diff --git a/js/shaders/marker.frag.glsl b/js/shaders/marker.frag.glsl new file mode 100644 index 00000000..77c55dc6 --- /dev/null +++ b/js/shaders/marker.frag.glsl @@ -0,0 +1,26 @@ +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D map; + +uniform bool SHADE; +uniform float BRIGHTNESS; +uniform vec3 base; + +varying vec2 vUv; +varying float light; +varying float lift; + +void main(void) +{ + vec4 color = texture2D(map, vUv); + + gl_FragColor = vec4(lift + color.rgb * base * light * BRIGHTNESS, 1.0); + + if (lift > 0.2) { + gl_FragColor.r = gl_FragColor.r * 0.6; + gl_FragColor.g = gl_FragColor.g * 0.7; + } + +}` \ No newline at end of file diff --git a/js/shaders/marker.vert.glsl b/js/shaders/marker.vert.glsl new file mode 100644 index 00000000..85136b2f --- /dev/null +++ b/js/shaders/marker.vert.glsl @@ -0,0 +1,40 @@ +attribute float highlight; + +uniform bool SHADE; + +varying vec2 vUv; +varying float light; +varying float lift; + +float AMBIENT = 0.5; +float XFAC = -0.15; +float ZFAC = 0.05; + +void main() +{ + + if (SHADE) { + + vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); + + float yLight = (1.0+N.y) * 0.5; + light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; + + } else { + + light = 1.0; + + } + + if (highlight == 2.0) { + lift = 0.22; + } else if (highlight == 1.0) { + lift = 0.1; + } else { + lift = 0.0; + } + + vUv = uv; + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} \ No newline at end of file diff --git a/js/shaders/shader.ts b/js/shaders/shader.ts new file mode 100644 index 00000000..78a56d28 --- /dev/null +++ b/js/shaders/shader.ts @@ -0,0 +1,11 @@ +import { settings } from "../interface/settings"; + +export function prepareShader(shader: string): string { + if (settings.antialiasing_bleed_fix.value == false) { + shader = shader.replace(/centroid /g, ''); + } + if (!isApp) { + shader = shader.replace('precision highp', 'precision mediump'); + } + return shader; +} \ No newline at end of file diff --git a/js/shaders/solid.frag.glsl b/js/shaders/solid.frag.glsl new file mode 100644 index 00000000..3eb02266 --- /dev/null +++ b/js/shaders/solid.frag.glsl @@ -0,0 +1,26 @@ +#ifdef GL_ES +precision highp float; +#endif + +uniform bool SHADE; +uniform float BRIGHTNESS; +uniform vec3 base; + +varying float light; +varying float lift; + +void main(void) +{ + + gl_FragColor = vec4(lift + base * light * BRIGHTNESS, 1.0); + + if (lift > 0.1) { + gl_FragColor.b = gl_FragColor.b * 1.16; + gl_FragColor.g = gl_FragColor.g * 1.04; + } + if (lift > 0.2) { + gl_FragColor.r = gl_FragColor.r * 0.6; + gl_FragColor.g = gl_FragColor.g * 0.7; + } + +} \ No newline at end of file diff --git a/js/shaders/solid.vert.glsl b/js/shaders/solid.vert.glsl new file mode 100644 index 00000000..6f915181 --- /dev/null +++ b/js/shaders/solid.vert.glsl @@ -0,0 +1,37 @@ +attribute float highlight; + +uniform bool SHADE; + +varying float light; +varying float lift; + +float AMBIENT = 0.1; +float XFAC = -0.05; +float ZFAC = 0.05; + +void main() +{ + + if (SHADE) { + + vec3 N = normalize( vec3( modelViewMatrix * vec4(normal, 0.0) ) ); + + light = (0.2 + abs(N.z) * 0.8) * (1.0-AMBIENT) + N.x*N.x * XFAC + N.y*N.y * ZFAC + AMBIENT; + + } else { + + light = 1.0; + + } + + if (highlight == 2.0) { + lift = 0.3; + } else if (highlight == 1.0) { + lift = 0.12; + } else { + lift = 0.0; + } + + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} \ No newline at end of file diff --git a/js/shaders/texture.frag.glsl b/js/shaders/texture.frag.glsl new file mode 100644 index 00000000..3195e703 --- /dev/null +++ b/js/shaders/texture.frag.glsl @@ -0,0 +1,41 @@ +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D map; + +uniform bool SHADE; +uniform bool EMISSIVE; +uniform vec3 LIGHTCOLOR; + +centroid varying vec2 vUv; +varying float light; +varying float lift; + +void main(void) +{ + vec4 color = texture2D(map, vUv); + + if (color.a < 0.01) discard; + + if (EMISSIVE == false) { + + gl_FragColor = vec4(lift + color.rgb * light, color.a); + gl_FragColor.r = gl_FragColor.r * LIGHTCOLOR.r; + gl_FragColor.g = gl_FragColor.g * LIGHTCOLOR.g; + gl_FragColor.b = gl_FragColor.b * LIGHTCOLOR.b; + + } else { + + float light_r = (light * LIGHTCOLOR.r) + (1.0 - light * LIGHTCOLOR.r) * (1.0 - color.a); + float light_g = (light * LIGHTCOLOR.g) + (1.0 - light * LIGHTCOLOR.g) * (1.0 - color.a); + float light_b = (light * LIGHTCOLOR.b) + (1.0 - light * LIGHTCOLOR.b) * (1.0 - color.a); + gl_FragColor = vec4(lift + color.r * light_r, lift + color.g * light_g, lift + color.b * light_b, 1.0); + + } + + if (lift > 0.2) { + gl_FragColor.r = gl_FragColor.r * 0.6; + gl_FragColor.g = gl_FragColor.g * 0.7; + } +} \ No newline at end of file diff --git a/js/shaders/texture.vert.glsl b/js/shaders/texture.vert.glsl new file mode 100644 index 00000000..8847b265 --- /dev/null +++ b/js/shaders/texture.vert.glsl @@ -0,0 +1,65 @@ +attribute float highlight; + +uniform bool SHADE; +uniform int LIGHTSIDE; + +varying vec2 vUv; +varying float light; +varying float lift; + +float AMBIENT = 0.5; +float XFAC = -0.15; +float ZFAC = 0.05; + +void main() +{ + + if (SHADE) { + + vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); + + if (LIGHTSIDE == 1) { + float temp = N.y; + N.y = N.z * -1.0; + N.z = temp; + } + if (LIGHTSIDE == 2) { + float temp = N.y; + N.y = N.x; + N.x = temp; + } + if (LIGHTSIDE == 3) { + N.y = N.y * -1.0; + } + if (LIGHTSIDE == 4) { + float temp = N.y; + N.y = N.z; + N.z = temp; + } + if (LIGHTSIDE == 5) { + float temp = N.y; + N.y = N.x * -1.0; + N.x = temp; + } + + float yLight = (1.0+N.y) * 0.5; + light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; + + } else { + + light = 1.0; + + } + + if (highlight == 2.0) { + lift = 0.22; + } else if (highlight == 1.0) { + lift = 0.1; + } else { + lift = 0.0; + } + + vUv = uv; + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} \ No newline at end of file diff --git a/js/shaders/uv_helper.frag.glsl b/js/shaders/uv_helper.frag.glsl new file mode 100644 index 00000000..72cfc8a1 --- /dev/null +++ b/js/shaders/uv_helper.frag.glsl @@ -0,0 +1,28 @@ +#ifdef GL_ES +precision highp float; +#endif + +uniform sampler2D map; + +uniform bool SHADE; + +centroid varying vec2 vUv; +varying float light; +varying float lift; + +void main(void) +{ + + vec4 color = texture2D(map, vUv); + + if (color.a < 0.01) discard; + + gl_FragColor = vec4(lift + color.rgb * light, color.a); + + + if (lift > 0.2) { + gl_FragColor.r = gl_FragColor.r * 0.6; + gl_FragColor.g = gl_FragColor.g * 0.7; + } + +} \ No newline at end of file diff --git a/js/shaders/uv_helper.vert.glsl b/js/shaders/uv_helper.vert.glsl new file mode 100644 index 00000000..53da1f05 --- /dev/null +++ b/js/shaders/uv_helper.vert.glsl @@ -0,0 +1,42 @@ +attribute float highlight; + +uniform bool SHADE; +uniform float DENSITY; + +centroid varying vec2 vUv; +varying float light; +varying float lift; + +float AMBIENT = 0.1; +float XFAC = -0.05; +float ZFAC = 0.05; + +void main() +{ + + if (SHADE) { + + vec3 N = normalize( vec3( modelViewMatrix * vec4(normal, 0.0) ) ); + + light = (0.2 + abs(N.z) * 0.8) * (1.0-AMBIENT) + N.x*N.x * XFAC + N.y*N.y * ZFAC + AMBIENT; + + } else { + + light = 1.0; + + } + + if (highlight == 2.0) { + lift = 0.3; + } else if (highlight == 1.0) { + lift = 0.12; + } else { + lift = 0.0; + } + + vUv = uv; + vUv.x = vUv.x * DENSITY; + vUv.y = vUv.y * DENSITY; + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * mvPosition; +} \ No newline at end of file diff --git a/js/texturing/textures.js b/js/texturing/textures.js index 85451c2e..242b1066 100644 --- a/js/texturing/textures.js +++ b/js/texturing/textures.js @@ -1,3 +1,6 @@ +import VertShader from './../shaders/texture.vert.glsl'; +import FragShader from './../shaders/texture.frag.glsl'; +import { prepareShader } from '../shaders/shader'; //Textures export class Texture { @@ -61,114 +64,6 @@ export class Texture { tex.name = this.name; img.tex = tex; - var vertShader = ` - attribute float highlight; - - uniform bool SHADE; - uniform int LIGHTSIDE; - - ${settings.antialiasing_bleed_fix.value ? 'centroid' : ''} varying vec2 vUv; - varying float light; - varying float lift; - - float AMBIENT = 0.5; - float XFAC = -0.15; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); - - if (LIGHTSIDE == 1) { - float temp = N.y; - N.y = N.z * -1.0; - N.z = temp; - } - if (LIGHTSIDE == 2) { - float temp = N.y; - N.y = N.x; - N.x = temp; - } - if (LIGHTSIDE == 3) { - N.y = N.y * -1.0; - } - if (LIGHTSIDE == 4) { - float temp = N.y; - N.y = N.z; - N.z = temp; - } - if (LIGHTSIDE == 5) { - float temp = N.y; - N.y = N.x * -1.0; - N.x = temp; - } - - float yLight = (1.0+N.y) * 0.5; - light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; - - } else { - - light = 1.0; - - } - - if (highlight == 2.0) { - lift = 0.22; - } else if (highlight == 1.0) { - lift = 0.1; - } else { - lift = 0.0; - } - - vUv = uv; - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }` - var fragShader = ` - #ifdef GL_ES - precision ${isApp ? 'highp' : 'mediump'} float; - #endif - - uniform sampler2D map; - - uniform bool SHADE; - uniform bool EMISSIVE; - uniform vec3 LIGHTCOLOR; - - ${settings.antialiasing_bleed_fix.value ? 'centroid' : ''} varying vec2 vUv; - varying float light; - varying float lift; - - void main(void) - { - vec4 color = texture2D(map, vUv); - - if (color.a < 0.01) discard; - - if (EMISSIVE == false) { - - gl_FragColor = vec4(lift + color.rgb * light, color.a); - gl_FragColor.r = gl_FragColor.r * LIGHTCOLOR.r; - gl_FragColor.g = gl_FragColor.g * LIGHTCOLOR.g; - gl_FragColor.b = gl_FragColor.b * LIGHTCOLOR.b; - - } else { - - float light_r = (light * LIGHTCOLOR.r) + (1.0 - light * LIGHTCOLOR.r) * (1.0 - color.a); - float light_g = (light * LIGHTCOLOR.g) + (1.0 - light * LIGHTCOLOR.g) * (1.0 - color.a); - float light_b = (light * LIGHTCOLOR.b) + (1.0 - light * LIGHTCOLOR.b) * (1.0 - color.a); - gl_FragColor = vec4(lift + color.r * light_r, lift + color.g * light_g, lift + color.b * light_b, 1.0); - - } - - if (lift > 0.2) { - gl_FragColor.r = gl_FragColor.r * 0.6; - gl_FragColor.g = gl_FragColor.g * 0.7; - } - }` var mat = new THREE.ShaderMaterial({ uniforms: { map: {type: 't', value: tex}, @@ -177,8 +72,8 @@ export class Texture { LIGHTSIDE: {type: 'int', value: Canvas.global_light_side}, EMISSIVE: {type: 'bool', value: this.render_mode == 'emissive'} }, - vertexShader: vertShader, - fragmentShader: fragShader, + vertexShader: prepareShader(VertShader), + fragmentShader: prepareShader(FragShader), blending: this.render_mode == 'additive' ? THREE.AdditiveBlending : THREE.NormalBlending, side: Canvas.getRenderSide(this), transparent: true, diff --git a/js/types.d.ts b/js/types.d.ts index 05bfa5c2..522756cc 100644 --- a/js/types.d.ts +++ b/js/types.d.ts @@ -1 +1,5 @@ -/// \ No newline at end of file +/// +declare module "*.glsl" { + const value: string; + export default value; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ab490ac4..56347c75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "electron": "^33.3.1", "electron-builder": "^24.13.3", "esbuild": "0.25.0", + "esbuild-plugin-glsl": "^1.2.2", "typescript": "^5.8.2", "workbox-build": "^6.5.3" } @@ -4863,6 +4864,19 @@ "@esbuild/win32-x64": "0.25.0" } }, + "node_modules/esbuild-plugin-glsl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esbuild-plugin-glsl/-/esbuild-plugin-glsl-1.2.2.tgz", + "integrity": "sha512-HqRe6qf+9q3U4ugce7EXnXf+c+bRGZZWNkUSiJBYCKRLkA5ThhklNxlc1Z/rcBM8DIAKAdZGk+j6nTBaA5SV6A==", + "dev": true, + "license": "Zlib", + "engines": { + "node": ">= 0.10.18" + }, + "peerDependencies": { + "esbuild": "0.x.x" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", diff --git a/package.json b/package.json index 667c3117..048f1d46 100644 --- a/package.json +++ b/package.json @@ -142,6 +142,7 @@ "electron": "^33.3.1", "electron-builder": "^24.13.3", "esbuild": "0.25.0", + "esbuild-plugin-glsl": "^1.2.2", "typescript": "^5.8.2", "workbox-build": "^6.5.3" },