Skip to content

Commit

Permalink
Add GBufferPlugin, update ts-browser-helpers and uiconfig.js, add sup…
Browse files Browse the repository at this point in the history
…port to render and export MRT, add center all geometries in RootScene, other minor changes and refactor.
  • Loading branch information
repalash committed Feb 2, 2024
1 parent 9b48f29 commit fd88dc8
Show file tree
Hide file tree
Showing 38 changed files with 996 additions and 156 deletions.
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ To make changes and run the example, click on the CodePen button on the top righ
- [ProgressivePlugin](#progressiveplugin) - Post-render pass to blend the last frame with the current frame
- [DepthBufferPlugin](#depthbufferplugin) - Pre-rendering of depth buffer
- [NormalBufferPlugin](#normalbufferplugin) - Pre-rendering of normal buffer
- [GBufferPlugin](#depthnormalbufferplugin) - Pre-rendering of depth and normal buffers in a single pass buffer
- [GBufferPlugin](#gbufferplugin) - Pre-rendering of depth-normal and flags buffers in a single pass
- [PickingPlugin](#pickingplugin) - Adds support for selecting objects in the viewer with user interactions and selection widgets
- [TransformControlsPlugin](#transformcontrolsplugin) - Adds support for moving, rotating and scaling objects in the viewer with interactive widgets
- [GLTFAnimationPlugin](#gltfanimationplugin) - Add support for playing and seeking gltf animations
Expand Down Expand Up @@ -2212,7 +2212,7 @@ The depth values are based on camera near far values, which are controlled autom

Normal Buffer Plugin adds a pre-render pass to the render manager and renders a normal buffer to a target. The render target can be accessed by other plugins throughout the rendering pipeline to create effects like SSAO, SSR, etc.

Note: Use [`DepthNormalBufferPlugin`](#DepthNormalBufferPlugin) if using both `DepthBufferPlugin` and `NormalBufferPlugin` to render both depth and normal buffers in a single pass.
Note: Use [`GBufferPlugin`](#GBufferPlugin) if using both `DepthBufferPlugin` and `NormalBufferPlugin` to render both depth and normal buffers in a single pass.

```typescript
import {ThreeViewer, NormalBufferPlugin} from 'threepipe'
Expand All @@ -2229,7 +2229,25 @@ const normalTarget = normalPlugin.target;

## GBufferPlugin

todo
[//]: # (todo: image)

[Example](https://threepipe.org/examples/#gbuffer-plugin/) —
[Source Code](./src/plugins/pipeline/GBufferPlugin.ts) —
[API Reference](https://threepipe.org/docs/classes/GBufferPlugin.html)

GBuffer Plugin adds a pre-render pass to the render manager and renders depth+normals to a target and some customizable flags to another. The multiple render target and textures can be accessed by other plugins throughout the rendering pipeline to create effects like SSAO, SSR, etc.

```typescript
import {ThreeViewer, GBufferPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const gBufferPlugin = viewer.addPluginSync(new GBufferPlugin())

const gBuffer = gBufferPlugin.target;
const normalDepth = gBufferPlugin.normalDepthTexture;
const gBufferFlags = gBufferPlugin.flagsTexture;
```

## PickingPlugin

Expand Down
35 changes: 35 additions & 0 deletions examples/gbuffer-plugin/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GBuffer Plugin</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, #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>
80 changes: 80 additions & 0 deletions examples/gbuffer-plugin/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
_testFinish,
downloadBlob,
GBufferPlugin,
HalfFloatType,
IObject3D,
RenderTargetPreviewPlugin,
ThreeViewer,
} from 'threepipe'
import {createSimpleButtons} from '../examples-utils/simple-bottom-buttons.js'

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

async function init() {

const gbufferPlugin = viewer.addPluginSync(new GBufferPlugin(HalfFloatType))

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

let id = 1
model?.traverse((o) => {
o.materials?.forEach(m=>{
if (!m.userData.gBufferData) m.userData.gBufferData = {}
if (!m.userData.gBufferData.materialId) m.userData.gBufferData.materialId = id += 10
})
})

// Disable automatic near/far plane calculation based on scene bounding box
viewer.scene.mainCamera.userData.autoNearFar = false
viewer.scene.mainCamera.userData.minNearPlane = 1
viewer.scene.mainCamera.userData.maxFarPlane = 10
viewer.scene.refreshScene()

const gbufferTarget = gbufferPlugin.target
if (!gbufferTarget) {
throw new Error('gbufferPlugin.target returned undefined')
}

// to render depth buffer to screen, uncomment this line:
// viewer.renderManager.screenPass.overrideReadBuffer = gbufferTarget

const getNormalDepth = ()=>({texture: gbufferPlugin.normalDepthTexture})
const getFlags = ()=>({texture: gbufferPlugin.flagsTexture})

const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin)
targetPreview.addTarget(getNormalDepth, 'normalDepth')
targetPreview.addTarget(getFlags, 'gBufferFlags')

const screenPass = viewer.renderManager.screenPass

createSimpleButtons({
['Toggle Normal+Depth']: () => {
const rt = getNormalDepth()
screenPass.overrideReadBuffer = screenPass.overrideReadBuffer?.texture === rt.texture ? null : rt
viewer.setDirty()
},
['Toggle Gbuffer Flags']: () => {
const rt = getFlags()
screenPass.overrideReadBuffer = screenPass.overrideReadBuffer?.texture === rt.texture ? null : rt
viewer.setDirty()
},
['Download snapshot']: async(btn: HTMLButtonElement) => {
btn.disabled = true
const blob = await viewer.getScreenshotBlob({mimeType: 'image/png'})
if (blob) downloadBlob(blob, 'file.png')
else console.error('Unable to get screenshot')
btn.disabled = false
},
})

}

init().then(_testFinish)
3 changes: 2 additions & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,10 @@ <h2 class="category">Post-Processing</h2>
<h2 class="category">Rendering</h2>
<ul>
<li><a href="./progressive-plugin/">Progressive Plugin </a></li>
<li><a href="./custom-pipeline/">Custom Pipeline specification </a></li>
<li><a href="./depth-buffer-plugin/">Depth Buffer Plugin </a></li>
<li><a href="./normal-buffer-plugin/">Normal Buffer Plugin </a></li>
<li><a href="./custom-pipeline/">Custom Pipeline specification </a></li>
<li><a href="./gbuffer-plugin/">GBuffer Plugin <br/>(NormalDepth+Flags) </a></li>
<li><a href="./virtual-cameras-plugin/">Virtual Cameras Plugin </a></li>
<li><a href="./virtual-camera/">Virtual Camera (Animated) </a></li>
</ul>
Expand Down
10 changes: 7 additions & 3 deletions examples/tweakpane-editor/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
FragmentClippingExtensionPlugin,
FrameFadePlugin,
FullScreenPlugin,
GBufferPlugin,
GLTFAnimationPlugin,
HalfFloatType,
HDRiGroundPlugin,
Expand Down Expand Up @@ -64,7 +65,7 @@ async function init() {
new ProgressivePlugin(),
GLTFAnimationPlugin,
PickingPlugin,
TransformControlsPlugin,
new TransformControlsPlugin(false),
EditorViewWidgetPlugin,
CameraViewPlugin,
ViewerUiConfigPlugin,
Expand All @@ -74,7 +75,8 @@ async function init() {
CustomBumpMapPlugin,
VirtualCamerasPlugin,
// new SceneUiConfigPlugin(), // this is already in ViewerUiPlugin
new DepthBufferPlugin(HalfFloatType, true, true),
new GBufferPlugin(HalfFloatType, true, true, true),
new DepthBufferPlugin(HalfFloatType, false, false),
new NormalBufferPlugin(HalfFloatType, false),
new RenderTargetPreviewPlugin(false),
new FrameFadePlugin(),
Expand All @@ -97,13 +99,15 @@ async function init() {
])

const rt = viewer.getOrAddPluginSync(RenderTargetPreviewPlugin)
rt.addTarget({texture: viewer.getPlugin(GBufferPlugin)?.normalDepthTexture}, 'normalDepth')
rt.addTarget({texture: viewer.getPlugin(GBufferPlugin)?.flagsTexture}, 'gBufferFlags')
rt.addTarget(viewer.getPlugin(DepthBufferPlugin)?.target, 'depth', false, false, false)
rt.addTarget(viewer.getPlugin(NormalBufferPlugin)?.target, 'normal', false, true, false)

editor.loadPlugins({
['Viewer']: [ViewerUiConfigPlugin, SceneUiConfigPlugin, DropzonePlugin, FullScreenPlugin, TweakpaneUiPlugin],
['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin],
['GBuffer']: [DepthBufferPlugin, NormalBufferPlugin],
['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin],
['Post-processing']: [TonemapPlugin, ProgressivePlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin],
['Animation']: [GLTFAnimationPlugin, CameraViewPlugin],
['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin],
Expand Down
56 changes: 28 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fd88dc8

Please sign in to comment.