diff --git a/config/gui_config.json b/config/gui_config.json index f4d06a1..297385b 100644 --- a/config/gui_config.json +++ b/config/gui_config.json @@ -1 +1,94 @@ -{"disabled":false,"hidden":false,"children":[{"disabled":false,"hidden":false,"children":[{"disabled":false,"hidden":false,"title":"import"},{"disabled":false,"hidden":false,"title":"export"},{"disabled":false,"hidden":false,"title":"reset"}],"expanded":true,"title":"config"},{"disabled":false,"hidden":false,"children":[{"disabled":false,"hidden":false,"label":"gamma correction","max":2,"min":0,"binding":{"key":"gammaCorrection","value":2}},{"disabled":false,"hidden":false,"label":"granularity","max":10,"min":1,"binding":{"key":"granularity","value":1}},{"disabled":false,"hidden":false,"label":"color","binding":{"key":"color","value":{"r":1,"g":1,"b":1}}},{"disabled":false,"hidden":false,"label":"mode","options":[{"text":"BAYER_2x2","value":"BAYER_2x2"},{"text":"BAYER_4x4","value":"BAYER_4x4"},{"text":"BAYER_8x8","value":"BAYER_8x8"},{"text":"DOT_4x4","value":"DOT_4x4"},{"text":"DOT_6x6","value":"DOT_6x6"},{"text":"DOT_6x6_2","value":"DOT_6x6_2"},{"text":"DOT_6x6_3","value":"DOT_6x6_3"},{"text":"DOT_8x8","value":"DOT_8x8"},{"text":"VERTICAL_5x3","value":"VERTICAL_5x3"},{"text":"HORIZONTAL_3x5","value":"HORIZONTAL_3x5"},{"text":"DOT_DIAGONAL_6x6","value":"DOT_DIAGONAL_6x6"},{"text":"DOT_DIAGONAL_8x8","value":"DOT_DIAGONAL_8x8"},{"text":"DOT_DIAGONAL_8x8_2","value":"DOT_DIAGONAL_8x8_2"},{"text":"DOT_DIAGONAL_8x8_3","value":"DOT_DIAGONAL_8x8_3"},{"text":"DOT_DIAGONAL_16x16","value":"DOT_DIAGONAL_16x16"},{"text":"DOT_SPIRAL_5x5","value":"DOT_SPIRAL_5x5"},{"text":"DOT_HORIZONTAL_6x6","value":"DOT_HORIZONTAL_6x6"},{"text":"DOT_VERTICAL_6x6","value":"DOT_VERTICAL_6x6"},{"text":"RANDOM","value":"RANDOM"}],"binding":{"key":"mode","value":"DOT_DIAGONAL_16x16"}},{"disabled":false,"hidden":false,"children":[{"disabled":false,"hidden":false,"label":"opacity","max":1,"min":0,"binding":{"key":"opacity","value":1}},{"disabled":false,"hidden":false,"label":"mode","options":[{"text":"SKIP","value":9},{"text":"SET","value":30},{"text":"ADD","value":0},{"text":"ALPHA","value":1},{"text":"AVERAGE","value":2},{"text":"COLOR","value":3},{"text":"COLOR_BURN","value":4},{"text":"COLOR_DODGE","value":5},{"text":"DARKEN","value":6},{"text":"DIFFERENCE","value":7},{"text":"DIVIDE","value":8},{"text":"DST","value":9},{"text":"EXCLUSION","value":10},{"text":"HARD_LIGHT","value":11},{"text":"HARD_MIX","value":12},{"text":"HUE","value":13},{"text":"INVERT","value":14},{"text":"INVERT_RGB","value":15},{"text":"LIGHTEN","value":16},{"text":"LINEAR_BURN","value":17},{"text":"LINEAR_DODGE","value":18},{"text":"LINEAR_LIGHT","value":19},{"text":"LUMINOSITY","value":20},{"text":"MULTIPLY","value":21},{"text":"NEGATION","value":22},{"text":"NORMAL","value":23},{"text":"OVERLAY","value":24},{"text":"PIN_LIGHT","value":25},{"text":"REFLECT","value":26},{"text":"SATURATION","value":27},{"text":"SCREEN","value":28},{"text":"SOFT_LIGHT","value":29},{"text":"SRC","value":30},{"text":"SUBTRACT","value":31},{"text":"VIVID_LIGHT","value":32}],"binding":{"key":"mode","value":23}}],"expanded":true,"title":"blending"}],"expanded":true,"title":"dithering"},{"disabled":false,"hidden":false,"children":[{"disabled":false,"hidden":false,"title":"export as image"},{"disabled":false,"hidden":false,"title":"start recording"},{"disabled":false,"hidden":false,"title":"stop recording"}],"expanded":true,"title":"export"}],"expanded":true} \ No newline at end of file +{ + "disabled": false, + "hidden": false, + "children": [ + { + "disabled": false, + "hidden": false, + "children": [ + { "disabled": false, "hidden": false, "title": "import" }, + { "disabled": false, "hidden": false, "title": "export" }, + { "disabled": false, "hidden": false, "title": "reset" } + ], + "expanded": true, + "title": "config" + }, + { + "disabled": false, + "hidden": false, + "children": [ + { + "disabled": false, + "hidden": false, + "label": "gamma correction", + "max": 2, + "min": 0, + "binding": { "key": "gammaCorrection", "value": 2 } + }, + { + "disabled": false, + "hidden": false, + "label": "granularity", + "max": 10, + "min": 1, + "binding": { "key": "granularity", "value": 1 } + }, + { + "disabled": false, + "hidden": false, + "label": "color", + "binding": { "key": "color", "value": { "r": 0, "g": 0, "b": 1 } } + }, + { + "disabled": false, + "hidden": false, + "label": "opacity", + "max": 1, + "min": 0, + "binding": { "key": "opacity", "value": 1 } + }, + { + "disabled": false, + "hidden": false, + "label": "mode", + "options": [ + { "text": "BAYER_2x2", "value": "BAYER_2x2" }, + { "text": "BAYER_4x4", "value": "BAYER_4x4" }, + { "text": "BAYER_8x8", "value": "BAYER_8x8" }, + { "text": "DOT_4x4", "value": "DOT_4x4" }, + { "text": "DOT_6x6", "value": "DOT_6x6" }, + { "text": "DOT_6x6_2", "value": "DOT_6x6_2" }, + { "text": "DOT_6x6_3", "value": "DOT_6x6_3" }, + { "text": "DOT_8x8", "value": "DOT_8x8" }, + { "text": "VERTICAL_5x3", "value": "VERTICAL_5x3" }, + { "text": "HORIZONTAL_3x5", "value": "HORIZONTAL_3x5" }, + { "text": "DOT_DIAGONAL_6x6", "value": "DOT_DIAGONAL_6x6" }, + { "text": "DOT_DIAGONAL_8x8", "value": "DOT_DIAGONAL_8x8" }, + { "text": "DOT_DIAGONAL_8x8_2", "value": "DOT_DIAGONAL_8x8_2" }, + { "text": "DOT_DIAGONAL_8x8_3", "value": "DOT_DIAGONAL_8x8_3" }, + { "text": "DOT_DIAGONAL_16x16", "value": "DOT_DIAGONAL_16x16" }, + { "text": "DOT_SPIRAL_5x5", "value": "DOT_SPIRAL_5x5" }, + { "text": "DOT_HORIZONTAL_6x6", "value": "DOT_HORIZONTAL_6x6" }, + { "text": "DOT_VERTICAL_6x6", "value": "DOT_VERTICAL_6x6" }, + { "text": "RANDOM", "value": "RANDOM" } + ], + "binding": { "key": "mode", "value": "DOT_DIAGONAL_16x16" } + } + ], + "expanded": true, + "title": "dithering" + }, + { + "disabled": false, + "hidden": false, + "children": [ + { "disabled": false, "hidden": false, "title": "export as image" }, + { "disabled": false, "hidden": false, "title": "start recording" }, + { "disabled": false, "hidden": false, "title": "stop recording" } + ], + "expanded": true, + "title": "export" + } + ], + "expanded": true +} diff --git a/libs/gui.js b/libs/gui.js index 27afaba..74b11cd 100644 --- a/libs/gui.js +++ b/libs/gui.js @@ -1,7 +1,7 @@ import DEFAULT_CONFIG from 'config/gui_config.json' import { Pane } from 'tweakpane' -let defaultConfig +// let defaultConfig export const GUI = new Pane() @@ -26,7 +26,6 @@ folder.addButton({ title: 'import' }).on('click', () => { folder.addButton({ title: 'export' }).on('click', () => { const state = GUI.exportState() - console.log(state) const link = document.createElement('a') link.download = 'config.json' @@ -37,19 +36,26 @@ folder.addButton({ title: 'export' }).on('click', () => { }) folder.addButton({ title: 'reset' }).on('click', () => { - if (!defaultConfig) return - GUI.importState(JSON.parse(defaultConfig)) - localStorage.setItem('config', JSON.stringify(defaultConfig)) + // localStorage.removeItem('gpu-dithering-config') + + // if (!defaultConfig) return + // GUI.importState(JSON.parse(defaultConfig)) + // localStorage.setItem('config', JSON.stringify(defaultConfig)) + + GUI.importState(DEFAULT_CONFIG) }) setTimeout(() => { GUI.importState(DEFAULT_CONFIG) // persist config - defaultConfig = JSON.stringify(GUI.exportState()) - GUI.importState(JSON.parse(localStorage.getItem('config')) || {}) + // defaultConfig = JSON.stringify(GUI.exportState()) + // GUI.importState(JSON.parse(localStorage.getItem('config')) || {}) GUI.on('change', () => { - localStorage.setItem('config', JSON.stringify(GUI.exportState())) + localStorage.setItem( + 'gpu-dithering-config', + JSON.stringify(GUI.exportState()), + ) }) }, 1000) diff --git a/libs/webgl/components/postprocessing/effects/dithering/effect.js b/libs/webgl/components/postprocessing/effects/dithering/effect.js index 227fb4c..1bb9f9f 100644 --- a/libs/webgl/components/postprocessing/effects/dithering/effect.js +++ b/libs/webgl/components/postprocessing/effects/dithering/effect.js @@ -1,3 +1,4 @@ +import { BLEND } from 'libs/webgl/utils/blend' import { Effect } from 'postprocessing' import { Color, Vector2, Vector4 } from 'three' @@ -6,8 +7,10 @@ import { Color, Vector2, Vector4 } from 'three' // https://offscreencanvas.com/issues/glsl-dithering/ const fragmentShader = ` + ${BLEND.NORMAL} uniform float uGammaCorrection; + uniform float uOpacity; uniform vec3 uColor; uniform float uMatrix; uniform sampler2D uMatrixTexture; @@ -28,7 +31,7 @@ const fragmentShader = ` float dither(float value) { float threshold = uRandom ? rand(gl_FragCoord.xy * 10.) : indexValue(); - value *= 0.985; // hot fix for correct dithering + // value *= 0.985; // hot fix for correct dithering return (value <= threshold) ? 0. : 1.; } @@ -59,7 +62,9 @@ const fragmentShader = ` float dithered = dither(gammaCorrection(grayscaled, uGammaCorrection)); vec3 ditheredColor = vec3(dithered); - outputColor = vec4(ditheredColor * uColor, inputColor.a); + vec3 color = blendNormal(grayscaledColor * uColor, ditheredColor + uColor, uOpacity); + + outputColor = vec4(color, inputColor.a); } ` @@ -67,11 +72,13 @@ export class DitheringEffect extends Effect { constructor({ gammaCorrection = 0.6, color = new Color(1, 1, 1), + opacity = 1, granularity = 1, } = {}) { super('DitheringEffect', fragmentShader, { uniforms: new Map([ ['uGammaCorrection', { value: gammaCorrection }], + ['uOpacity', { value: opacity }], ['uColor', { value: color }], ['uMatrixTexture', { value: null }], ['uMatrixTextureSize', { value: new Vector2() }], @@ -112,6 +119,10 @@ export class DitheringEffect extends Effect { return this._granularity } + set opacity(value) { + this.uniforms.get('uOpacity').value = value + } + set granularity(value) { let d = Math.floor(value) d = Math.max(1, d) diff --git a/libs/webgl/components/postprocessing/effects/dithering/index.js b/libs/webgl/components/postprocessing/effects/dithering/index.js index 37d28c9..f1be017 100644 --- a/libs/webgl/components/postprocessing/effects/dithering/index.js +++ b/libs/webgl/components/postprocessing/effects/dithering/index.js @@ -10,9 +10,10 @@ import { DitheringEffect } from './effect' const DEFAULT_CONFIG = { // luminanceFilter: { r: 0.299, g: 0.587, b: 0.114 }, gammaCorrection: 1, - color: { r: 1, g: 1, b: 1 }, + color: { r: 0, g: 0, b: 1 }, granularity: 1, mode: 'BAYER_8x8', + opacity: 1, blending: { opacity: 1, mode: BlendFunction.NORMAL, @@ -69,7 +70,7 @@ export function useDitheringEffect() { ditheringFolder .addBinding(CONFIG, 'granularity', { min: 1, - step: 0.1, + step: 1, max: 10, label: 'granularity', }) @@ -88,21 +89,17 @@ export function useDitheringEffect() { }) effect.color = CONFIG.color - // ditheringFolder - // .addBlade({ - // view: 'list', - // label: 'mode', - // options: Object.keys(ORDERED_DITHERERS).map((key) => ({ - // text: key, - // value: key, - // })), - // value: 'BAYER_8x8', - // }) - // .on('change', ({ value }) => { - // console.log(value) - // // setMode(value) - // // effect.matrix = value - // }) + ditheringFolder + .addBinding(CONFIG, 'opacity', { + label: 'opacity', + min: 0, + step: 0.01, + max: 1, + }) + .on('change', ({ value }) => { + effect.opacity = value + }) + effect.opacity = CONFIG.opacity ditheringFolder .addBinding(CONFIG, 'mode', { @@ -122,48 +119,36 @@ export function useDitheringEffect() { // effect.matrix = value }) - // ditheringFolder - // .addBinding(PARAMS, 'matrix', { - // options: { - // 'Bayer 4x4': 4, - // 'Bayer 8x8': 8, - // }, - // label: 'matrix', + // const blendingFolder = ditheringFolder.addFolder({ + // title: 'blending', + // expanded: true, + // }) + + // blendingFolder + // .addBinding(CONFIG.blending, 'opacity', { + // min: 0, + // step: 0.01, + // max: 1, + // label: 'opacity', // }) // .on('change', ({ value }) => { - // effect.matrix = value + // effect.blendMode.setOpacity(value) // }) - // effect.matrix = PARAMS.matrix - - const blendingFolder = ditheringFolder.addFolder({ - title: 'blending', - expanded: true, - }) + // effect.blendMode.setOpacity(CONFIG.blending.opacity) - blendingFolder - .addBinding(CONFIG.blending, 'opacity', { - min: 0, - step: 0.01, - max: 1, - label: 'opacity', - }) - .on('change', ({ value }) => { - effect.blendMode.setOpacity(value) - }) - effect.blendMode.setOpacity(CONFIG.blending.opacity) - - blendingFolder - .addBinding(CONFIG.blending, 'mode', { - label: 'mode', - options: BlendFunction, - }) - .on('change', ({ value }) => { - effect.blendMode.blendFunction = value - }) - effect.blendMode.blendFunction = CONFIG.blending.mode + // blendingFolder + // .addBinding(CONFIG.blending, 'mode', { + // label: 'mode', + // options: BlendFunction, + // }) + // .on('change', ({ value }) => { + // effect.blendMode.blendFunction = value + // }) + // effect.blendMode.blendFunction = CONFIG.blending.mode return () => { ditheringFolder.dispose() + // blendingFolder.dispose() // GUI.dispose() } }, [effect]) diff --git a/pages/_app.js b/pages/_app.js index 9a52182..f5b407d 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -7,7 +7,6 @@ import { ScrollTrigger } from 'gsap/dist/ScrollTrigger' import { GTM_ID } from 'libs/analytics' import { Orchestra } from 'libs/orchestra' import { useStore } from 'libs/store' -import { ProjectProvider, RafDriverProvider } from 'libs/theatre' import Script from 'next/script' import { useEffect } from 'react' import 'styles/global.scss' @@ -68,15 +67,8 @@ function MyApp({ Component, pageProps }) { )} - - - - - - + + )