Просмотр исходного кода

Render target properties serialization, export serialization decorators.

master
Palash Bansal 3 лет назад
Родитель
Сommit
e444ca3e14
Аккаунт пользователя с таким Email не найден
4 измененных файлов: 109 добавлений и 6 удалений
  1. 9
    0
      src/rendering/RenderTarget.ts
  2. 8
    4
      src/rendering/RenderTargetManager.ts
  3. 3
    1
      src/utils/index.ts
  4. 89
    1
      src/utils/serialization.ts

+ 9
- 0
src/rendering/RenderTarget.ts Просмотреть файл

@@ -10,7 +10,13 @@ import {Vector4} from 'three/src/math/Vector4'
import {DepthTexture} from 'three/src/textures/DepthTexture'

export interface IRenderTarget extends EventDispatcher {
isWebGLRenderTarget: boolean
width: number
height: number
depth: number

texture: Texture | Texture[]
uuid?: string
sizeMultiplier?: number
isTemporary?: boolean
targetKey?: string // for caching.
@@ -45,6 +51,9 @@ export interface IRenderTarget extends EventDispatcher {
*/
samples: number;

isWebGLCubeRenderTarget?: boolean
isWebGLMultipleRenderTargets?: boolean

}

export interface CreateRenderTargetOptions {

+ 8
- 4
src/rendering/RenderTargetManager.ts Просмотреть файл

@@ -16,6 +16,7 @@ import {
WebGLRenderTarget,
WebGLRenderTargetOptions,
} from 'three'
import {generateUUID} from '../three'

export abstract class RenderTargetManager<E extends BaseEvent = BaseEvent, ET extends string = string> extends EventDispatcher<E, ET> {
abstract isWebGL2: boolean
@@ -125,7 +126,7 @@ export abstract class RenderTargetManager<E extends BaseEvent = BaseEvent, ET ex
if (width !== height) throw 'Width and height of cube render target must be equal'
size = [width]
}
options = {
const params = [...size, {
format: RGBAFormat,
minFilter: LinearFilter,
magFilter: LinearFilter,
@@ -133,17 +134,19 @@ export abstract class RenderTargetManager<E extends BaseEvent = BaseEvent, ET ex
type: UnsignedByteType,
colorSpace: NoColorSpace,
...options,
}
const params = [...size, options]
}]
return new class RenderTarget extends ((clazz as any as Class<WebGLRenderTarget>) ?? WebGLRenderTarget) implements IRenderTarget {
isTemporary?: boolean
sizeMultiplier?: number
uuid: string

constructor(...ps: any[]) {
super(...ps)
this.uuid = generateUUID()
const ops = ps[ps.length - 1] as WebGLRenderTargetOptions
if (Array.isArray(this.texture)) {
this.texture.forEach(t => {
t.colorSpace = options.colorSpace
t.colorSpace = ops.colorSpace
t.toJSON = () => {
console.warn('Multiple render target texture.toJSON not supported yet.')
return {}
@@ -172,6 +175,7 @@ export abstract class RenderTargetManager<E extends BaseEvent = BaseEvent, ET ex
else tex.isRenderTargetTexture = true
return processNewTarget(cloned, this.sizeMultiplier || 1, trackTarget)
}

}(...params) as any as T
}


+ 3
- 1
src/utils/index.ts Просмотреть файл

@@ -3,5 +3,7 @@ export {windowDialogWrapper, type IDialogWrapper} from './DialogWrapper'
export {GLStatsJS} from './GLStatsJS'
export {CustomContextMenu} from './CustomContextMenu'
export {Dropzone, type DropFile, type ListenerCallback, type DropEventType} from './Dropzone'
export {ThreeSerialization, type SerializationMetaType, type SerializationResourcesType, MetaImporter} from './serialization'
export {ThreeSerialization, type SerializationMetaType, type SerializationResourcesType, MetaImporter, metaToResources, getEmptyMeta, metaFromResources, convertArrayBufferToStringsInMeta, convertStringsToArrayBuffersInMeta, copyMaterialUserData, copyObject3DUserData, copyUserData, copyTextureUserData} from './serialization'
export {shaderReplaceString} from './shader-helpers'

export {serialize, serializable, Serialization} from 'ts-browser-helpers'

+ 89
- 1
src/utils/serialization.ts Просмотреть файл

@@ -17,6 +17,7 @@ import type {AssetImporter, AssetManager, MaterialManager} from '../assetmanager
import {IAssetImporter} from '../assetmanager'
import {ThreeViewer} from '../viewer'
import {ITexture} from '../core'
import {IRenderTarget, RenderManager} from '../rendering'

const copier = (c: any) => (v: any, o: any) => o?.copy?.(v) ?? new c().copy(v)
export class ThreeSerialization {
@@ -276,6 +277,88 @@ export class ThreeSerialization {

},
})

// render target
Serialization.RegisterSerializer({
priority: 2,
isType: (obj: any) => obj.isWebGLRenderTarget || obj.metadata?.type === 'RenderTarget',
serialize: (obj: IRenderTarget, meta?: SerializationMetaType) => {
if (!obj?.isWebGLRenderTarget || !obj.uuid) throw new Error('Expected a IRenderTarget')
if (meta?.extras[obj.uuid]) return {uuid: obj.uuid, resource: 'extras'}

const tex = Array.isArray(obj.texture) ? obj.texture[0] : obj.texture
let res: any = {
metadata: {type: 'RenderTarget'},
uuid: obj.uuid,
width: obj.width,
height: obj.height,
depth: obj.depth,
sizeMultiplier: obj.sizeMultiplier,
count: Array.isArray(obj.texture) ? obj.texture.length : undefined,
isCubeRenderTarget: obj.isWebGLCubeRenderTarget || undefined,
isTemporary: obj.isTemporary,
textureName: Array.isArray(obj.texture) ? obj.texture.map(t => t.name) : obj.texture?.name,
options: {
wrapS: tex?.wrapS,
wrapT: tex?.wrapT,
magFilter: tex?.magFilter,
minFilter: tex?.minFilter,
format: tex?.format,
type: tex?.type,
anisotropy: tex?.anisotropy,
depthBuffer: !!obj.depthBuffer,
stencilBuffer: !!obj.stencilBuffer,
generateMipmaps: tex?.generateMipmaps,
depthTexture: !!obj.depthTexture,
colorSpace: tex?.colorSpace,
samples: obj.samples,
},
}

if (meta?.extras) {
if (!meta.extras[res.uuid])
meta.extras[res.uuid] = res
res = {uuid: res.uuid, resource: 'extras'}
}
return res
},
deserialize: (dat: any, obj: any, meta?: SerializationMetaType) => {
if (obj?.uuid === dat.uuid) return obj
if (dat.isWebGLRenderTarget) return dat

const renderManager = meta?._context.renderManager
if (!renderManager) {
console.error('Cannot deserialize render target without render manager', dat)
return obj
}
if (dat.isWebGLCubeRenderTarget || dat.isTemporary) {
// todo support cube, temporary render target here
console.warn('Cannot deserialize WebGLCubeRenderTarget or temporary render target yet', dat)
return obj
}

const res = renderManager.createTarget({
sizeMultiplier: dat.sizeMultiplier || undefined,
size: dat.sizeMultiplier ? undefined : {width: dat.width, height: dat.height},
textureCount: dat.count,
...dat.options,
})
if (dat.textureName) {
if (Array.isArray(dat.textureName) && Array.isArray(res.texture)) {
for (let i = 0; i < dat.textureName.length; i++) {
res.texture[i].name = dat.textureName[i]
}
} else if (!Array.isArray(res.texture)) {
res.texture.name = Array.isArray(dat.textureName) ? dat.textureName[0] : dat.textureName
}
}
if (!res) return res
res.uuid = dat.uuid
if (meta?.extras) meta.extras[dat.uuid] = res
return res
},
})

}

/**
@@ -477,6 +560,7 @@ export interface SerializationMetaType extends SerializationResourcesType {
objectLoader?: ObjectLoader,
materialManager?: MaterialManager,
assetManager?: AssetManager,
renderManager?: RenderManager,

imagePromises?: Promise<any>[],

@@ -571,7 +655,10 @@ export class MetaImporter {
resources.extras = json.extras
for (const e of (Object.values(json.extras) as any as any[])) {
if (!e.uuid) continue
if (!e.url) continue
if (!e.url) {
resources.extras[e.uuid] = ThreeSerialization.Deserialize(e, undefined, resources)
continue
}
// see LUTCubeTextureWrapper, KTX2LoadPlugin for sample use
if (typeof e.url === 'string') {
const r = await assetImporter.importPath(e.url)
@@ -637,6 +724,7 @@ export function metaFromResources(resources?: Partial<SerializationResourcesType
assetManager: viewer?.assetManager,
assetImporter: viewer?.assetManager.importer,
materialManager: viewer?.assetManager.materials,
renderManager: viewer?.renderManager,
}, // clear context even if its present in resources
}
}

Загрузка…
Отмена
Сохранить