| "@types/wicg-file-system-access": "^2020.9.5", | "@types/wicg-file-system-access": "^2020.9.5", | ||||
| "stats.js": "^0.17.0", | "stats.js": "^0.17.0", | ||||
| "ts-browser-helpers": "^0.16.0", | "ts-browser-helpers": "^0.16.0", | ||||
| "uiconfig.js": "^0.1.1" | |||||
| "uiconfig.js": "0.1.1" | |||||
| }, | }, | ||||
| "//": { | "//": { | ||||
| "dependencies": { | "dependencies": { |
| { | { | ||||
| "name": "@threepipe/plugin-blend-importer", | "name": "@threepipe/plugin-blend-importer", | ||||
| "version": "0.0.2", | |||||
| "version": "0.0.3", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-blend-importer", | "name": "@threepipe/plugin-blend-importer", | ||||
| "version": "0.0.2", | |||||
| "version": "0.0.3", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-blueprintjs", | "name": "@threepipe/plugin-blueprintjs", | ||||
| "version": "0.2.0", | |||||
| "version": "0.2.1", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-blueprintjs", | "name": "@threepipe/plugin-blueprintjs", | ||||
| "version": "0.2.0", | |||||
| "version": "0.2.1", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-configurator", | "name": "@threepipe/plugin-configurator", | ||||
| "version": "0.1.1", | |||||
| "version": "0.1.2", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-configurator", | "name": "@threepipe/plugin-configurator", | ||||
| "version": "0.1.1", | |||||
| "version": "0.1.2", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/", | "threepipe": "file:./../../src/", |
| { | { | ||||
| "name": "@threepipe/plugins-extra-importers", | "name": "@threepipe/plugins-extra-importers", | ||||
| "version": "0.2.0", | |||||
| "version": "0.2.1", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugins-extra-importers", | "name": "@threepipe/plugins-extra-importers", | ||||
| "version": "0.2.0", | |||||
| "version": "0.2.1", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-gaussian-splatting", | "name": "@threepipe/plugin-gaussian-splatting", | ||||
| "version": "0.2.1", | |||||
| "version": "0.2.2", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-gaussian-splatting", | "name": "@threepipe/plugin-gaussian-splatting", | ||||
| "version": "0.2.1", | |||||
| "version": "0.2.2", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-geometry-generator", | "name": "@threepipe/plugin-geometry-generator", | ||||
| "version": "0.3.0", | |||||
| "version": "0.3.1", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-geometry-generator", | "name": "@threepipe/plugin-geometry-generator", | ||||
| "version": "0.3.0", | |||||
| "version": "0.3.1", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-gltf-transform", | "name": "@threepipe/plugin-gltf-transform", | ||||
| "version": "0.1.0", | |||||
| "version": "0.1.1", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-gltf-transform", | "name": "@threepipe/plugin-gltf-transform", | ||||
| "version": "0.1.0", | |||||
| "version": "0.1.1", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-network", | "name": "@threepipe/plugin-network", | ||||
| "version": "0.1.0", | |||||
| "version": "0.1.1", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-network", | "name": "@threepipe/plugin-network", | ||||
| "version": "0.1.0", | |||||
| "version": "0.1.1", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "aws4fetch": "^1.0.18", | "aws4fetch": "^1.0.18", |
| { | { | ||||
| "name": "@threepipe/plugin-svg-renderer", | "name": "@threepipe/plugin-svg-renderer", | ||||
| "version": "0.2.1", | |||||
| "version": "0.2.2", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-svg-renderer", | "name": "@threepipe/plugin-svg-renderer", | ||||
| "version": "0.2.1", | |||||
| "version": "0.2.2", | |||||
| "license": "GPLV3", | "license": "GPLV3", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" |
| { | { | ||||
| "name": "@threepipe/plugin-tweakpane", | "name": "@threepipe/plugin-tweakpane", | ||||
| "version": "0.5.0", | |||||
| "version": "0.4.2", | |||||
| "lockfileVersion": 3, | "lockfileVersion": 3, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "@threepipe/plugin-tweakpane", | "name": "@threepipe/plugin-tweakpane", | ||||
| "version": "0.5.0", | |||||
| "version": "0.4.2", | |||||
| "license": "Apache-2.0", | "license": "Apache-2.0", | ||||
| "dependencies": { | "dependencies": { | ||||
| "threepipe": "file:./../../src/" | "threepipe": "file:./../../src/" | ||||
| }, | }, | ||||
| "devDependencies": { | "devDependencies": { | ||||
| "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | "tweakpane-image-plugin": "https://github.com/repalash/tweakpane-image-plugin/releases/download/v1.1.404/package.tgz", | ||||
| "uiconfig-tweakpane": "^0.0.10" | |||||
| } | |||||
| }, | |||||
| "../../../uiconfig-react/packages/uiconfig-tweakpane": { | |||||
| "version": "0.0.0", | |||||
| "extraneous": true, | |||||
| "devDependencies": { | |||||
| "typescript": "~5.6.2", | |||||
| "vite": "^6.0.3" | |||||
| "uiconfig-tweakpane": "^0.0.8" | |||||
| } | } | ||||
| }, | }, | ||||
| "../../src": {}, | "../../src": {}, | ||||
| "node_modules/@tweakpane/core": { | |||||
| "version": "1.1.8", | |||||
| "resolved": "https://registry.npmjs.org/@tweakpane/core/-/core-1.1.8.tgz", | |||||
| "integrity": "sha512-psvBf6Cbm3YSZOTmDFWkcGzHYMnw7gVZM3jw+TfbzErIC+sMXPQb85h4ayW04w2u7AGg8jD0gHXSCg5wd+rafg==", | |||||
| "dev": true | |||||
| }, | |||||
| "node_modules/@tweenjs/tween.js": { | "node_modules/@tweenjs/tween.js": { | ||||
| "version": "18.6.4", | "version": "18.6.4", | ||||
| "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", | "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", | ||||
| "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", | "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", | ||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| "dev": true | |||||
| }, | }, | ||||
| "node_modules/@types/stats.js": { | "node_modules/@types/stats.js": { | ||||
| "version": "0.17.3", | "version": "0.17.3", | ||||
| "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", | "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", | ||||
| "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", | "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", | ||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| "dev": true | |||||
| }, | }, | ||||
| "node_modules/@types/three": { | "node_modules/@types/three": { | ||||
| "version": "0.152.1", | "version": "0.152.1", | ||||
| "resolved": "https://registry.npmjs.org/@types/three/-/three-0.152.1.tgz", | "resolved": "https://registry.npmjs.org/@types/three/-/three-0.152.1.tgz", | ||||
| "integrity": "sha512-PMOCQnx9JRmq+2OUGTPoY9h1hTWD2L7/nmuW/SyNq1Vbq3Lwt3MNdl3wYSa4DvLTGv62NmIXD9jYdAOwohwJyw==", | "integrity": "sha512-PMOCQnx9JRmq+2OUGTPoY9h1hTWD2L7/nmuW/SyNq1Vbq3Lwt3MNdl3wYSa4DvLTGv62NmIXD9jYdAOwohwJyw==", | ||||
| "dev": true, | "dev": true, | ||||
| "license": "MIT", | |||||
| "dependencies": { | "dependencies": { | ||||
| "@tweenjs/tween.js": "~18.6.4", | "@tweenjs/tween.js": "~18.6.4", | ||||
| "@types/stats.js": "*", | "@types/stats.js": "*", | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/@types/webxr": { | "node_modules/@types/webxr": { | ||||
| "version": "0.5.20", | |||||
| "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.20.tgz", | |||||
| "integrity": "sha512-JGpU6qiIJQKUuVSKx1GtQnHJGxRjtfGIhzO2ilq43VZZS//f1h1Sgexbdk+Lq+7569a6EYhOWrUpIruR/1Enmg==", | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| "version": "0.5.12", | |||||
| "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.12.tgz", | |||||
| "integrity": "sha512-+6LV7bN17XUWy4wIMILsGQX6ucawf64lYLG9jaGKSvOnKaJzWjcKXAkO0dZaC8MfoEqYQC7gl1GQnfITjBcazw==", | |||||
| "dev": true | |||||
| }, | }, | ||||
| "node_modules/fflate": { | "node_modules/fflate": { | ||||
| "version": "0.6.10", | "version": "0.6.10", | ||||
| "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", | "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", | ||||
| "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", | "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", | ||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| "dev": true | |||||
| }, | }, | ||||
| "node_modules/lil-gui": { | "node_modules/lil-gui": { | ||||
| "version": "0.17.0", | "version": "0.17.0", | ||||
| "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.17.0.tgz", | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.17.0.tgz", | ||||
| "integrity": "sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==", | "integrity": "sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==", | ||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| "dev": true | |||||
| }, | }, | ||||
| "node_modules/threepipe": { | "node_modules/threepipe": { | ||||
| "resolved": "../../src", | "resolved": "../../src", | ||||
| "@tweakpane/core": "1.1.8" | "@tweakpane/core": "1.1.8" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/tweakpane-image-plugin/node_modules/@tweakpane/core": { | |||||
| "version": "1.1.8", | |||||
| "resolved": "https://registry.npmjs.org/@tweakpane/core/-/core-1.1.8.tgz", | |||||
| "integrity": "sha512-psvBf6Cbm3YSZOTmDFWkcGzHYMnw7gVZM3jw+TfbzErIC+sMXPQb85h4ayW04w2u7AGg8jD0gHXSCg5wd+rafg==", | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| }, | |||||
| "node_modules/uiconfig-tweakpane": { | "node_modules/uiconfig-tweakpane": { | ||||
| "version": "0.0.10", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig-tweakpane/-/uiconfig-tweakpane-0.0.10.tgz", | |||||
| "integrity": "sha512-VF67oUg7M9EXKR3IO+TXS6jP28qfT1ci/C4Inu8CjruJk8qBfUjuxKBU5kLXH97rE5dM0xLvLg/rYxRlpJ8mog==", | |||||
| "version": "0.0.8", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig-tweakpane/-/uiconfig-tweakpane-0.0.8.tgz", | |||||
| "integrity": "sha512-BZE/+6pW7qlywu4nhMjvzJ47IUORWn8rJsPpmcGqJgAz8G6MZjMXEW3Ey8EL41cVsDf5QSb0E/eTK8OWwuRfbA==", | |||||
| "dev": true, | "dev": true, | ||||
| "license": "MIT", | |||||
| "dependencies": { | "dependencies": { | ||||
| "@types/three": "^0.152.1", | "@types/three": "^0.152.1", | ||||
| "uiconfig.js": "^0.1.1" | |||||
| "uiconfig.js": "^0.0.8" | |||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/uiconfig.js": { | "node_modules/uiconfig.js": { | ||||
| "version": "0.1.1", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig.js/-/uiconfig.js-0.1.1.tgz", | |||||
| "integrity": "sha512-JzJyAgtFOfWVg964mmKKByULnhg4d5QpfsvXzj0T/Mncs1pK3/FACM+pAteLmT1xDeVDwwIU5s86UzlTiYwR/A==", | |||||
| "dev": true, | |||||
| "license": "MIT" | |||||
| "version": "0.0.8", | |||||
| "resolved": "https://registry.npmjs.org/uiconfig.js/-/uiconfig.js-0.0.8.tgz", | |||||
| "integrity": "sha512-0H1OO4CNHP5O0LBy82YWWFCzDK+Yf/GtXnR3i968FkMkf0+3/JsW7MC8ea2CcPtsi8ni4TA1FrMOC+KrYmMnCQ==", | |||||
| "dev": true | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| // if (ext.transparent !== undefined) o.transparent = ext.transparent // this is set by GLTFLoader based on alpha mode | // if (ext.transparent !== undefined) o.transparent = ext.transparent // this is set by GLTFLoader based on alpha mode | ||||
| if (ext.envMapIntensity !== undefined) o.envMapIntensity = ext.envMapIntensity // for when separateEnvMapIntensity is true | if (ext.envMapIntensity !== undefined) o.envMapIntensity = ext.envMapIntensity // for when separateEnvMapIntensity is true | ||||
| // if (ext.envMapSlotKey !== undefined) o.envMapSlotKey = ext.envMapSlotKey // in userdata | |||||
| // if (ext.stencilWrite !== undefined) o.stencilWrite = ext.stencilWrite | // if (ext.stencilWrite !== undefined) o.stencilWrite = ext.stencilWrite | ||||
| // if (ext.stencilWriteMask !== undefined) o.stencilWriteMask = ext.stencilWriteMask | // if (ext.stencilWriteMask !== undefined) o.stencilWriteMask = ext.stencilWriteMask | ||||
| if (material.alphaTest !== undefined) dat.alphaTest = material.alphaTest | if (material.alphaTest !== undefined) dat.alphaTest = material.alphaTest | ||||
| if (material.envMapIntensity !== undefined) dat.envMapIntensity = material.envMapIntensity // for when separateEnvMapIntensity is true | if (material.envMapIntensity !== undefined) dat.envMapIntensity = material.envMapIntensity // for when separateEnvMapIntensity is true | ||||
| // if (material.envMapSlotKey !== undefined) dat.envMapSlotKey = material.envMapSlotKey // in userData | |||||
| // if (material.stencilWrite !== undefined) dat.stencilWrite = material.stencilWrite | // if (material.stencilWrite !== undefined) dat.stencilWrite = material.stencilWrite | ||||
| // if (material.stencilWriteMask !== undefined) dat.stencilWriteMask = material.stencilWriteMask | // if (material.stencilWriteMask !== undefined) dat.stencilWriteMask = material.stencilWriteMask |
| */ | */ | ||||
| renderToDepth?: boolean | renderToDepth?: boolean | ||||
| // only for materials that have envMapIntensity | |||||
| /** | |||||
| * Flag to tell the scene to prefer `material.envMapIntensity` over `scene.envMapIntensity` | |||||
| * only for materials that have envMapIntensity | |||||
| */ | |||||
| separateEnvMapIntensity?: boolean // default: false | separateEnvMapIntensity?: boolean // default: false | ||||
| /** | |||||
| * The environment map to use in the `RootScene`. To use this, object with the material must be in the RootScene, and the key should exist in the `RootScene`'s `textureSlots`. | |||||
| * | |||||
| * only for materials that have envMap | |||||
| */ | |||||
| envMapSlotKey?: string | |||||
| cloneId?: string | cloneId?: string | ||||
| cloneCount?: number | cloneCount?: number |
| // hidden: ()=>!material.transparent && material.transmission < 0.001, | // hidden: ()=>!material.transparent && material.transmission < 0.001, | ||||
| getValue: ()=>material.userData.renderToGBuffer === true, | getValue: ()=>material.userData.renderToGBuffer === true, | ||||
| setValue: (v: boolean)=>{ | setValue: (v: boolean)=>{ | ||||
| material.userData.renderToGBuffer = v ? v : undefined | |||||
| if (!v && !material.userData.renderToGBuffer) return | |||||
| material.userData.renderToGBuffer = v | |||||
| material.setDirty() | |||||
| }, | |||||
| }, | |||||
| { | |||||
| type: 'checkbox', | |||||
| label: 'Render to Depth', | |||||
| hidden: ()=>material.userData.renderToDepth !== undefined, | |||||
| getValue: ()=>material.userData.renderToDepth === true, | |||||
| setValue: (v: boolean)=>{ | |||||
| if (!v && !material.userData.renderToDepth) return | |||||
| material.userData.renderToDepth = v | |||||
| material.setDirty() | material.setDirty() | ||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| } | } | ||||
| ), | ), | ||||
| environment: (material: IMaterial): UiObjectConfig => ( | |||||
| { | |||||
| type: 'folder', | |||||
| label: 'Environment', | |||||
| children: [ | |||||
| { | |||||
| type: 'checkbox', | |||||
| label: 'Override Environment', | |||||
| // property: [this.userData, 'separateEnvMapIntensity'], | |||||
| getValue: ()=>material.userData.separateEnvMapIntensity === true, | |||||
| setValue: (v: boolean)=>{ | |||||
| material.userData.separateEnvMapIntensity = v | |||||
| if (!v) delete material.userData.separateEnvMapIntensity | |||||
| }, | |||||
| // onChange: material.setDirty, | |||||
| }, | |||||
| { | |||||
| type: 'slider', | |||||
| bounds: [0, 20], | |||||
| hidden: ()=>!material.userData.separateEnvMapIntensity, | |||||
| label: 'Environment Intensity', | |||||
| property: [material, 'envMapIntensity'], | |||||
| }, | |||||
| { | |||||
| type: 'dropdown', | |||||
| hidden: ()=>!material.userData.separateEnvMapIntensity && !material.userData.envMapSlotKey, | |||||
| label: 'Environment Map', | |||||
| children: ['', 'environment1', 'environment2'].map((i)=>({label: i || 'default', value: i})), | |||||
| getValue: ()=>material.userData.envMapSlotKey || '', | |||||
| setValue: (v: string)=>{ | |||||
| material.userData.envMapSlotKey = v | |||||
| if (!v) delete material.userData.envMapSlotKey | |||||
| material.setDirty() | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| } | |||||
| ), | |||||
| misc: (material: IMaterial): UiObjectConfig[] => [ | misc: (material: IMaterial): UiObjectConfig[] => [ | ||||
| ()=>material.materialExtensions?.map(v=>{ | ()=>material.materialExtensions?.map(v=>{ | ||||
| v.uuid = v.uuid || generateUUID() | v.uuid = v.uuid || generateUUID() |
| iMaterialUI.bumpNormal(this), | iMaterialUI.bumpNormal(this), | ||||
| iMaterialUI.emission(this), | iMaterialUI.emission(this), | ||||
| iMaterialUI.transmission(this), | iMaterialUI.transmission(this), | ||||
| iMaterialUI.environment(this), | |||||
| iMaterialUI.clearcoat(this), | iMaterialUI.clearcoat(this), | ||||
| iMaterialUI.iridescence(this), | iMaterialUI.iridescence(this), | ||||
| iMaterialUI.sheen(this), | iMaterialUI.sheen(this), |
| iMaterialUI.blending(this), | iMaterialUI.blending(this), | ||||
| iMaterialUI.polygonOffset(this), | iMaterialUI.polygonOffset(this), | ||||
| iMaterialUI.aoLightMap(this), | iMaterialUI.aoLightMap(this), | ||||
| // iMaterialUI.environment(this), | |||||
| ...iMaterialUI.misc(this), | ...iMaterialUI.misc(this), | ||||
| ], | ], | ||||
| } | } |
| @serialize() @onChange2(RootScene.prototype._onEnvironmentChange) | @serialize() @onChange2(RootScene.prototype._onEnvironmentChange) | ||||
| environment: ITexture | null = null | environment: ITexture | null = null | ||||
| /** | |||||
| * Extra textures/envmaps that can be used by objects/materials/plugins and will be serialized. | |||||
| */ | |||||
| @serialize() | |||||
| public textureSlots: Record<string, ITexture> = {} | |||||
| /** | /** | ||||
| * The intensity for the environment light. | * The intensity for the environment light. | ||||
| */ | */ | ||||
| iObjectCommons.upgradeObject3D.call(this, undefined, objectProcessor) | iObjectCommons.upgradeObject3D.call(this, undefined, objectProcessor) | ||||
| // this is called from parentDispatch since scene is a parent. | // this is called from parentDispatch since scene is a parent. | ||||
| this.addEventListener('materialUpdate', ()=>this.dispatchEvent({type: 'sceneMaterialUpdate'})) | |||||
| this.addEventListener('materialUpdate', (e: any)=>this.dispatchEvent({...e, type: 'sceneMaterialUpdate'})) | |||||
| this.addEventListener('objectUpdate', this.refreshScene) | this.addEventListener('objectUpdate', this.refreshScene) | ||||
| this.addEventListener('geometryUpdate', this.refreshScene) | this.addEventListener('geometryUpdate', this.refreshScene) | ||||
| this.addEventListener('geometryChanged', this.refreshScene) | this.addEventListener('geometryChanged', this.refreshScene) | ||||
| } | } | ||||
| private _mainCameraUpdate = () => { | |||||
| private _mainCameraUpdate = (e: any) => { | |||||
| this.setDirty({refreshScene: false}) | this.setDirty({refreshScene: false}) | ||||
| this.refreshActiveCameraNearFar() | this.refreshActiveCameraNearFar() | ||||
| this.dispatchEvent({type: 'mainCameraUpdate'}) | |||||
| this.dispatchEvent({type: 'activeCameraUpdate'}) // deprecated | |||||
| this.dispatchEvent({...e, type: 'mainCameraUpdate'}) | |||||
| this.dispatchEvent({...e, type: 'activeCameraUpdate'}) // deprecated | |||||
| } | } | ||||
| // cached values | // cached values |
| import {AViewerPluginSync, ThreeViewer} from '../../viewer' | import {AViewerPluginSync, ThreeViewer} from '../../viewer' | ||||
| import {IGeometry, iGeometryCommons, IMaterial, ISceneEvent, Mesh2, PhysicalMaterial, UnlitMaterial} from '../../core' | |||||
| import {IGeometry, iGeometryCommons, IMaterial, ISceneEvent, Mesh2, PhysicalMaterial} from '../../core' | |||||
| import {BufferAttribute, BufferGeometry, Euler, InterleavedBufferAttribute, PlaneGeometry, Vector3} from 'three' | import {BufferAttribute, BufferGeometry, Euler, InterleavedBufferAttribute, PlaneGeometry, Vector3} from 'three' | ||||
| import {onChange, onChange2, serialize} from 'ts-browser-helpers' | import {onChange, onChange2, serialize} from 'ts-browser-helpers' | ||||
| import {OrbitControls3} from '../../three' | |||||
| import {bindToValue, OrbitControls3} from '../../three' | |||||
| import {uiConfig, uiFolderContainer, uiNumber, uiToggle} from 'uiconfig.js' | import {uiConfig, uiFolderContainer, uiNumber, uiToggle} from 'uiconfig.js' | ||||
| @uiFolderContainer('Ground') | @uiFolderContainer('Ground') | ||||
| export class BaseGroundPlugin<TEvent extends string = ''> extends AViewerPluginSync<TEvent> { | export class BaseGroundPlugin<TEvent extends string = ''> extends AViewerPluginSync<TEvent> { | ||||
| public static readonly PluginType: string = 'BaseGroundPlugin' | public static readonly PluginType: string = 'BaseGroundPlugin' | ||||
| public static readonly OldPluginType: string = 'Ground' | |||||
| get enabled() { | get enabled() { | ||||
| return this.visible | return this.visible | ||||
| @serialize('material') | @serialize('material') | ||||
| @uiConfig() | @uiConfig() | ||||
| @bindToValue({obj: 'mesh', key: 'material'}) | |||||
| protected _material?: PhysicalMaterial | protected _material?: PhysicalMaterial | ||||
| onAdded(viewer: ThreeViewer): void { | onAdded(viewer: ThreeViewer): void { | ||||
| protected _createMesh(mesh?: Mesh2<IGeometry&PlaneGeometry, IMaterial>): Mesh2<IGeometry&PlaneGeometry, IMaterial> { | protected _createMesh(mesh?: Mesh2<IGeometry&PlaneGeometry, IMaterial>): Mesh2<IGeometry&PlaneGeometry, IMaterial> { | ||||
| if (!mesh) mesh = new Mesh2(this._geometry, new UnlitMaterial()) | |||||
| if (!mesh) mesh = new Mesh2(this._geometry, this._createMaterial()) | |||||
| else mesh.geometry = this._geometry | else mesh.geometry = this._geometry | ||||
| if (mesh) { | if (mesh) { | ||||
| mesh.userData.physicsMass = 0 | mesh.userData.physicsMass = 0 | ||||
| if (!material) material = new PhysicalMaterial({ | if (!material) material = new PhysicalMaterial({ | ||||
| name: 'BaseGroundMaterial', | name: 'BaseGroundMaterial', | ||||
| color: 0xffffff, | color: 0xffffff, | ||||
| roughness: 0.8, | |||||
| metalness: 0.5, | |||||
| }) | }) | ||||
| material.userData.runtimeMaterial = true | material.userData.runtimeMaterial = true | ||||
| return material | return material | ||||
| if (!this._viewer) return false | if (!this._viewer) return false | ||||
| if (this.isDisabled()) return false | if (this.isDisabled()) return false | ||||
| const mat = this._material ?? this._createMaterial() | const mat = this._material ?? this._createMaterial() | ||||
| const isNewMaterial = mat !== this._material | |||||
| const isNewMaterial = this._mesh.material !== this._material | |||||
| if (isNewMaterial) { // new material | if (isNewMaterial) { // new material | ||||
| this._removeMaterial() | |||||
| // this._removeMaterial() | |||||
| this._material = mat | this._material = mat | ||||
| const id = this._material?.uuid | |||||
| if (!id) console.warn('No material found for ground') | |||||
| // const id = this._material?.uuid | |||||
| // if (!id) console.warn('No material found for ground') | |||||
| this._viewer.scene.setDirty() | this._viewer.scene.setDirty() | ||||
| if (this._mesh && this._material) { | |||||
| this._material.roughness = 0.2 | |||||
| this._material.metalness = 0.5 | |||||
| this._mesh.material = this._material // for update event handlers. | |||||
| } | |||||
| // if (this._mesh && this._material) { | |||||
| // this._mesh.material = this._material // must be set even if same, for update event handlers. | |||||
| // } | |||||
| } | } | ||||
| if (this._material) { | if (this._material) { | ||||
| if (this._material.userData.__renderToDepth === undefined) { | if (this._material.userData.__renderToDepth === undefined) { |
| private _mainCameraUpdate = (e: any)=>{ | private _mainCameraUpdate = (e: any)=>{ | ||||
| if (this.isDisabled()) return | if (this.isDisabled()) return | ||||
| if (e.change === 'deserialize') { | |||||
| this.stopAnimation() | |||||
| if (e.change === 'deserialize' && this.animationRunning) { | |||||
| this.stopAnimation({reset: false}) // reset is false so that the new camera position is not reset | |||||
| this.startAnimation() | this.startAnimation() | ||||
| } else { | } else { | ||||
| this.lastActionTime = now() | this.lastActionTime = now() |
| } | } | ||||
| protected _createPass() { | protected _createPass() { | ||||
| return new FrameFadeBlendPass(this.passId, this) | |||||
| return new FrameFadeBlendPass(this.passId, this, this._viewer?.renderManager.maxHDRIntensity) | |||||
| } | } | ||||
| get canFrameFade() { | get canFrameFade() { | ||||
| required = ['render', 'progressive'] | required = ['render', 'progressive'] | ||||
| dirty: ValOrFunc<boolean> = () => false | dirty: ValOrFunc<boolean> = () => false | ||||
| fadeTime = 0 // ms | fadeTime = 0 // ms | ||||
| fadeTimeState = 0 | fadeTimeState = 0 | ||||
| toSaveFrame = false | toSaveFrame = false | ||||
| private _lastTime = 0 | private _lastTime = 0 | ||||
| constructor(public readonly passId: IPassID, public plugin: FrameFadePlugin) { | |||||
| super() | |||||
| constructor(public readonly passId: IPassID, public plugin: FrameFadePlugin, maxIntensity = 120) { | |||||
| super(undefined, maxIntensity) | |||||
| } | } | ||||
| render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) { | render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) { | ||||
| this.needsSwap = false | this.needsSwap = false | ||||
| const target = this.plugin.target | const target = this.plugin.target |
| protected _createPass() { | protected _createPass() { | ||||
| // this._createTarget(true) | // this._createTarget(true) | ||||
| const pass = new ProgressiveBlendPass(this.passId, ()=>this.target ?? this._createTarget()) // todo: disposeTarget somewhere | |||||
| const pass = new ProgressiveBlendPass(this.passId, ()=>this.target ?? this._createTarget(), this._viewer?.renderManager.maxHDRIntensity) // todo: disposeTarget somewhere | |||||
| pass.dirty = () => (this._viewer?.renderManager.frameCount || 0) < this.maxFrameCount // todo use isConverged function | pass.dirty = () => (this._viewer?.renderManager.frameCount || 0) < this.maxFrameCount // todo use isConverged function | ||||
| return pass | return pass | ||||
| } | } | ||||
| after = ['render'] | after = ['render'] | ||||
| required = ['render'] | required = ['render'] | ||||
| dirty: ValOrFunc<boolean> = () => false | dirty: ValOrFunc<boolean> = () => false | ||||
| constructor(public readonly passId: IPassID, public target?: ValOrFunc<WebGLRenderTarget|undefined>) { | |||||
| super() | |||||
| constructor(public readonly passId: IPassID, public target?: ValOrFunc<WebGLRenderTarget|undefined>, maxIntensity = 120) { | |||||
| super(undefined, maxIntensity) | |||||
| } | } | ||||
| render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) { | render(renderer: IWebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean) { | ||||
| if (!this.enabled) return | if (!this.enabled) return |
| #ifdef GBUFFER_HAS_FLAGS | #ifdef GBUFFER_HAS_FLAGS | ||||
| doTonemap = getToneMapBit(getGBufferFlags(vUv).a) > 0; | doTonemap = getToneMapBit(getGBufferFlags(vUv).a) > 0; | ||||
| #endif | #endif | ||||
| #if TONEMAP_BACKGROUND < 1 | |||||
| #if TONEMAP_BACKGROUND < 1 // todo - || (defined(CLIP_BACKGROUND) && CLIP_BACKGROUND > 0) || defined(CLIP_BACKGROUND_FORCE) | |||||
| if(isBackground) doTonemap = false; // isBackground defined in ScreenPass | if(isBackground) doTonemap = false; // isBackground defined in ScreenPass | ||||
| #endif | #endif | ||||
| #endif | #endif |
| import {glsl} from 'ts-browser-helpers' | import {glsl} from 'ts-browser-helpers' | ||||
| export class AddBlendTexturePass extends ExtendedShaderPass implements IPass { | export class AddBlendTexturePass extends ExtendedShaderPass implements IPass { | ||||
| constructor(texture?: Texture) { | |||||
| constructor(texture?: Texture, maxIntensity = 120) { | |||||
| super({ | super({ | ||||
| vertexShader: CopyShader.vertexShader, | vertexShader: CopyShader.vertexShader, | ||||
| fragmentShader: glsl` | fragmentShader: glsl` | ||||
| uniform vec4 weight2; | uniform vec4 weight2; | ||||
| varying vec2 vUv; | varying vec2 vUv; | ||||
| void main() { | void main() { | ||||
| vec4 texel = clamp(weight * tDiffuseTexelToLinear ( texture2D( tDiffuse, vUv ) ) + weight2 * tDiffuse2TexelToLinear ( texture2D( tDiffuse2, vUv ) ), vec4(0), vec4(8)); | |||||
| vec4 texel = clamp(weight * tDiffuseTexelToLinear ( texture2D( tDiffuse, vUv ) ) + weight2 * tDiffuse2TexelToLinear ( texture2D( tDiffuse2, vUv ) ), vec4(0), vec4(MAX_INTENSITY)); | |||||
| gl_FragColor = texel; | gl_FragColor = texel; | ||||
| #include <encodings_fragment> | #include <encodings_fragment> | ||||
| } | } | ||||
| 'weight': {value: new Vector4(1, 1, 1, 1)}, | 'weight': {value: new Vector4(1, 1, 1, 1)}, | ||||
| 'weight2': {value: new Vector4(1, 1, 1, 1)}, | 'weight2': {value: new Vector4(1, 1, 1, 1)}, | ||||
| }, | }, | ||||
| defines: { | |||||
| ['MAX_INTENSITY']: maxIntensity, | |||||
| }, | |||||
| }, 'tDiffuse', 'tDiffuse2') | }, 'tDiffuse', 'tDiffuse2') | ||||
| this.clear = false | this.clear = false | ||||
| this.needsSwap = true | this.needsSwap = true |
| constructor(renderManager: ViewerRenderManager, overrideMaterial?: Material, clearColor = new Color(0, 0, 0), clearAlpha = 0) { | constructor(renderManager: ViewerRenderManager, overrideMaterial?: Material, clearColor = new Color(0, 0, 0), clearAlpha = 0) { | ||||
| super(undefined, undefined, overrideMaterial, clearColor, clearAlpha) | super(undefined, undefined, overrideMaterial, clearColor, clearAlpha) | ||||
| this.renderManager = renderManager | this.renderManager = renderManager | ||||
| this._blendPass = new GenericBlendTexturePass({}, 'c = vec4(a.rgb * (1. - b.a) + b.rgb * b.a, 1.);') | |||||
| this._blendPass = new GenericBlendTexturePass({}, 'c = vec4(a.rgb * (1. - b.a) + b.rgb * b.a, 1.);', '', undefined, renderManager.maxHDRIntensity) | |||||
| this.setDirty = this.setDirty.bind(this) | this.setDirty = this.setDirty.bind(this) | ||||
| } | } | ||||
| renderToGBuffer = renderToGBuffer ?? material.userData.renderToGBuffer | renderToGBuffer = renderToGBuffer ?? material.userData.renderToGBuffer | ||||
| if (material.userData.pluginsDisabled) renderToGBuffer = false | if (material.userData.pluginsDisabled) renderToGBuffer = false | ||||
| if ( | if ( | ||||
| material.transparent && (renderToGBuffer || material.opacity > 0.99) || // transparent and render to gbuffer | |||||
| material.transparent && (renderToGBuffer || material.opacity > 0.99 && !material.map && !material.alphaMap) || // transparent and render to gbuffer | |||||
| !material.transparent && !material.transmission && renderToGBuffer === false // opaque and dont render to gbuffer | !material.transparent && !material.transmission && renderToGBuffer === false // opaque and dont render to gbuffer | ||||
| ) { | ) { | ||||
| this._transparentMats.add(material) | this._transparentMats.add(material) |
| import {IPass} from './Pass' | import {IPass} from './Pass' | ||||
| export class GenericBlendTexturePass extends ExtendedShaderPass implements IPass { | export class GenericBlendTexturePass extends ExtendedShaderPass implements IPass { | ||||
| constructor(uniforms: {[uniform: string]: IUniform}, blendFunc = 'c = a + b;', extraFrag = '', texture?: Texture) { | |||||
| constructor(uniforms: {[uniform: string]: IUniform}, blendFunc = 'c = a + b;', extraFrag = '', texture?: Texture, maxIntensity = 120) { | |||||
| super({ | super({ | ||||
| vertexShader: CopyShader.vertexShader, | vertexShader: CopyShader.vertexShader, | ||||
| fragmentShader: ` | fragmentShader: ` | ||||
| vec4 b = tDiffuse2TexelToLinear ( texture2D( tDiffuse2, vUv ) ); | vec4 b = tDiffuse2TexelToLinear ( texture2D( tDiffuse2, vUv ) ); | ||||
| vec4 c = vec4(0); | vec4 c = vec4(0); | ||||
| ${blendFunc} | ${blendFunc} | ||||
| c = clamp(c, vec4(0), vec4(8)); | |||||
| c = clamp(c, vec4(0), vec4(MAX_INTENSITY)); | |||||
| gl_FragColor = c; | gl_FragColor = c; | ||||
| #include <encodings_fragment> | #include <encodings_fragment> | ||||
| } | } | ||||
| 'tDiffuse2': {value: texture}, | 'tDiffuse2': {value: texture}, | ||||
| ...uniforms, | ...uniforms, | ||||
| }, | }, | ||||
| defines: { | |||||
| ['MAX_INTENSITY']: maxIntensity, | |||||
| }, | |||||
| }, 'tDiffuse', 'tDiffuse2') | }, 'tDiffuse', 'tDiffuse2') | ||||
| this.clear = false | this.clear = false | ||||
| this.needsSwap = true | this.needsSwap = true |
| @matDefineBool('CLIP_BACKGROUND_FORCE', undefined, undefined, ScreenPass.prototype.setDirty, true) | @matDefineBool('CLIP_BACKGROUND_FORCE', undefined, undefined, ScreenPass.prototype.setDirty, true) | ||||
| clipBackgroundForce = false | clipBackgroundForce = false | ||||
| // todo: this is not serialized anymore? | |||||
| // todo: this is not serialized anymore? we should serialize this in some plugin... | |||||
| @matDefineBool('CLIP_BACKGROUND', undefined, undefined, ScreenPass.prototype.setDirty) | @matDefineBool('CLIP_BACKGROUND', undefined, undefined, ScreenPass.prototype.setDirty) | ||||
| @uiToggle() clipBackground = false | @uiToggle() clipBackground = false | ||||
| target?: Vector3, | target?: Vector3, | ||||
| } | } | ||||
| // values above this might be clamped in post processing | |||||
| maxHDRIntensity?: number | |||||
| /** | /** | ||||
| * Options for the asset manager. | * Options for the asset manager. | ||||
| renderScale: typeof options.renderScale === 'string' ? options.renderScale === 'auto' ? | renderScale: typeof options.renderScale === 'string' ? options.renderScale === 'auto' ? | ||||
| Math.min(2, window.devicePixelRatio) : parseFloat(options.renderScale) : | Math.min(2, window.devicePixelRatio) : parseFloat(options.renderScale) : | ||||
| options.renderScale, | options.renderScale, | ||||
| maxHDRIntensity: options.maxHDRIntensity, | |||||
| }) | }) | ||||
| this.renderManager.addEventListener('animationLoop', this._animationLoop as any) | this.renderManager.addEventListener('animationLoop', this._animationLoop as any) | ||||
| this.renderManager.addEventListener('resize', ()=> this._scene.mainCamera.refreshAspect()) | this.renderManager.addEventListener('resize', ()=> this._scene.mainCamera.refreshAspect()) |
| import {IRenderTarget, RenderManager} from '../rendering' | import {IRenderTarget, RenderManager} from '../rendering' | ||||
| import {HalfFloatType, LinearMipMapLinearFilter, NoColorSpace, RGBM16ColorSpace, UnsignedByteType} from 'three' | |||||
| import { | |||||
| HalfFloatType, | |||||
| LinearFilter, | |||||
| LinearMipMapLinearFilter, | |||||
| NoColorSpace, | |||||
| RGBM16ColorSpace, | |||||
| UnsignedByteType, | |||||
| } from 'three' | |||||
| import {IRenderManagerEvent, IRenderManagerOptions, IScene} from '../core' | import {IRenderManagerEvent, IRenderManagerOptions, IScene} from '../core' | ||||
| import {ExtendedRenderPass, ScreenPass, TViewerScreenShader} from '../postprocessing' | import {ExtendedRenderPass, ScreenPass, TViewerScreenShader} from '../postprocessing' | ||||
| import {uiFolderContainer, UiObjectConfig} from 'uiconfig.js' | import {uiFolderContainer, UiObjectConfig} from 'uiconfig.js' | ||||
| depthBuffer?: boolean, | depthBuffer?: boolean, | ||||
| zPrepass?: boolean, | zPrepass?: boolean, | ||||
| screenShader?: TViewerScreenShader | screenShader?: TViewerScreenShader | ||||
| maxHDRIntensity?: number | |||||
| } | } | ||||
| @uiFolderContainer('Render Manager') | @uiFolderContainer('Render Manager') | ||||
| readonly msaa: boolean | number | readonly msaa: boolean | number | ||||
| readonly depthBuffer: boolean | readonly depthBuffer: boolean | ||||
| readonly zPrepass: boolean | readonly zPrepass: boolean | ||||
| readonly maxHDRIntensity: number | |||||
| readonly renderPass: ExtendedRenderPass | readonly renderPass: ExtendedRenderPass | ||||
| readonly screenPass: ScreenPass | readonly screenPass: ScreenPass | ||||
| declare uiConfig: UiObjectConfig | declare uiConfig: UiObjectConfig | ||||
| colorSpace: rgbm ? RGBM16ColorSpace : NoColorSpace, | colorSpace: rgbm ? RGBM16ColorSpace : NoColorSpace, | ||||
| type: rgbm ? UnsignedByteType : HalfFloatType, | type: rgbm ? UnsignedByteType : HalfFloatType, | ||||
| depthBuffer: depthBuffer, | depthBuffer: depthBuffer, | ||||
| generateMipmaps: msaa ? true : undefined, // todo: hack for now, fix blurTransmissionTarget in ExtendedRenderPass | |||||
| minFilter: msaa ? LinearMipMapLinearFilter : undefined, // todo: hack for now, fix blurTransmissionTarget in ExtendedRenderPass | |||||
| generateMipmaps: msaa ? true : false, // todo: hack for now, fix blurTransmissionTarget in ExtendedRenderPass | |||||
| minFilter: msaa ? LinearMipMapLinearFilter : LinearFilter, // todo: hack for now, fix blurTransmissionTarget in ExtendedRenderPass | |||||
| }, | }, | ||||
| }) | }) | ||||
| this.rgbm = rgbm | this.rgbm = rgbm | ||||
| this.msaa = msaa && this.isWebGL2 | this.msaa = msaa && this.isWebGL2 | ||||
| this.depthBuffer = depthBuffer | this.depthBuffer = depthBuffer | ||||
| this.zPrepass = options.zPrepass || false | this.zPrepass = options.zPrepass || false | ||||
| this.maxHDRIntensity = options.maxHDRIntensity ?? (rgbm ? 16 : 72) | |||||
| let doTransmissionFix = true // const for debugging, todo could be made into a static prop maybe? | let doTransmissionFix = true // const for debugging, todo could be made into a static prop maybe? | ||||
| if (!this._renderer.userData) { | if (!this._renderer.userData) { |