Procházet zdrojové kódy

Add msaa transmission test, Add multi viewer test, Add LegacyPhongMaterial, Allow custom numeric samples in msaa, temporary fix for transmission not working with msaa, circular import fixes, stats.js position fix, disable debug by default in ThreeViewer.

master
Palash Bansal před 2 roky
rodič
revize
0c4d6ea549
Žádný účet není propojen s e-mailovou adresou tvůrce revize

+ 2
- 2
README.md Zobrazit soubor

Threepipe includes several built-in materials like Threepipe includes several built-in materials like
[PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html), [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html),
[UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html), [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html),
[ExtendedShaderMaterial](https://threepipe.org/docs/classes/ExtendedShaderMaterial.html)
[ExtendedShaderMaterial](https://threepipe.org/docs/classes/ExtendedShaderMaterial.html), [LegacyPhongMaterial](https://threepipe.org/docs/classes/LegacyPhongMaterial.html),
that include support for extending the material. that include support for extending the material.
Any three.js material can be made extendable, Any three.js material can be made extendable,
check the `ShaderPass2` class for a simple example that adds support for material extension to three.js ShaderPass. check the `ShaderPass2` class for a simple example that adds support for material extension to three.js ShaderPass.


Example: https://threepipe.org/examples/#camera-view-plugin/ Example: https://threepipe.org/examples/#camera-view-plugin/


Source Code: [src/plugins/animation/CameraViewPlugin.ts](./src/plugins/ui/RenderTargetPreviewPlugin.ts)
Source Code: [src/plugins/animation/CameraViewPlugin.ts](./src/plugins/animation/CameraViewPlugin.ts)


API Reference: [CameraViewPlugin](https://threepipe.org/docs/classes/CameraViewPlugin.html) API Reference: [CameraViewPlugin](https://threepipe.org/docs/classes/CameraViewPlugin.html)



+ 36
- 0
examples/gltf-transmission-test-msaa/index.html Zobrazit soubor

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GLTF Transmission Test (MSAA)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 52
- 0
examples/gltf-transmission-test-msaa/script.ts Zobrazit soubor

import {_testFinish, IObject3D, RenderTargetPreviewPlugin, ThreeViewer} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
rgbm: true,
zPrepass: false,
})

async function init() {

const targetPreview = viewer.addPluginSync(RenderTargetPreviewPlugin)
targetPreview.addTarget(()=>viewer.renderManager.composerTarget, 'composer-1', false, false)
viewer.renderManager.renderPass.preserveTransparentTarget = true
targetPreview.addTarget(()=>viewer.renderManager.renderPass.transparentTarget, 'transparent', true, true)
targetPreview.addTarget(()=>viewer.renderManager.composerTarget2, 'composer-2', false, false)

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
const [model, model2] = await Promise.all([
viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/IridescenceLamp.glb', {
autoCenter: true,
autoScale: true,
}),
viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/IridescentDishWithOlives.glb', {
autoCenter: true,
autoScale: true,
}),
])

if (!model || !model2) {
console.error('model not loaded')
return
}
model.position.x = -1
model2.position.x = 1
model2.position.y = -1.2

const ui = viewer.addPluginSync(new TweakpaneUiPlugin(false))

const m1 = model?.getObjectByName('lamp_transmission')
const m2 = model2?.getObjectByName('glassCover')
const materials = [...m1?.materials || [], ...m2?.materials || []]
for (const material of materials) {
const config = material.uiConfig
if (!config) continue
ui.appendChild(config)
}

}

init().then(_testFinish)

+ 2
- 0
examples/index.html Zobrazit soubor

</ul> </ul>
<h2 class="category">Tests</h2> <h2 class="category">Tests</h2>
<ul> <ul>
<li><a href="./multi-viewer-test/">Multiple Viewers Test </a></li>
<li><a href="./gltf-transmission-test/">glTF Transmission Test </a></li> <li><a href="./gltf-transmission-test/">glTF Transmission Test </a></li>
<li><a href="./gltf-transmission-test-msaa/">glTF Transmission Test + MSAA </a></li>
<li><a href="./uint8-rgbm-hdr-test/">Uint8 RGBM HDR Test </a></li> <li><a href="./uint8-rgbm-hdr-test/">Uint8 RGBM HDR Test </a></li>
<li><a href="./half-float-hdr-test/">Half-float HDR Test </a></li> <li><a href="./half-float-hdr-test/">Half-float HDR Test </a></li>
<li><a href="./sphere-rgbm-test/">RGBM Test </a></li> <li><a href="./sphere-rgbm-test/">RGBM Test </a></li>

+ 57
- 0
examples/multi-viewer-test/index.html Zobrazit soubor

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Multiple Viewers Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, .mcanvas, .container {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
.container{
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.canvas-container{
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
outline: 1px solid #464646;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div class="container">
<div class="canvas-container">
<canvas id="mcanvas1" class="mcanvas"></canvas>
</div>
<div class="canvas-container">
<canvas id="mcanvas2" class="mcanvas"></canvas>
</div>
<div class="canvas-container">
<canvas id="mcanvas3" class="mcanvas"></canvas>
</div>
<div class="canvas-container">
<canvas id="mcanvas4" class="mcanvas"></canvas>
</div>
</div>
</body>

+ 37
- 0
examples/multi-viewer-test/script.ts Zobrazit soubor

import {_testFinish, ThreeViewer} from 'threepipe'

const models = [
'https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf',
'https://threejs.org/examples/models/fbx/Samba Dancing.fbx',
'https://threejs.org/examples/models/draco/bunny.drc',
'https://threejs.org/examples/models/gltf/kira.glb',
]

async function init(i: number) {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas' + (i + 1)) as HTMLCanvasElement,
msaa: true,
debug: true,
dropzone: {
allowedExtensions: ['gltf', 'glb', 'hdr', 'bin', 'png', 'jpeg', 'webp', 'jpg', 'exr'],
addOptions: {
disposeSceneObjects: true,
autoSetEnvironment: true, // when hdr is dropped
autoSetBackground: true,
},
},
})

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
// setBackground: true,
})
const result = await viewer.load(models[i], {
autoCenter: true,
autoScale: true,
})
console.log(result)

}

Promise.all(new Array(4).fill(0).map(async(_, i) => init(i))).then(_testFinish)

+ 6
- 6
package-lock.json Zobrazit soubor

"version": "0.0.14", "version": "0.0.14",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1017/package.tgz",
"@types/webxr": "^0.5.1", "@types/webxr": "^0.5.1",
"@types/wicg-file-system-access": "^2020.9.5", "@types/wicg-file-system-access": "^2020.9.5",
"ts-browser-helpers": "^0.8.0" "ts-browser-helpers": "^0.8.0"
"dev": true "dev": true
}, },
"node_modules/@types/three": { "node_modules/@types/three": {
"version": "0.152.1016",
"resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"integrity": "sha512-S4AczoUaWTfyh7ApgEXZWhhusqF9DGX8ynfIa8OzS0+ES0DmD1UQuyVQUmwOTxgTDGO10vc7zWrObZGPvM88NQ==",
"version": "0.152.1017",
"resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1017/package.tgz",
"integrity": "sha512-iRThz0XfSleoy53jfLfos5bC1EyWc2dNrxXglVnIYU3ducMSjwS3iAdZehmlGMmiIpz3l1fc3xBpVOO4F8Z/Iw==",
"dependencies": { "dependencies": {
"@tweenjs/tween.js": "~18.6.4", "@tweenjs/tween.js": "~18.6.4",
"fflate": "~0.6.9", "fflate": "~0.6.9",
"dev": true "dev": true
}, },
"@types/three": { "@types/three": {
"version": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"integrity": "sha512-S4AczoUaWTfyh7ApgEXZWhhusqF9DGX8ynfIa8OzS0+ES0DmD1UQuyVQUmwOTxgTDGO10vc7zWrObZGPvM88NQ==",
"version": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1017/package.tgz",
"integrity": "sha512-iRThz0XfSleoy53jfLfos5bC1EyWc2dNrxXglVnIYU3ducMSjwS3iAdZehmlGMmiIpz3l1fc3xBpVOO4F8Z/Iw==",
"requires": { "requires": {
"@tweenjs/tween.js": "~18.6.4", "@tweenjs/tween.js": "~18.6.4",
"fflate": "~0.6.9", "fflate": "~0.6.9",

+ 4
- 4
package.json Zobrazit soubor

{ {
"name": "threepipe", "name": "threepipe",
"version": "0.0.14",
"version": "0.0.15",
"description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.", "description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.",
"main": "src/index.ts", "main": "src/index.ts",
"module": "dist/index.mjs", "module": "dist/index.mjs",
"popmotion": "^11.0.5" "popmotion": "^11.0.5"
}, },
"dependencies": { "dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1017/package.tgz",
"@types/webxr": "^0.5.1", "@types/webxr": "^0.5.1",
"@types/wicg-file-system-access": "^2020.9.5", "@types/wicg-file-system-access": "^2020.9.5",
"ts-browser-helpers": "^0.8.0" "ts-browser-helpers": "^0.8.0"
"ts-browser-helpers": "^0.8.0", "ts-browser-helpers": "^0.8.0",
"three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz", "three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2015/package.tgz",
"three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.152.2015.tar.gz", "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.152.2015.tar.gz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1016/package.tgz",
"@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.152.1016.tar.gz",
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1017/package.tgz",
"@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.152.1017.tar.gz",
"@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three" "@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three"
}, },
"local_dependencies": { "local_dependencies": {

+ 3
- 1
src/assetmanager/MaterialManager.ts Zobrazit soubor

import {downloadFile} from 'ts-browser-helpers' import {downloadFile} from 'ts-browser-helpers'
import {MaterialExtension} from '../materials' import {MaterialExtension} from '../materials'
import {generateUUID, isInScene} from '../three' import {generateUUID, isInScene} from '../three'
import {LegacyPhongMaterial} from '../core/material/LegacyPhongMaterial'


/** /**
* Material Manager * Material Manager
readonly templates: IMaterialTemplate[] = [ readonly templates: IMaterialTemplate[] = [
PhysicalMaterial.MaterialTemplate, PhysicalMaterial.MaterialTemplate,
UnlitMaterial.MaterialTemplate, UnlitMaterial.MaterialTemplate,
LegacyPhongMaterial.MaterialTemplate,
] ]


private _materials: IMaterial[] = [] private _materials: IMaterial[] = []
while (!template.generator) { // looping so that we can inherit templates, not fully implemented yet while (!template.generator) { // looping so that we can inherit templates, not fully implemented yet
const t2 = this.findTemplate(template.materialType) // todo add a baseTemplate property to the template? const t2 = this.findTemplate(template.materialType) // todo add a baseTemplate property to the template?
if (!t2) { if (!t2) {
console.error('Template has no generator or materialType', template, nameOrType)
console.warn('Template has no generator or materialType', template, nameOrType)
return undefined return undefined
} }
template = {...template, ...t2} template = {...template, ...t2}

+ 1
- 1
src/core/IRenderer.ts Zobrazit soubor

alpha?: boolean, // default = true alpha?: boolean, // default = true
targetOptions?: CreateRenderTargetOptions targetOptions?: CreateRenderTargetOptions
rgbm?: boolean, rgbm?: boolean,
msaa?: boolean,
msaa?: boolean | number,
depthBuffer?: boolean, depthBuffer?: boolean,
renderScale?: number, renderScale?: number,
} }

+ 1
- 0
src/core/index.ts Zobrazit soubor

export {PhysicalMaterial, type PhysicalMaterialEventTypes, MeshStandardMaterial2} from './material/PhysicalMaterial' export {PhysicalMaterial, type PhysicalMaterialEventTypes, MeshStandardMaterial2} from './material/PhysicalMaterial'
export {ShaderMaterial2} from './material/ShaderMaterial2' export {ShaderMaterial2} from './material/ShaderMaterial2'
export {UnlitMaterial, type UnlitMaterialEventTypes, MeshBasicMaterial2} from './material/UnlitMaterial' export {UnlitMaterial, type UnlitMaterialEventTypes, MeshBasicMaterial2} from './material/UnlitMaterial'
export {LegacyPhongMaterial, type PhongMaterialEventTypes} from './material/LegacyPhongMaterial'
export {iObjectCommons} from './object/iObjectCommons' export {iObjectCommons} from './object/iObjectCommons'
export {iCameraCommons} from './object/iCameraCommons' export {iCameraCommons} from './object/iCameraCommons'
export {iGeometryCommons} from './geometry/iGeometryCommons' export {iGeometryCommons} from './geometry/iGeometryCommons'

+ 3
- 2
src/core/material/IMaterialUi.ts Zobrazit soubor

import {downloadBlob, uploadFile} from 'ts-browser-helpers' import {downloadBlob, uploadFile} from 'ts-browser-helpers'
import {PhysicalMaterial} from './PhysicalMaterial' import {PhysicalMaterial} from './PhysicalMaterial'
import {getEmptyMeta} from '../../utils/serialization' import {getEmptyMeta} from '../../utils/serialization'
import {LegacyPhongMaterial} from './LegacyPhongMaterial'


export const iMaterialUI = { export const iMaterialUI = {
base: (material: IMaterial): UiObjectConfig[] => [ base: (material: IMaterial): UiObjectConfig[] => [
], ],
} }
), ),
bumpNormal: (material: PhysicalMaterial): UiObjectConfig => (
bumpNormal: (material: PhysicalMaterial|LegacyPhongMaterial): UiObjectConfig => (
{ {
type: 'folder', type: 'folder',
label: 'Bump/Normal', label: 'Bump/Normal',
], ],
} }
), ),
emission: (material: PhysicalMaterial): UiObjectConfig => (
emission: (material: PhysicalMaterial|LegacyPhongMaterial): UiObjectConfig => (
{ {
type: 'folder', type: 'folder',
label: 'Emission', label: 'Emission',

+ 291
- 0
src/core/material/LegacyPhongMaterial.ts Zobrazit soubor

import {
Color,
IUniform,
Material,
MeshPhongMaterial,
MeshPhongMaterialParameters,
MultiplyOperation,
Shader,
Vector2,
WebGLRenderer,
} from 'three'
import {UiObjectConfig} from 'uiconfig.js'
import {
IMaterial,
IMaterialEvent,
IMaterialEventTypes,
IMaterialGenerator,
IMaterialParameters,
IMaterialTemplate,
} from '../IMaterial'
import {MaterialExtension} from '../../materials'
import {SerializationMetaType, shaderReplaceString, ThreeSerialization} from '../../utils'
import {ITexture} from '../ITexture'
import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons'
import {IObject3D} from '../IObject'
import {iMaterialUI} from './IMaterialUi'
import {makeSamplerUi} from '../../ui/image-ui'

export type PhongMaterialEventTypes = IMaterialEventTypes | ''

export class LegacyPhongMaterial extends MeshPhongMaterial<IMaterialEvent, PhongMaterialEventTypes> implements IMaterial<IMaterialEvent, PhongMaterialEventTypes> {
declare ['constructor']: typeof LegacyPhongMaterial

public static readonly TypeSlug = 'phongmat'
public static readonly TYPE = 'LegacyPhongMaterial' // not using .type because it is used by three.js
assetType = 'material' as const

public readonly isLegacyPhongMaterial = true

readonly appliedMeshes: Set<IObject3D> = new Set()
readonly setDirty = iMaterialCommons.setDirty
dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)}
clone(): this {return iMaterialCommons.clone(super.clone).call(this)}
dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)}

generator?: IMaterialGenerator

envMap: ITexture | null = null

constructor({customMaterialExtensions, ...parameters}: MeshPhongMaterialParameters & IMaterialParameters = {}) {
super(parameters)
!this.defines && (this.defines = {})
this.fog = false
this.setDirty = this.setDirty.bind(this)
if (customMaterialExtensions) this.registerMaterialExtensions(customMaterialExtensions)
iMaterialCommons.upgradeMaterial.call(this)
}

// region Material Extension

materialExtensions: MaterialExtension[] = []
extraUniformsToUpload: Record<string, IUniform> = {}
registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions
unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions

customProgramCacheKey(): string {
return super.customProgramCacheKey() + iMaterialCommons.customProgramCacheKey.call(this)
}

onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines
const f = [
['vec3 outgoingLight = ', 'afterModulation'], // added markers before found substring
['#include <aomap_fragment>', 'beforeModulation'],
['ReflectedLight reflectedLight = ', 'beforeAccumulation'],
['#include <clipping_planes_fragment>', 'mainStart'],
]
const v = [
['#include <uv_vertex>', 'mainStart'],
]

for (const vElement of v) shader.vertexShader = shaderReplaceString(shader.vertexShader, vElement[0], '#glMarker ' + vElement[1] + '\n' + vElement[0])
for (const vElement of f) shader.fragmentShader = shaderReplaceString(shader.fragmentShader, vElement[0], '#glMarker ' + vElement[1] + '\n' + vElement[0])

iMaterialCommons.onBeforeCompile.call(this, shader, renderer)
// ;(shader as any).defines.INVERSE_ALPHAMAP = this.userData.inverseAlphaMap ? 1 : 0 // todo

super.onBeforeCompile(shader, renderer)
}

// onBeforeRender(...args: Parameters<IMaterial['onBeforeRender']>): void {
// super.onBeforeRender(...args)
// iMaterialCommons.onBeforeRender.call(this, ...args)
//
// // const t = this.userData.inverseAlphaMap ? 1 : 0 // todo
// // if (t !== this.defines.INVERSE_ALPHAMAP) {
// // this.defines.INVERSE_ALPHAMAP = t
// // this.needsUpdate = true
// // }
// }
onBeforeRender = iMaterialCommons.onBeforeRenderOverride(super.onBeforeRender)
onAfterRender = iMaterialCommons.onAfterRenderOverride(super.onAfterRender)

// endregion

// region Serialization

/**
* Sets the values of this material based on the values of the passed material or an object with material properties
* The input is expected to be a valid material or a deserialized material parameters object(including the deserialized userdata)
* @param parameters - material or material parameters object
* @param allowInvalidType - if true, the type of the oldMaterial is not checked. Objects without type are always allowed.
* @param clearCurrentUserData - if undefined, then depends on material.isMaterial. if true, the current userdata is cleared before setting the new values, because it can have data which wont be overwritten if not present in the new material.
*/
setValues(parameters: Material|(MeshPhongMaterialParameters&{type?:string}), allowInvalidType = true, clearCurrentUserData: boolean|undefined = undefined): this {
if (!parameters) return this
if (parameters.type && !allowInvalidType && !['MeshPhongMaterial', 'MeshPhongMaterial2', this.constructor.TYPE].includes(parameters.type)) {
console.error('Material type is not supported:', parameters.type)
return this
}
if (clearCurrentUserData === undefined) clearCurrentUserData = (<Material>parameters).isMaterial
if (clearCurrentUserData) this.userData = {}
iMaterialCommons.setValues(super.setValues).call(this, parameters)

this.userData.uuid = this.uuid
return this
}
copy(source: Material|any): this {
return this.setValues(source, false)
}

/**
* Serializes this material to JSON.
* @param meta - metadata for serialization
* @param _internal - Calls only super.toJSON, does internal three.js serialization and @serialize tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material
*/
toJSON(meta?: SerializationMetaType, _internal = false): any {
if (_internal) return {
...super.toJSON(meta),
...ThreeSerialization.Serialize(this, meta, true), // this will serialize the properties of this class(like defined with @serialize and @serialize attribute)
}
return ThreeSerialization.Serialize(this, meta, false) // this will call toJSON again, but with baseOnly=true, that's why we set isThis to false.
}

/**
* Deserializes the material from JSON.
* Textures should be loaded and in meta.textures before calling this method.
* todo - needs to be tested
* @param data
* @param meta
* @param _internal
*/
fromJSON(data: any, meta?: SerializationMetaType, _internal = false): this | null {
if (_internal) {
ThreeSerialization.Deserialize(data, this, meta, true)
return this.setValues(data)
}
this.dispatchEvent({type: 'beforeDeserialize', data, meta, bubbleToObject: true, bubbleToParent: true})
return this
}

// endregion

// region UI Config

// todo dispose ui config
uiConfig: UiObjectConfig = {
type: 'folder',
label: 'Phong Material',
uuid: 'MBM2_' + this.uuid,
expanded: true,
children: [
...iMaterialUI.base(this),
iMaterialUI.blending(this),
iMaterialUI.polygonOffset(this),
iMaterialUI.aoLightMap(this),
{
type: 'folder',
label: 'Specular',
children: [
{
type: 'color',
property: [this, 'specular'],
},
{
type: 'image',
property: [this, 'specularMap'],
},
makeSamplerUi(this, 'specularMap'),
{
type: 'slider',
label: 'Shininess',
property: [this, 'shininess'],
bounds: [0, 100],
stepSize: 0.1,
},
{
type: 'slider',
label: 'Reflectivity',
property: [this, 'reflectivity'],
bounds: [0, 1],
stepSize: 0.01,
},
{
type: 'slider',
label: 'Refraction Ratio',
property: [this, 'refractionRatio'],
bounds: [0, 3],
stepSize: 0.01,
},
],
},
iMaterialUI.bumpNormal(this),
iMaterialUI.emission(this),
{
type: 'folder',
label: 'Env Map',
children: [
{
type: 'image',
property: [this, 'envMap'],
},
makeSamplerUi(this, 'envMap'),
{
type: 'slider',
label: 'Env Map Intensity',
property: [this, 'envMapIntensity'],
bounds: [0, 5],
stepSize: 0.01,
},
],
},
...iMaterialUI.misc(this),
],
}

// endregion UI Config


// Class properties can also be listed with annotations like @serialize or @property
// used for serialization
static readonly MaterialProperties = {
...threeMaterialPropList,

color: new Color(0xffffff),
specular: new Color(0x111111),
shininess: 30,
map: null,
lightMap: null,
lightMapIntensity: 1,
aoMap: null,
aoMapIntensity: 1,
emissive: new Color(0x000000),
emissiveIntensity: 1,
emissiveMap: null,
bumpMap: null,
bumpScale: 1,
normalMap: null,
normalMapType: 'TangentSpaceNormalMap',
normalScale: new Vector2(1, 1),
displacementMap: null,
displacementScale: 1,
displacementBias: 0,
specularMap: null,
alphaMap: null,
envMap: null,
combine: MultiplyOperation,
envMapIntensity: 1,
reflectivity: 1,
refractionRatio: 0.98,
wireframe: false,
wireframeLinewidth: 1,
wireframeLinecap: 'round',
wireframeLinejoin: 'round',
skinning: false,
fog: true,
flatShading: false,
}

static MaterialTemplate: IMaterialTemplate<LegacyPhongMaterial, Partial<typeof LegacyPhongMaterial.MaterialProperties>> = {
materialType: LegacyPhongMaterial.TYPE,
name: 'phong',
typeSlug: LegacyPhongMaterial.TypeSlug,
alias: ['phong', 'legacy-phong', LegacyPhongMaterial.TYPE, LegacyPhongMaterial.TypeSlug, 'MeshPhongMaterial', 'MeshPhongMaterial2', 'PhongMaterial'],
params: {
color: new Color(1, 1, 1),
},
generator: (params) => {
return new LegacyPhongMaterial(params)
},
}
}

+ 1
- 0
src/core/material/PhysicalMaterial.ts Zobrazit soubor



// endregion // endregion


// used for serialization
static readonly MaterialProperties = { static readonly MaterialProperties = {
// keep updated with properties in MeshStandardMaterial.js // keep updated with properties in MeshStandardMaterial.js
...threeMaterialPropList, ...threeMaterialPropList,

+ 3
- 3
src/core/material/UnlitMaterial.ts Zobrazit soubor

IMaterialTemplate, IMaterialTemplate,
} from '../IMaterial' } from '../IMaterial'
import {MaterialExtension} from '../../materials' import {MaterialExtension} from '../../materials'
import {shaderReplaceString} from '../../utils/shader-helpers'
import {SerializationMetaType, ThreeSerialization} from '../../utils/serialization'
import {SerializationMetaType, shaderReplaceString, ThreeSerialization} from '../../utils'
import {ITexture} from '../ITexture' import {ITexture} from '../ITexture'
import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons' import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons'
import {IObject3D} from '../IObject' import {IObject3D} from '../IObject'




// Class properties can also be listed with annotations like @serialize or @property // Class properties can also be listed with annotations like @serialize or @property
// used for serialization
static readonly MaterialProperties = { static readonly MaterialProperties = {
...threeMaterialPropList, ...threeMaterialPropList,


wireframeLinejoin: 'round', wireframeLinejoin: 'round',
skinning: false, skinning: false,
fog: true, fog: true,
flatShading: false,
} }


static MaterialTemplate: IMaterialTemplate<UnlitMaterial, Partial<typeof UnlitMaterial.MaterialProperties>> = { static MaterialTemplate: IMaterialTemplate<UnlitMaterial, Partial<typeof UnlitMaterial.MaterialProperties>> = {

+ 3
- 1
src/plugins/postprocessing/TonemapPlugin.ts Zobrazit soubor

import {AViewerPluginSync, ThreeViewer} from '../../viewer'
// noinspection ES6PreferShortImport
import {AViewerPluginSync} from '../../viewer/AViewerPlugin'
import type {ThreeViewer} from '../../viewer'
import {MaterialExtension} from '../../materials' import {MaterialExtension} from '../../materials'
import {uiDropdown, uiFolderContainer, uiSlider, uiToggle} from 'uiconfig.js' import {uiDropdown, uiFolderContainer, uiSlider, uiToggle} from 'uiconfig.js'
import { import {

+ 2
- 2
src/postprocessing/ExtendedRenderPass.ts Zobrazit soubor

// renderer.autoClearDepth = false // renderer.autoClearDepth = false


ud.transmissionRenderTarget = writeBuffer ud.transmissionRenderTarget = writeBuffer
ud.blurTransmissionTarget = this.blurTransmissionTarget
ud.blurTransmissionTarget = this.blurTransmissionTarget && ud.transmissionRenderTarget.samples === 0 // todo: not working with msaa


renderer.renderWithModes({ renderer.renderWithModes({
shadowMapRender: false, shadowMapRender: false,
// renderer.autoClearDepth = false // renderer.autoClearDepth = false


ud.transmissionRenderTarget = needsSwap ? writeBuffer : readBuffer ud.transmissionRenderTarget = needsSwap ? writeBuffer : readBuffer
ud.blurTransmissionTarget = this.blurTransmissionTarget
ud.blurTransmissionTarget = this.blurTransmissionTarget && ud.transmissionRenderTarget.samples === 0 // todo: not working with msaa


renderer.renderWithModes({ renderer.renderWithModes({
shadowMapRender: false, shadowMapRender: false,

+ 2
- 1
src/three/utils/gpu-instancing.ts Zobrazit soubor

import {IGeometry, IMaterial, IObject3D} from '../../core' import {IGeometry, IMaterial, IObject3D} from '../../core'
import {BufferAttribute, InstancedMesh} from 'three' import {BufferAttribute, InstancedMesh} from 'three'
import {copyObject3DUserData} from '../../utils'
// noinspection ES6PreferShortImport
import {copyObject3DUserData} from '../../utils/serialization'


export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) { export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) {
if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return

+ 1
- 0
src/utils/GLStatsJS.ts Zobrazit soubor



constructor(private _container: HTMLElement) { constructor(private _container: HTMLElement) {
this._stats.dom.id = 'stats-js' this._stats.dom.id = 'stats-js'
this._stats.dom.style.position = 'absolute'
this._stats.dom.style.left = 'unset' this._stats.dom.style.left = 'unset'
this._stats.dom.style.right = '0' this._stats.dom.style.right = '0'



+ 1
- 1
src/viewer/AViewerPlugin.ts Zobrazit soubor

import {ISerializedConfig, ThreeViewer} from './ThreeViewer'
import type {ISerializedConfig, ThreeViewer} from './ThreeViewer'
import {Event, EventDispatcher} from 'three' import {Event, EventDispatcher} from 'three'
import {SerializationMetaType, ThreeSerialization} from '../utils' import {SerializationMetaType, ThreeSerialization} from '../utils'
import {IViewerPlugin, IViewerPluginAsync} from './IViewerPlugin' import {IViewerPlugin, IViewerPluginAsync} from './IViewerPlugin'

+ 5
- 4
src/viewer/ThreeViewer.ts Zobrazit soubor

RootSceneImportResult, RootSceneImportResult,
} from '../assetmanager' } from '../assetmanager'
import {IViewerPlugin, IViewerPluginSync} from './IViewerPlugin' import {IViewerPlugin, IViewerPluginSync} from './IViewerPlugin'
// noinspection ES6PreferShortImport
import {DropzonePlugin, DropzonePluginOptions} from '../plugins/interaction/DropzonePlugin'
import {uiConfig, uiFolderContainer, UiObjectConfig} from 'uiconfig.js' import {uiConfig, uiFolderContainer, UiObjectConfig} from 'uiconfig.js'
import {IRenderTarget} from '../rendering' import {IRenderTarget} from '../rendering'
import type {ProgressivePlugin} from '../plugins' import type {ProgressivePlugin} from '../plugins'
import {TonemapPlugin} from '../plugins'
// noinspection ES6PreferShortImport
import {DropzonePlugin, DropzonePluginOptions} from '../plugins/interaction/DropzonePlugin'
// noinspection ES6PreferShortImport
import {TonemapPlugin} from '../plugins/postprocessing/TonemapPlugin'
import {VERSION} from './version' import {VERSION} from './version'


export type IViewerEvent = BaseEvent & { export type IViewerEvent = BaseEvent & {
* Create a viewer instance for using the webgi viewer SDK. * Create a viewer instance for using the webgi viewer SDK.
* @param options - {@link ThreeViewerOptions} * @param options - {@link ThreeViewerOptions}
*/ */
constructor({debug = true, ...options}: ThreeViewerOptions) {
constructor({debug = false, ...options}: ThreeViewerOptions) {
super() super()
this.debug = debug this.debug = debug
this._canvas = options.canvas || createCanvasElement() this._canvas = options.canvas || createCanvasElement()

+ 6
- 4
src/viewer/ViewerRenderManager.ts Zobrazit soubor

import {IRenderTarget, RenderManager} from '../rendering' import {IRenderTarget, RenderManager} from '../rendering'
import {HalfFloatType, NoColorSpace, RGBM16ColorSpace, UnsignedByteType} from 'three'
import {HalfFloatType, LinearMipMapLinearFilter, NoColorSpace, RGBM16ColorSpace, UnsignedByteType} from 'three'
import {IRenderManagerOptions} from '../core' import {IRenderManagerOptions} from '../core'
import {ExtendedRenderPass, ScreenPass, TViewerScreenShader} from '../postprocessing' import {ExtendedRenderPass, ScreenPass, TViewerScreenShader} from '../postprocessing'
import {uiFolderContainer} from 'uiconfig.js' import {uiFolderContainer} from 'uiconfig.js'


export interface ViewerRenderManagerOptions extends IRenderManagerOptions { export interface ViewerRenderManagerOptions extends IRenderManagerOptions {
rgbm?: boolean, rgbm?: boolean,
msaa?: boolean,
msaa?: boolean | number,
depthBuffer?: boolean, depthBuffer?: boolean,
zPrepass?: boolean, zPrepass?: boolean,
screenShader?: TViewerScreenShader screenShader?: TViewerScreenShader
@uiFolderContainer('Render Manager') @uiFolderContainer('Render Manager')
export class ViewerRenderManager extends RenderManager { export class ViewerRenderManager extends RenderManager {
readonly rgbm: boolean readonly rgbm: boolean
readonly msaa: boolean
readonly msaa: boolean | number
readonly depthBuffer: boolean readonly depthBuffer: boolean
readonly zPrepass: boolean readonly zPrepass: boolean
readonly renderPass: ExtendedRenderPass readonly renderPass: ExtendedRenderPass
super({ super({
...options, ...options,
targetOptions: { targetOptions: {
samples: msaa ? 4 : 0,
samples: msaa ? typeof msaa !== 'number' ? 4 : msaa : 0,
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
}, },
}) })
this.rgbm = rgbm this.rgbm = rgbm

+ 1
- 1
src/viewer/version.ts Zobrazit soubor

export const VERSION = '0.0.14'
export const VERSION = '0.0.15'

Načítá se…
Zrušit
Uložit