diff --git a/src/editor/assets/assets-migrate.ts b/src/editor/assets/assets-migrate.ts index 8bc5d6439..9e35977bc 100644 --- a/src/editor/assets/assets-migrate.ts +++ b/src/editor/assets/assets-migrate.ts @@ -151,6 +151,10 @@ editor.once('load', () => { asset.set('data.alphaToCoverage', false); } + if (!asset.has('data.twoSidedLighting')) { + asset.set('data.twoSidedLighting', false); + } + if (!asset.has('data.opacityFadesSpecular')) { asset.set('data.opacityFadesSpecular', true); } diff --git a/src/editor/attributes/reference/assets/material.ts b/src/editor/attributes/reference/assets/material.ts index d0b3dcff5..9f3075e9f 100644 --- a/src/editor/attributes/reference/assets/material.ts +++ b/src/editor/attributes/reference/assets/material.ts @@ -1321,4 +1321,10 @@ export const fields: AttributeReference[] = [{ subTitle: '{Number}', description: 'Use alphaFade to fade out materials that do not use opacity to fade specular (opacityFadesSpecular is false).', url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#alphafade' +}, { + name: 'asset:material:twoSidedLighting', + title: 'twoSidedLighting', + subTitle: '{Boolean}', + description: 'Calculate proper normals on the backface. When cull mode is set to None, this enables lighting to be calculated for the backside of the mesh.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#twosidedlighting' }]; diff --git a/src/editor/attributes/reference/components/light.ts b/src/editor/attributes/reference/components/light.ts index f386825f7..f5f2ab39f 100644 --- a/src/editor/attributes/reference/components/light.ts +++ b/src/editor/attributes/reference/components/light.ts @@ -231,6 +231,12 @@ export const fields: AttributeReference[] = [{ subTitle: '{pc.Vec2}', description: 'Spotlight cookie scale.', url: 'https://api.playcanvas.com/engine/classes/LightComponent.html#cookiescale' +}, { + name: 'light:penumbraSize', + title: 'penumbraSize', + subTitle: '{Number}', + description: 'The size of the penumbra for PCSS (Percentage Closer Soft Shadows). A larger value produces softer shadow edges. Only applies when shadows are enabled.', + url: 'https://api.playcanvas.com/engine/classes/LightComponent.html#penumbrasize' }, { name: 'light:layers', title: 'layers', diff --git a/src/editor/attributes/reference/components/rigidbody.ts b/src/editor/attributes/reference/components/rigidbody.ts index b928f3fc8..777f37cf4 100644 --- a/src/editor/attributes/reference/components/rigidbody.ts +++ b/src/editor/attributes/reference/components/rigidbody.ts @@ -65,4 +65,10 @@ export const fields: AttributeReference[] = [{
  • Kinematic (pc.BODYTYPE_KINEMATIC): Controlled by code. Not affected by physics but can push dynamic bodies.
  • `, url: 'https://api.playcanvas.com/engine/classes/RigidBodyComponent.html#type' +}, { + name: 'rigidbody:rollingFriction', + title: 'rollingFriction', + subTitle: '{Number}', + description: 'Sets a torsional friction orthogonal to the contact point. This prevents round objects (spheres, cylinders) from rolling indefinitely.', + url: 'https://api.playcanvas.com/engine/classes/RigidBodyComponent.html#rollingfriction' }]; diff --git a/src/editor/attributes/reference/settings.ts b/src/editor/attributes/reference/settings.ts index cd0480d49..85daaa5e4 100644 --- a/src/editor/attributes/reference/settings.ts +++ b/src/editor/attributes/reference/settings.ts @@ -158,6 +158,12 @@ editor.once('load', () => { subTitle: '{Number}', description: 'Mip level of the prefiltered skybox. Higher values select lower-resolution, more prefiltered (blurred) mips.', url: 'https://api.playcanvas.com/engine/classes/Scene.html#skyboxmip' + }, { + name: 'settings:skyDepthWrite', + title: 'skyDepthWrite', + subTitle: '{Boolean}', + description: 'Whether the sky writes to the depth buffer. Disable to allow 3D geometry to render on top of the sky.', + url: 'https://api.playcanvas.com/engine/classes/Scene.html#sky' }, { name: 'settings:skyboxRotation', title: 'skyboxRotation', diff --git a/src/editor/entities/entities-migrations.ts b/src/editor/entities/entities-migrations.ts index 0629e371b..b7d1486b4 100644 --- a/src/editor/entities/entities-migrations.ts +++ b/src/editor/entities/entities-migrations.ts @@ -124,6 +124,11 @@ editor.once('load', () => { entity.set('components.light.vsmBias', 0.01 * 0.25); } + // penumbraSize + if (!entity.has('components.light.penumbraSize')) { + entity.set('components.light.penumbraSize', 1); + } + // cookieAsset if (!entity.has('components.light.cookieAsset')) { entity.set('components.light.cookieAsset', null); @@ -171,6 +176,14 @@ editor.once('load', () => { } } + // rigidbody + if (entity.has('components.rigidbody')) { + // rollingFriction + if (!entity.has('components.rigidbody.rollingFriction')) { + entity.set('components.rigidbody.rollingFriction', 0); + } + } + // model if (entity.has('components.model')) { // isStatic diff --git a/src/editor/inspector/assets/material.ts b/src/editor/inspector/assets/material.ts index a132bdccc..864c325fe 100644 --- a/src/editor/inspector/assets/material.ts +++ b/src/editor/inspector/assets/material.ts @@ -882,6 +882,11 @@ const OTHER_ATTRIBUTES: (Attribute | Divider)[] = [{ }] }, reference: 'asset:material:cull' +}, { + label: 'Two Sided Lighting', + path: 'data.twoSidedLighting', + type: 'boolean', + reference: 'asset:material:twoSidedLighting' }, { label: 'Use Fog', path: 'data.useFog', diff --git a/src/editor/inspector/components/light.ts b/src/editor/inspector/components/light.ts index 96aad5106..7423f792c 100644 --- a/src/editor/inspector/components/light.ts +++ b/src/editor/inspector/components/light.ts @@ -6,6 +6,7 @@ import { SHADOW_PCF1_32F, SHADOW_PCF3_32F, SHADOW_PCF5_32F, + SHADOW_PCSS_32F, SHADOW_VSM_16F, SHADOW_VSM_32F, SHADOWUPDATE_REALTIME, @@ -336,6 +337,16 @@ const ATTRIBUTES: (Attribute | Divider)[] = [{ precision: 3, step: 0.001 } +}, { + label: 'Penumbra Size', + path: 'components.light.penumbraSize', + reference: 'light:penumbraSize', + type: 'number', + args: { + precision: 2, + step: 0.1, + min: 0 + } }, { type: 'divider', alias: 'components.light.cookieDivider' @@ -589,6 +600,8 @@ class LightComponentInspector extends ComponentInspector { this._field(field).parent.hidden = !castShadows || shadowTypeVsm; }); + this._field('penumbraSize').parent.hidden = !castShadows || shadowType !== SHADOW_PCSS_32F; + this._btnUpdateShadow.hidden = this._field('shadowUpdateMode').value !== SHADOWUPDATE_THISFRAME; } diff --git a/src/editor/inspector/components/rigidbody.ts b/src/editor/inspector/components/rigidbody.ts index fd86e0ea7..772758f8f 100644 --- a/src/editor/inspector/components/rigidbody.ts +++ b/src/editor/inspector/components/rigidbody.ts @@ -97,6 +97,16 @@ const ATTRIBUTES: Attribute[] = [{ min: 0, max: 1 } +}, { + label: 'Rolling Friction', + path: 'components.rigidbody.rollingFriction', + reference: 'rigidbody:rollingFriction', + type: 'number', + args: { + precision: 2, + step: 0.01, + min: 0 + } }]; class RigidbodyComponentInspector extends ComponentInspector { diff --git a/src/editor/inspector/settings-panels/rendering.ts b/src/editor/inspector/settings-panels/rendering.ts index 5b7644e76..7b17b4160 100644 --- a/src/editor/inspector/settings-panels/rendering.ts +++ b/src/editor/inspector/settings-panels/rendering.ts @@ -143,6 +143,13 @@ const ATTRIBUTES: (Attribute | Divider)[] = [ ] } }, + { + observer: 'sceneSettings', + label: 'Sky Depth Write', + path: 'render.skyDepthWrite', + reference: 'settings:skyDepthWrite', + type: 'boolean' + }, { type: 'divider' }, diff --git a/src/editor/viewport/viewport-scene-settings.ts b/src/editor/viewport/viewport-scene-settings.ts index f1bd47f3d..1503c3f9e 100644 --- a/src/editor/viewport/viewport-scene-settings.ts +++ b/src/editor/viewport/viewport-scene-settings.ts @@ -20,6 +20,12 @@ editor.once('load', () => { // apply scene settings app.applySceneSettings(sceneSettings.json()); + // apply sky depth write (not yet handled by engine's applySettings) + const skyDepthWrite = sceneSettings.get('render.skyDepthWrite'); + if (skyDepthWrite !== undefined) { + app.scene.sky.depthWrite = skyDepthWrite; + } + // need to update all materials on scene settings change app.assets.filter((asset) => { return asset.type === 'material' && asset.resource; diff --git a/src/launch/viewport/viewport-binding-scene.ts b/src/launch/viewport/viewport-binding-scene.ts index 3d511e819..a62d05653 100644 --- a/src/launch/viewport/viewport-binding-scene.ts +++ b/src/launch/viewport/viewport-binding-scene.ts @@ -12,6 +12,12 @@ editor.once('load', () => { updating = false; app.applySceneSettings(sceneSettings.json()); + + // apply sky depth write (not yet handled by engine's applySettings) + const skyDepthWrite = sceneSettings.get('render.skyDepthWrite'); + if (skyDepthWrite !== undefined) { + app.scene.sky.depthWrite = skyDepthWrite; + } }; // queue settings apply