-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into remove-unbundled-sourcemapping
- Loading branch information
Showing
27 changed files
with
660 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
The house model has been obtained from this address: | ||
https://sketchfab.com/3d-models/house-03-pbr-c56521b89188460a99235dec8bcd0ed3 | ||
|
||
It's distributed under CC license: | ||
https://creativecommons.org/licenses/by/4.0/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* @type {import('../../../../types.mjs').ExampleConfig} | ||
*/ | ||
export default { | ||
WEBGPU_ENABLED: true | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as pc from 'playcanvas'; | ||
|
||
/** | ||
* @param {import('../../../app/components/Example.mjs').ControlOptions} options - The options. | ||
* @returns {JSX.Element} The returned JSX Element. | ||
*/ | ||
export function controls({ observer, ReactPCUI, React, jsx, fragment }) { | ||
const { BindingTwoWay, BooleanInput, LabelGroup, Panel, SliderInput } = ReactPCUI; | ||
return fragment( | ||
jsx( | ||
Panel, | ||
{ headerText: 'Scene Rendering' }, | ||
jsx( | ||
LabelGroup, | ||
{ text: 'resolution' }, | ||
jsx(SliderInput, { | ||
binding: new BindingTwoWay(), | ||
link: { observer, path: 'data.scene.scale' }, | ||
min: 0.5, | ||
max: 1, | ||
precision: 1 | ||
}) | ||
), | ||
jsx( | ||
LabelGroup, | ||
{ text: 'Bloom' }, | ||
jsx(BooleanInput, { | ||
type: 'toggle', | ||
binding: new BindingTwoWay(), | ||
link: { observer, path: 'data.scene.bloom' } | ||
}) | ||
) | ||
), | ||
jsx( | ||
Panel, | ||
{ headerText: 'TAA' }, | ||
jsx( | ||
LabelGroup, | ||
{ text: 'enabled' }, | ||
jsx(BooleanInput, { | ||
type: 'toggle', | ||
binding: new BindingTwoWay(), | ||
link: { observer, path: 'data.taa.enabled' } | ||
}) | ||
), | ||
jsx( | ||
LabelGroup, | ||
{ text: 'jitter' }, | ||
jsx(SliderInput, { | ||
binding: new BindingTwoWay(), | ||
link: { observer, path: 'data.taa.jitter' }, | ||
min: 0, | ||
max: 1, | ||
precision: 2 | ||
}) | ||
) | ||
) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
import * as pc from 'playcanvas'; | ||
import * as pcx from 'playcanvas-extras'; | ||
import { data } from '@examples/observer'; | ||
import { deviceType, rootPath } from '@examples/utils'; | ||
|
||
const canvas = document.getElementById('application-canvas'); | ||
if (!(canvas instanceof HTMLCanvasElement)) { | ||
throw new Error('No canvas found'); | ||
} | ||
|
||
const assets = { | ||
orbit: new pc.Asset('script', 'script', { url: rootPath + '/static/scripts/camera/orbit-camera.js' }), | ||
house: new pc.Asset('house', 'container', { url: rootPath + '/static/assets/models/pbr-house.glb' }), | ||
envatlas: new pc.Asset( | ||
'env-atlas', | ||
'texture', | ||
{ url: rootPath + '/static/assets/cubemaps/table-mountain-env-atlas.png' }, | ||
{ type: pc.TEXTURETYPE_RGBP, mipmaps: false } | ||
) | ||
}; | ||
|
||
const gfxOptions = { | ||
deviceTypes: [deviceType], | ||
glslangUrl: rootPath + '/static/lib/glslang/glslang.js', | ||
twgslUrl: rootPath + '/static/lib/twgsl/twgsl.js', | ||
|
||
// disable anti-aliasing as TAA is used to smooth edges | ||
antialias: false | ||
}; | ||
|
||
const device = await pc.createGraphicsDevice(canvas, gfxOptions); | ||
const createOptions = new pc.AppOptions(); | ||
createOptions.graphicsDevice = device; | ||
createOptions.mouse = new pc.Mouse(document.body); | ||
createOptions.touch = new pc.TouchDevice(document.body); | ||
|
||
createOptions.componentSystems = [ | ||
pc.RenderComponentSystem, | ||
pc.CameraComponentSystem, | ||
pc.LightComponentSystem, | ||
pc.ScriptComponentSystem | ||
]; | ||
createOptions.resourceHandlers = [ | ||
pc.TextureHandler, | ||
pc.ContainerHandler, | ||
pc.ScriptHandler | ||
]; | ||
|
||
const app = new pc.AppBase(canvas); | ||
app.init(createOptions); | ||
|
||
// Set the canvas to fill the window and automatically change resolution to be the same as the canvas size | ||
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW); | ||
app.setCanvasResolution(pc.RESOLUTION_AUTO); | ||
|
||
// Ensure canvas is resized when window changes size | ||
const resize = () => app.resizeCanvas(); | ||
window.addEventListener('resize', resize); | ||
app.on('destroy', () => { | ||
window.removeEventListener('resize', resize); | ||
}); | ||
|
||
const assetListLoader = new pc.AssetListLoader(Object.values(assets), app.assets); | ||
assetListLoader.load(() => { | ||
app.start(); | ||
|
||
// setup skydome with low intensity | ||
app.scene.envAtlas = assets.envatlas.resource; | ||
app.scene.skyboxMip = 0; | ||
app.scene.exposure = 1.0; | ||
|
||
// the render passes render in HDR format, and so disable output tone mapping and gamma correction, | ||
// as that is applied in the final compose pass | ||
app.scene.toneMapping = pc.TONEMAP_LINEAR; | ||
app.scene.gammaCorrection = pc.GAMMA_NONE; | ||
|
||
// create an instance of the house and add it to the scene | ||
const houseEntity = assets.house.resource.instantiateRenderEntity(); | ||
houseEntity.setLocalScale(100, 100, 100); | ||
app.root.addChild(houseEntity); | ||
|
||
// Create an Entity with a camera component | ||
const cameraEntity = new pc.Entity(); | ||
cameraEntity.addComponent('camera', { | ||
nearClip: 10, | ||
farClip: 600, | ||
fov: 80 | ||
}); | ||
|
||
// add orbit camera script with a mouse and a touch support | ||
cameraEntity.addComponent('script'); | ||
cameraEntity.script.create("orbitCamera", { | ||
attributes: { | ||
inertiaFactor: 0.2, | ||
focusEntity: houseEntity, | ||
distanceMax: 400, | ||
frameOnStart: true | ||
} | ||
}); | ||
cameraEntity.script.create("orbitCameraInputMouse"); | ||
cameraEntity.script.create("orbitCameraInputTouch"); | ||
cameraEntity.setLocalPosition(0, 40, -220); | ||
cameraEntity.lookAt(0, 0, 100); | ||
app.root.addChild(cameraEntity); | ||
|
||
// add a shadow casting directional light | ||
const lightColor = new pc.Color(1, 1, 1); | ||
const light = new pc.Entity(); | ||
light.addComponent('light', { | ||
type: 'directional', | ||
color: lightColor, | ||
intensity: 0.2, | ||
range: 700, | ||
shadowResolution: 4096, | ||
shadowDistance: 600, | ||
castShadows: true, | ||
shadowBias: 0.2, | ||
normalOffsetBias: 0.05 | ||
}); | ||
app.root.addChild(light); | ||
light.setLocalEulerAngles(40, 10, 0); | ||
|
||
// ------ Custom render passes set up ------ | ||
|
||
const currentOptions = { | ||
camera: cameraEntity.camera, // camera used to render those passes | ||
samples: 0, // number of samples for multi-sampling | ||
// sceneColorMap: true, // true if the scene color should be captured | ||
sceneColorMap: false, | ||
|
||
// enable the pre-pass to generate the depth buffer, which is needed by the TAA | ||
prepassEnabled: true, | ||
|
||
// enable temporal anti-aliasing | ||
taaEnabled: true | ||
}; | ||
|
||
const setupRenderPass = () => { | ||
// destroy existing pass if any | ||
if (cameraEntity.camera.renderPasses.length > 0) { | ||
cameraEntity.camera.renderPasses[0].destroy(); | ||
} | ||
|
||
// Use a render pass camera frame, which is a render pass that implements typical rendering of a camera. | ||
// Internally this sets up additional passes it needs, based on the options passed to it. | ||
const renderPassCamera = new pcx.RenderPassCameraFrame(app, currentOptions); | ||
|
||
const composePass = renderPassCamera.composePass; | ||
composePass.toneMapping = data.get('data.scene.tonemapping'); | ||
composePass.bloomIntensity = 0.02; | ||
|
||
// and set up these rendering passes to be used by the camera, instead of its default rendering | ||
cameraEntity.camera.renderPasses = [renderPassCamera]; | ||
}; | ||
|
||
// ------ | ||
|
||
const applySettings = () => { | ||
|
||
// if settings require render passes to be re-created | ||
const noPasses = cameraEntity.camera.renderPasses.length === 0; | ||
const taaEnabled = data.get('data.taa.enabled'); | ||
if (noPasses || taaEnabled !== currentOptions.taaEnabled) { | ||
currentOptions.taaEnabled = taaEnabled; | ||
|
||
// create new pass | ||
setupRenderPass(); | ||
} | ||
|
||
|
||
// apply all runtime settings | ||
const renderPassCamera = cameraEntity.camera.renderPasses[0]; | ||
renderPassCamera.renderTargetScale = data.get('data.scene.scale'); | ||
renderPassCamera.bloomEnabled = data.get('data.scene.bloom'); | ||
|
||
// taa - enable camera jitter if taa is enabled | ||
cameraEntity.camera.jitter = taaEnabled ? data.get('data.taa.jitter') : 0; | ||
}; | ||
|
||
// apply UI changes | ||
let initialValuesSetup = false; | ||
data.on('*:set', () => { | ||
if (initialValuesSetup) applySettings(); | ||
}); | ||
|
||
// set initial values | ||
data.set('data', { | ||
scene: { | ||
scale: 1, | ||
bloom: true, | ||
tonemapping: pc.TONEMAP_ACES | ||
}, | ||
taa: { | ||
enabled: currentOptions.taaEnabled, | ||
jitter: 1 | ||
} | ||
}); | ||
|
||
// apply initial settings after all values are set | ||
initialValuesSetup = true; | ||
applySettings(); | ||
}); | ||
|
||
export { app }; |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.