Move shaders to separate files

This commit is contained in:
JannisX11 2025-03-06 22:42:41 +01:00
parent de90b06fc1
commit 5b8e8413a3
21 changed files with 587 additions and 560 deletions

View File

@ -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) {

View File

@ -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
});

View File

@ -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;
}

View File

@ -0,0 +1,7 @@
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}`

View File

@ -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;
}

11
js/shaders/shader.ts Normal file
View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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,

6
js/types.d.ts vendored
View File

@ -1 +1,5 @@
/// <reference types="blockbench-types" />
/// <reference types="blockbench-types" />
declare module "*.glsl" {
const value: string;
export default value;
}

14
package-lock.json generated
View File

@ -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",

View File

@ -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"
},