Skip to content

Commit

Permalink
Updated the Particles Snow example with depth softening (#7106)
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
  • Loading branch information
mvaligursky and Martin Valigursky authored Nov 13, 2024
1 parent fb5962c commit 00e2f02
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 11 deletions.
23 changes: 23 additions & 0 deletions examples/src/examples/graphics/particles-snow.controls.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @param {import('../../app/components/Example.mjs').ControlOptions} options - The options.
* @returns {JSX.Element} The returned JSX Element.
*/
export const controls = ({ observer, ReactPCUI, React, jsx, fragment }) => {
const { BindingTwoWay, LabelGroup, Panel, BooleanInput } = ReactPCUI;
return fragment(
jsx(
Panel,
{ headerText: 'Options' },
jsx(
LabelGroup,
{ text: 'Soft' },
jsx(BooleanInput, {
type: 'toggle',
binding: new BindingTwoWay(),
link: { observer, path: 'data.soft' },
value: observer.get('data.soft')
})
)
)
);
};
61 changes: 50 additions & 11 deletions examples/src/examples/graphics/particles-snow.example.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as pc from 'playcanvas';
import { data } from 'examples/observer';
import { deviceType, rootPath } from 'examples/utils';

const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById('application-canvas'));
window.focus();

const assets = {
orbit: new pc.Asset('script', 'script', { url: rootPath + '/static/scripts/camera/orbit-camera.js' }),
snowflake: new pc.Asset('snowflake', 'texture', { url: rootPath + '/static/assets/textures/snowflake.png' }, { srgb: true })
};

Expand All @@ -19,16 +21,19 @@ device.maxPixelRatio = Math.min(window.devicePixelRatio, 2);

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,
pc.ParticleSystemComponentSystem
];
createOptions.resourceHandlers = [
// @ts-ignore
pc.TextureHandler
pc.TextureHandler,
pc.ScriptHandler
];

const app = new pc.AppBase(canvas);
Expand All @@ -55,7 +60,19 @@ assetListLoader.load(() => {
clearColor: new pc.Color(0, 0, 0)
});
cameraEntity.rotateLocal(0, 0, 0);
cameraEntity.translateLocal(0, 0, 10);
cameraEntity.translateLocal(0, 7, 10);

// add orbit camera script with a mouse and a touch support
cameraEntity.addComponent('script');
cameraEntity.script.create('orbitCamera', {
attributes: {
inertiaFactor: 0.2,
distanceMax: 190,
frameOnStart: false
}
});
cameraEntity.script.create('orbitCameraInputMouse');
cameraEntity.script.create('orbitCameraInputTouch');

// Create a directional light
const lightDirEntity = new pc.Entity();
Expand Down Expand Up @@ -87,31 +104,53 @@ assetListLoader.load(() => {
const rotCurve2 = new pc.Curve([0, -100]);

// scale is constant at 0.1
const scaleCurve = new pc.Curve([0, 0.1]);
const scaleCurve = new pc.Curve([0, 0.2]);

// Create entity for particle system
const entity = new pc.Entity();
app.root.addChild(entity);
entity.setLocalPosition(0, 3, 0);
entity.setLocalPosition(0, 5, 0);

// load snowflake texture
// app.assets.loadFromUrl(rootPath + '/static/assets/textures/snowflake.png', 'texture', function () {
// when texture is loaded add particlesystem component to entity
entity.addComponent('particlesystem', {
numParticles: 100,
lifetime: 10,
rate: 0.1,
startAngle: 360,
startAngle2: -360,
emitterExtents: new pc.Vec3(5, 0, 0),
emitterExtents: new pc.Vec3(7, 2, 7),
velocityGraph: velocityCurve,
velocityGraph2: velocityCurve2,
scaleGraph: scaleCurve,
rotationSpeedGraph: rotCurve,
rotationSpeedGraph2: rotCurve2,
colorMap: assets.snowflake.resource
colorMap: assets.snowflake.resource,
depthSoftening: 0.08
});

// Create an Entity for the ground
const ground = new pc.Entity();
ground.addComponent('render', {
type: 'cylinder'
});
ground.setLocalScale(10, 0.01, 10);
ground.setLocalPosition(0, 0, 0);
app.root.addChild(ground);

let depthRendering = false;
data.on('*:set', (/** @type {string} */ path, value) => {

// toggle the depth texture for the camera based on the soft parameter
const soft = data.get('data.soft');
if (depthRendering !== soft) {
cameraEntity.camera.requestSceneDepthMap(soft);
depthRendering = soft;
}
});

// initial values
data.set('data', {
soft: true
});
// });
});

export { app };

0 comments on commit 00e2f02

Please sign in to comment.