| @@ -3654,7 +3654,10 @@ Note that this does not support all the features of three.js and may not work wi | |||
| import {ThreeViewer} from 'threepipe' | |||
| import {ThreeSVGRendererPlugin} from '@threepipe/plugin-svg-renderer' | |||
| const viewer = new ThreeViewer({...}) | |||
| const viewer = new ThreeViewer({ | |||
| ..., | |||
| rgbm: false, // this is required | |||
| }) | |||
| const svgRender = viewer.addPluginSync(ThreeSVGRendererPlugin) | |||
| svgRender.autoRender = true // automatically render when camera or any object changes. | |||
| svgRender.autoMakeSvgObjects = true // automatically create SVG objects for all meshes in the scene. | |||
| @@ -3664,10 +3667,8 @@ svgRender.autoMakeSvgObjects = true // automatically create SVG objects for all | |||
| const model = await viewer.load<IOBject3D>('path/to/file.glb') | |||
| // clear the background of the viewer | |||
| // this is only required if rgbm = false in the viewer | |||
| viewer.scene.backgroundColor = null | |||
| // this is only required if rgbm = true in the viewer | |||
| viewer.renderManager.screenPass.clipBackground = true | |||
| viewer.scene.background = null | |||
| // disable damping to get better experience. | |||
| viewer.scene.mainCamera.controls!.enableDamping = false | |||
| @@ -29,7 +29,7 @@ async function init() { | |||
| }), | |||
| ]) | |||
| viewer.scene.overrideMaterial = new PhysicalMaterial({ | |||
| viewer.renderManager.renderPass.overrideMaterial = new PhysicalMaterial({ | |||
| color: 'white', | |||
| roughness: 1, | |||
| metalness: 0, | |||
| @@ -49,6 +49,7 @@ async function init() { | |||
| expanded: true, | |||
| }) | |||
| ui.setupPlugins(ProgressivePlugin) | |||
| ui.appendChild(viewer.renderManager.uiConfig) | |||
| await viewer.getPlugin(ProgressivePlugin)?.convergedPromise | |||
| @@ -46,7 +46,7 @@ async function init() { | |||
| 'https://threejs.org/examples/models/obj/male02/male02.obj', | |||
| 'https://threejs.org/examples/models/gltf/kira.glb', // slow | |||
| // not working | |||
| // not working/very slow | |||
| 'https://threejs.org/examples/models/gltf/Soldier.glb', | |||
| 'https://threejs.org/examples/models/gltf/LittlestTokyo.glb', | |||
| 'https://threejs.org/examples/models/gltf/ferrari.glb', | |||
| @@ -59,7 +59,6 @@ async function init() { | |||
| viewer.scene.backgroundColor = null | |||
| viewer.scene.background = null | |||
| // viewer.renderManager.screenPass.clipBackground = true // required when rgbm: true | |||
| viewer.scene.mainCamera.controls!.enableDamping = false | |||
| @@ -23,7 +23,7 @@ void main() { | |||
| #ifdef HAS_GBUFFER | |||
| #ifdef CLIP_BACKGROUND | |||
| #if (defined(CLIP_BACKGROUND) && CLIP_BACKGROUND > 0) || defined(CLIP_BACKGROUND_FORCE) | |||
| if(isBackground) diffuseColor.a = 0.0; | |||
| if(depth>0.99 && transparentColor.a >= 0.001) diffuseColor.a = transparentColor.a; | |||
| #endif | |||
| @@ -62,6 +62,7 @@ export class ScreenPass extends ExtendedShaderPass implements IPipelinePass<'scr | |||
| this._needsReRender = false | |||
| this.reRender(renderManager.renderer) | |||
| if (this.clipBackground && !(renderManager as ViewerRenderManager).gbufferTarget) { | |||
| // todo warn only when rgbm | |||
| console.warn('ScreenPass: clipBackground set to true but no gbufferTarget set. Try adding GBufferPlugin.') | |||
| } | |||
| } | |||
| @@ -71,8 +72,16 @@ export class ScreenPass extends ExtendedShaderPass implements IPipelinePass<'scr | |||
| super.dispose() | |||
| } | |||
| /** | |||
| * Force clip background. If this is `true` {@link clipBackground} is overridden. | |||
| * This happens when scene.background and scene.backgroundColor are both null. | |||
| * This is set in {@link ViewerRenderManager.render}. | |||
| */ | |||
| @matDefineBool('CLIP_BACKGROUND_FORCE', undefined, undefined, ScreenPass.prototype.setDirty, true) | |||
| clipBackgroundForce = false | |||
| // todo: this is not serialized anymore? | |||
| @matDefineBool('CLIP_BACKGROUND', undefined, undefined, ScreenPass.prototype.setDirty, true) | |||
| @matDefineBool('CLIP_BACKGROUND', undefined, undefined, ScreenPass.prototype.setDirty) | |||
| @uiToggle() clipBackground = false | |||
| beforeRender(_: IScene, _1: ICamera, renderManager: ViewerRenderManager) { | |||
| @@ -110,7 +110,7 @@ export function matDefine(key?: string|symbol, customDefines?: any, thisMat = fa | |||
| * @param customDefines - object for setting define value (like ShaderMaterial.defines), otherwise this.material.defines is taken | |||
| * @param thisMat - access this.defines instead of this.material.defines | |||
| * @param onChange - function to call when the value changes. If a string, it is used as a property name in `this` and called. If a function, it is called. The function is called with the following parameters: key, newVal | |||
| * @param deleteOnFalse - sets to undefined instead of '0' when false | |||
| * @param deleteOnFalse - sets to undefined instead of '0' when false. Note deleteOnFalse doesn't work with tweakpane ui because the value will be undefined. | |||
| */ | |||
| export function matDefineBool(key?: string|symbol, customDefines?: any, thisMat = false, onChange?: (...args: any[]) => any, deleteOnFalse = false): PropertyDecorator { | |||
| return matDefine(key, customDefines, thisMat, onChange, (v: any)=>v ? '1' : deleteOnFalse ? undefined : '0', (v: any)=>v && v !== '0') | |||
| @@ -135,6 +135,7 @@ export interface ThreeViewerOptions { | |||
| * Same as pixelRatio in three.js | |||
| * Can be set to `window.devicePixelRatio` to render at device resolution in browsers. | |||
| * An optimal value is `Math.min(2, window.devicePixelRatio)` to prevent issues on mobile. This is set when 'auto' is passed. | |||
| * Default is 1. | |||
| */ | |||
| renderScale?: number | 'auto' | |||
| @@ -1,8 +1,8 @@ | |||
| import {IRenderTarget, RenderManager} from '../rendering' | |||
| import {HalfFloatType, LinearMipMapLinearFilter, NoColorSpace, RGBM16ColorSpace, UnsignedByteType} from 'three' | |||
| import {IRenderManagerEvent, IRenderManagerOptions} from '../core' | |||
| import {IRenderManagerEvent, IRenderManagerOptions, IScene} from '../core' | |||
| import {ExtendedRenderPass, ScreenPass, TViewerScreenShader} from '../postprocessing' | |||
| import {uiFolderContainer} from 'uiconfig.js' | |||
| import {uiFolderContainer, UiObjectConfig} from 'uiconfig.js' | |||
| import {MaterialExtension} from '../materials' | |||
| import {onChange3} from 'ts-browser-helpers' | |||
| @@ -22,6 +22,7 @@ export class ViewerRenderManager extends RenderManager<IRenderManagerEvent, 'gbu | |||
| readonly zPrepass: boolean | |||
| readonly renderPass: ExtendedRenderPass | |||
| readonly screenPass: ScreenPass | |||
| declare uiConfig: UiObjectConfig | |||
| constructor({rgbm = true, msaa = false, depthBuffer = false, ...options}: ViewerRenderManagerOptions) { | |||
| super({ | |||
| @@ -68,4 +69,12 @@ export class ViewerRenderManager extends RenderManager<IRenderManagerEvent, 'gbu | |||
| this.dispatchEvent({type: 'gbufferUnpackExtensionChanged', ...params}) | |||
| } | |||
| render(scene: IScene, renderToScreen?: boolean): void { | |||
| const cbf = this.screenPass.clipBackgroundForce | |||
| if (this.rgbm) { | |||
| const val = !scene.background && !scene.backgroundColor | |||
| if (val !== cbf) this.screenPass.clipBackgroundForce = val | |||
| } | |||
| super.render(scene, renderToScreen) | |||
| } | |||
| } | |||