Quellcode durchsuchen

Add maxHDRIntensity, textureSlots, envMapSlotKey, fix material update options, fix material in ground, fix animation in interaction prompt on deserialize, some fixes

master
Palash Bansal vor 1 Jahr
Ursprung
Commit
0273cf862f
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden

+ 1034
- 3019
package-lock.json
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1
- 1
package.json Datei anzeigen

"@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": {

+ 2
- 2
plugins/blend-importer/package-lock.json Datei anzeigen

{ {
"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/"

+ 2
- 2
plugins/blueprintjs/package-lock.json Datei anzeigen

{ {
"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/"

+ 2
- 2
plugins/configurator/package-lock.json Datei anzeigen

{ {
"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/",

+ 2
- 2
plugins/extra-importers/package-lock.json Datei anzeigen

{ {
"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/"

+ 2
- 2
plugins/gaussian-splatting/package-lock.json Datei anzeigen

{ {
"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/"

+ 2
- 2
plugins/geometry-generator/package-lock.json Datei anzeigen

{ {
"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/"

+ 2
- 2
plugins/gltf-transform/package-lock.json Datei anzeigen

{ {
"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/"

+ 2
- 2
plugins/network/package-lock.json Datei anzeigen

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

+ 2
- 2
plugins/svg-renderer/package-lock.json Datei anzeigen

{ {
"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/"

+ 25
- 42
plugins/tweakpane/package-lock.json Datei anzeigen

{ {
"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
} }
} }
} }

+ 2
- 0
src/assetmanager/gltf/GLTFMaterialExtrasExtension.ts Datei anzeigen

// 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

+ 10
- 1
src/core/IMaterial.ts Datei anzeigen

*/ */
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

+ 51
- 1
src/core/material/IMaterialUi.ts Datei anzeigen

// 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()

+ 1
- 0
src/core/material/PhysicalMaterial.ts Datei anzeigen

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

+ 1
- 0
src/core/material/UnlitMaterial.ts Datei anzeigen

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),
], ],
} }

+ 9
- 4
src/core/object/RootScene.ts Datei anzeigen

@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

+ 14
- 12
src/plugins/base/BaseGroundPlugin.ts Datei anzeigen

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

+ 2
- 2
src/plugins/interaction/InteractionPromptPlugin.ts Datei anzeigen



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()

+ 4
- 5
src/plugins/pipeline/FrameFadePlugin.ts Datei anzeigen

} }


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

+ 3
- 3
src/plugins/pipeline/ProgressivePlugin.ts Datei anzeigen



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

+ 1
- 1
src/plugins/postprocessing/shaders/TonemapPlugin.patch.glsl Datei anzeigen

#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

+ 5
- 2
src/postprocessing/AddBlendTexturePass.ts Datei anzeigen

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

+ 1
- 1
src/postprocessing/ExtendedRenderPass.ts Datei anzeigen

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



+ 1
- 1
src/postprocessing/GBufferRenderPass.ts Datei anzeigen

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)

+ 5
- 2
src/postprocessing/GenericBlendTexturePass.ts Datei anzeigen

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

+ 1
- 1
src/postprocessing/ScreenPass.ts Datei anzeigen

@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



+ 4
- 0
src/viewer/ThreeViewer.ts Datei anzeigen

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())

+ 13
- 3
src/viewer/ViewerRenderManager.ts Datei anzeigen

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

Laden…
Abbrechen
Speichern