From aa519f3de6da5654f8f3792bcf9149f381ecc6dd Mon Sep 17 00:00:00 2001 From: kpal Date: Fri, 13 Feb 2026 14:03:43 +0000 Subject: [PATCH 1/2] feat: expose new engine properties in editor UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose the following engine properties that were previously missing from the Editor frontend: Material: - twoSidedLighting (boolean) — backface normal calculation - diffuseDetailMap / normalDetailMap — detail texture maps with UV, channel, offset, tiling, rotation sub-properties - diffuseDetailMode (string enum) — detail map blend mode - normalDetailMapBumpiness (slider) — detail normal intensity Components: - light.penumbraSize (number) — PCSS soft shadow edge size - rigidbody.rollingFriction (number) — torsional friction - gsplat.unified (boolean) — unified splat rendering path Scene Settings: - render.skyDepthWrite (boolean) — sky depth buffer writes Includes attribute references, asset/entity migrations, visibility gating for engine feature availability, and editor-side application of skyDepthWrite to scene.sky.depthWrite. Refs #1750 Co-authored-by: Cursor --- src/editor/assets/assets-migrate.ts | 12 +++ .../attributes/reference/assets/material.ts | 84 +++++++++++++++++++ .../attributes/reference/components/gsplat.ts | 6 ++ .../attributes/reference/components/light.ts | 6 ++ .../reference/components/rigidbody.ts | 6 ++ src/editor/attributes/reference/settings.ts | 6 ++ src/editor/entities/entities-migrations.ts | 21 +++++ src/editor/inspector/assets/material.ts | 74 +++++++++++++++- src/editor/inspector/components/gsplat.ts | 8 ++ src/editor/inspector/components/light.ts | 12 +++ src/editor/inspector/components/rigidbody.ts | 10 +++ .../inspector/settings-panels/rendering.ts | 7 ++ .../viewport/viewport-scene-settings.ts | 6 ++ src/launch/viewport/viewport-binding-scene.ts | 6 ++ 14 files changed, 261 insertions(+), 3 deletions(-) diff --git a/src/editor/assets/assets-migrate.ts b/src/editor/assets/assets-migrate.ts index 8bc5d6439..6ac390859 100644 --- a/src/editor/assets/assets-migrate.ts +++ b/src/editor/assets/assets-migrate.ts @@ -151,6 +151,18 @@ editor.once('load', () => { asset.set('data.alphaToCoverage', false); } + if (!asset.has('data.twoSidedLighting')) { + asset.set('data.twoSidedLighting', false); + } + + if (!asset.has('data.diffuseDetailMode')) { + asset.set('data.diffuseDetailMode', 'mul'); + } + + if (!asset.has('data.normalDetailMapBumpiness')) { + asset.set('data.normalDetailMapBumpiness', 1); + } + 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..aeb028547 100644 --- a/src/editor/attributes/reference/assets/material.ts +++ b/src/editor/attributes/reference/assets/material.ts @@ -1321,4 +1321,88 @@ 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:diffuseDetailMap', + title: 'diffuseDetailMap', + subTitle: '{pc.Texture}', + description: 'A detail map that is blended with the diffuse color of the material.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmap' +}, { + name: 'asset:material:diffuseDetailMapUv', + title: 'diffuseDetailMapUv', + subTitle: '{Number}', + description: 'The UV channel for the diffuse detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmapuv' +}, { + name: 'asset:material:diffuseDetailMapChannel', + title: 'diffuseDetailMapChannel', + subTitle: '{String}', + description: 'Color channel of the diffuse detail map to use.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmapchannel' +}, { + name: 'asset:material:diffuseDetailMapOffset', + title: 'diffuseDetailMapOffset', + subTitle: '{pc.Vec2}', + description: 'Controls the 2D offset of the diffuse detail map. Each component is between 0 and 1.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmapoffset' +}, { + name: 'asset:material:diffuseDetailMapTiling', + title: 'diffuseDetailMapTiling', + subTitle: '{pc.Vec2}', + description: 'Controls the 2D tiling of the diffuse detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmaptiling' +}, { + name: 'asset:material:diffuseDetailMapRotation', + title: 'diffuseDetailMapRotation', + subTitle: '{Number}', + description: 'Controls the 2D rotation (in degrees) of the diffuse detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmaprotation' +}, { + name: 'asset:material:diffuseDetailMode', + title: 'diffuseDetailMode', + subTitle: '{String}', + description: 'Determines how the diffuse detail map is blended with the diffuse map. Can be: mul, add, screen, overlay, min, max.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmode' +}, { + name: 'asset:material:normalDetailMap', + title: 'normalDetailMap', + subTitle: '{pc.Texture}', + description: 'A detail normal map that is blended with the main normal map of the material.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmap' +}, { + name: 'asset:material:normalDetailMapUv', + title: 'normalDetailMapUv', + subTitle: '{Number}', + description: 'The UV channel for the normal detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmapuv' +}, { + name: 'asset:material:normalDetailMapOffset', + title: 'normalDetailMapOffset', + subTitle: '{pc.Vec2}', + description: 'Controls the 2D offset of the normal detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmapoffset' +}, { + name: 'asset:material:normalDetailMapTiling', + title: 'normalDetailMapTiling', + subTitle: '{pc.Vec2}', + description: 'Controls the 2D tiling of the normal detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmaptiling' +}, { + name: 'asset:material:normalDetailMapRotation', + title: 'normalDetailMapRotation', + subTitle: '{Number}', + description: 'Controls the 2D rotation (in degrees) of the normal detail map.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmaprotation' +}, { + name: 'asset:material:normalDetailMapBumpiness', + title: 'normalDetailMapBumpiness', + subTitle: '{Number}', + description: 'The bumpiness of the normal detail map. This value scales the impact of the normal detail map on the surface.', + url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmapbumpiness' +}, { + 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/gsplat.ts b/src/editor/attributes/reference/components/gsplat.ts index 2ca7e0cec..d7bc3b200 100644 --- a/src/editor/attributes/reference/components/gsplat.ts +++ b/src/editor/attributes/reference/components/gsplat.ts @@ -15,4 +15,10 @@ export const fields: AttributeReference[] = [{ title: 'layers', subTitle: '{Number[]}', description: 'The layers to which the gaussian splats should belong.' +}, { + name: 'gsplat:unified', + title: 'unified', + subTitle: '{Boolean}', + description: 'Whether to use the unified splat rendering path. When enabled, splats are rendered as part of the standard rendering pipeline, allowing them to be properly sorted and blended with mesh-based geometry.', + url: 'https://api.playcanvas.com/engine/classes/GSplatComponent.html#unified' }]; 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..8d831c234 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,22 @@ editor.once('load', () => { } } + // rigidbody + if (entity.has('components.rigidbody')) { + // rollingFriction + if (!entity.has('components.rigidbody.rollingFriction')) { + entity.set('components.rigidbody.rollingFriction', 0); + } + } + + // gsplat + if (entity.has('components.gsplat')) { + // unified + if (!entity.has('components.gsplat.unified')) { + entity.set('components.gsplat.unified', false); + } + } + // 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..e475dce94 100644 --- a/src/editor/inspector/assets/material.ts +++ b/src/editor/inspector/assets/material.ts @@ -790,6 +790,45 @@ const IRIDESCENCE_ATTRIBUTES: (Attribute | Divider)[] = [{ } }]; +const DETAIL_ATTRIBUTES: (Attribute | Divider)[] = [ + ...createTextureAttribute('Diffuse Detail', 'diffuseDetail', TextureTypes.Color), { + label: 'Diffuse Detail Mode', + path: 'data.diffuseDetailMode', + type: 'select', + args: { + type: 'string', + options: [{ + v: 'mul', t: 'Multiply' + }, { + v: 'add', t: 'Add' + }, { + v: 'screen', t: 'Screen' + }, { + v: 'overlay', t: 'Overlay' + }, { + v: 'min', t: 'Min' + }, { + v: 'max', t: 'Max' + }] + }, + reference: 'asset:material:diffuseDetailMode' + }, { + type: 'divider' + }, + ...createTextureAttribute('Normal Detail', 'normalDetail', TextureTypes.Normal), { + label: 'Normal Detail Map Bump', + path: 'data.normalDetailMapBumpiness', + type: 'slider', + args: { + precision: 3, + step: 0.01, + min: 0, + max: 2 + }, + reference: 'asset:material:normalDetailMapBumpiness' + } +]; + const ENVIRONMENT_ATTRIBUTES: (Attribute | Divider)[] = [{ label: 'Sphere Map', path: 'data.sphereMap', @@ -882,6 +921,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', @@ -1060,6 +1104,21 @@ const DOM = parent => [{ attributes: PARALLAX_ATTRIBUTES }) }] +}, { + root: { + detailPanel: new Panel({ + headerText: 'DETAIL', + collapsible: true, + collapsed: true + }) + }, + children: [{ + detailInspector: new AttributesInspector({ + assets: parent._args.assets, + history: parent._args.history, + attributes: DETAIL_ATTRIBUTES + }) + }] }, { root: { clearCoatPanel: new Panel({ @@ -1205,7 +1264,9 @@ const MAPS = { 'refraction': ['refractionInspector'], 'thickness': ['refractionInspector'], 'iridescence': ['iridescenceInspector'], - 'iridescenceThickness': ['iridescenceInspector'] + 'iridescenceThickness': ['iridescenceInspector'], + 'diffuseDetail': ['detailInspector'], + 'normalDetail': ['detailInspector'] }; const COLLAPSED_PANEL_DEPENDENCIES = { @@ -1220,7 +1281,8 @@ const COLLAPSED_PANEL_DEPENDENCIES = { '_normalsPanel': ['normalMap'], '_parallaxPanel': ['heightMap'], '_envPanel': ['sphereMap', 'cubeMap'], - '_lightmapPanel': ['lightMap'] + '_lightmapPanel': ['lightMap'], + '_detailPanel': ['diffuseDetailMap', 'normalDetailMap'] }; const BULK_SLOTS = { @@ -1243,7 +1305,9 @@ const BULK_SLOTS = { 'opacity': ['o', 't', 'opacity', 'alpha', 'transparency', 'gmat', 'gmao', 'gmaa', 'rgba', 'rmat', 'rmao', 'rmaa'], 'normal': ['n', 'norm', 'normal', 'normals'], 'height': ['p', 'h', 'height', 'parallax', 'bump'], - 'light': ['l', 'lm', 'light', 'lightmap'] + 'light': ['l', 'lm', 'light', 'lightmap'], + 'diffuseDetail': ['dd', 'diffusedetail', 'detaildiffuse'], + 'normalDetail': ['nd', 'normaldetail', 'detailnormal'] }; const POSTFIX_TO_BULK_SLOT = {}; @@ -1283,6 +1347,8 @@ class MaterialAssetInspector extends Container { this._opacityInspector.getField('data.opacityShadowDither').parent.hidden = !pathExists(pc, 'StandardMaterial.prototype.opacityShadowDither'); this._refractionInspector.getField('data.dispersion').parent.hidden = !pathExists(pc, 'StandardMaterial.prototype.dispersion'); this._ambientInspector.getField('data.aoIntensity').parent.hidden = !pathExists(pc, 'StandardMaterial.prototype.aoIntensity'); + this._detailInspector.getField('data.diffuseDetailMap').hidden = !pathExists(pc, 'StandardMaterial.prototype.diffuseDetailMap'); + this._detailInspector.getField('data.normalDetailMap').hidden = !pathExists(pc, 'StandardMaterial.prototype.normalDetailMap'); // separated out because it needs more work before release if (!editor.call('users:hasFlag', 'hasAnisoGGXSpec')) { @@ -2176,6 +2242,7 @@ class MaterialAssetInspector extends Container { this._opacityInspector.link(assets); this._normalsInspector.link(assets); this._parallaxInspector.link(assets); + this._detailInspector.link(assets); this._envInspector.link(assets); this._lightmapInspector.link(assets); this._otherInspector.link(assets); @@ -2302,6 +2369,7 @@ class MaterialAssetInspector extends Container { this._opacityInspector.unlink(); this._normalsInspector.unlink(); this._parallaxInspector.unlink(); + this._detailInspector.unlink(); this._envInspector.unlink(); this._lightmapInspector.unlink(); this._otherInspector.unlink(); diff --git a/src/editor/inspector/components/gsplat.ts b/src/editor/inspector/components/gsplat.ts index 003390120..eddc2b6e9 100644 --- a/src/editor/inspector/components/gsplat.ts +++ b/src/editor/inspector/components/gsplat.ts @@ -1,5 +1,6 @@ import { LAYERID_DEPTH, LAYERID_SKYBOX, LAYERID_IMMEDIATE } from 'playcanvas'; +import { pathExists } from '@/common/utils'; import { ComponentInspector } from './component'; import type { Attribute } from '../attribute.type.d'; import { AttributesInspector } from '../attributes-inspector'; @@ -25,6 +26,11 @@ const ATTRIBUTES: Attribute[] = [{ LAYERID_IMMEDIATE ] } +}, { + label: 'Unified', + path: 'components.gsplat.unified', + reference: 'gsplat:unified', + type: 'boolean' }]; class GSplatComponentInspector extends ComponentInspector { @@ -45,6 +51,8 @@ class GSplatComponentInspector extends ComponentInspector { templateOverridesInspector: this._templateOverridesInspector }); this.append(this._attributesInspector); + + this._field('unified').parent.hidden = !pathExists(pc, 'GSplatComponent.prototype.unified'); } _field(name) { diff --git a/src/editor/inspector/components/light.ts b/src/editor/inspector/components/light.ts index 96aad5106..1fa3736f1 100644 --- a/src/editor/inspector/components/light.ts +++ b/src/editor/inspector/components/light.ts @@ -336,6 +336,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 +599,8 @@ class LightComponentInspector extends ComponentInspector { this._field(field).parent.hidden = !castShadows || shadowTypeVsm; }); + this._field('penumbraSize').parent.hidden = !castShadows; + 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 From 4ee93d75c6fa1cb049a9311d766f62b187ec9c95 Mon Sep 17 00:00:00 2001 From: kpal Date: Fri, 13 Feb 2026 14:08:28 +0000 Subject: [PATCH 2/2] feat: expose new engine properties in editor UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose the following engine properties that were previously missing from the Editor frontend: Material: - twoSidedLighting (boolean) — backface normal calculation Components: - light.penumbraSize (number) — PCSS soft shadow edge size - rigidbody.rollingFriction (number) — torsional friction Scene Settings: - render.skyDepthWrite (boolean) — sky depth buffer writes Includes attribute references, asset/entity migrations, visibility gating for engine feature availability, and editor-side application of skyDepthWrite to scene.sky.depthWrite. Refs #1750 Co-authored-by: Cursor --- src/editor/assets/assets-migrate.ts | 8 -- .../attributes/reference/assets/material.ts | 78 ------------------- .../attributes/reference/components/gsplat.ts | 6 -- src/editor/entities/entities-migrations.ts | 8 -- src/editor/inspector/assets/material.ts | 69 +--------------- src/editor/inspector/components/gsplat.ts | 8 -- src/editor/inspector/components/light.ts | 3 +- 7 files changed, 5 insertions(+), 175 deletions(-) diff --git a/src/editor/assets/assets-migrate.ts b/src/editor/assets/assets-migrate.ts index 6ac390859..9e35977bc 100644 --- a/src/editor/assets/assets-migrate.ts +++ b/src/editor/assets/assets-migrate.ts @@ -155,14 +155,6 @@ editor.once('load', () => { asset.set('data.twoSidedLighting', false); } - if (!asset.has('data.diffuseDetailMode')) { - asset.set('data.diffuseDetailMode', 'mul'); - } - - if (!asset.has('data.normalDetailMapBumpiness')) { - asset.set('data.normalDetailMapBumpiness', 1); - } - 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 aeb028547..9f3075e9f 100644 --- a/src/editor/attributes/reference/assets/material.ts +++ b/src/editor/attributes/reference/assets/material.ts @@ -1321,84 +1321,6 @@ 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:diffuseDetailMap', - title: 'diffuseDetailMap', - subTitle: '{pc.Texture}', - description: 'A detail map that is blended with the diffuse color of the material.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmap' -}, { - name: 'asset:material:diffuseDetailMapUv', - title: 'diffuseDetailMapUv', - subTitle: '{Number}', - description: 'The UV channel for the diffuse detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmapuv' -}, { - name: 'asset:material:diffuseDetailMapChannel', - title: 'diffuseDetailMapChannel', - subTitle: '{String}', - description: 'Color channel of the diffuse detail map to use.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmapchannel' -}, { - name: 'asset:material:diffuseDetailMapOffset', - title: 'diffuseDetailMapOffset', - subTitle: '{pc.Vec2}', - description: 'Controls the 2D offset of the diffuse detail map. Each component is between 0 and 1.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmapoffset' -}, { - name: 'asset:material:diffuseDetailMapTiling', - title: 'diffuseDetailMapTiling', - subTitle: '{pc.Vec2}', - description: 'Controls the 2D tiling of the diffuse detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmaptiling' -}, { - name: 'asset:material:diffuseDetailMapRotation', - title: 'diffuseDetailMapRotation', - subTitle: '{Number}', - description: 'Controls the 2D rotation (in degrees) of the diffuse detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmaprotation' -}, { - name: 'asset:material:diffuseDetailMode', - title: 'diffuseDetailMode', - subTitle: '{String}', - description: 'Determines how the diffuse detail map is blended with the diffuse map. Can be: mul, add, screen, overlay, min, max.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#diffusedetailmode' -}, { - name: 'asset:material:normalDetailMap', - title: 'normalDetailMap', - subTitle: '{pc.Texture}', - description: 'A detail normal map that is blended with the main normal map of the material.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmap' -}, { - name: 'asset:material:normalDetailMapUv', - title: 'normalDetailMapUv', - subTitle: '{Number}', - description: 'The UV channel for the normal detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmapuv' -}, { - name: 'asset:material:normalDetailMapOffset', - title: 'normalDetailMapOffset', - subTitle: '{pc.Vec2}', - description: 'Controls the 2D offset of the normal detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmapoffset' -}, { - name: 'asset:material:normalDetailMapTiling', - title: 'normalDetailMapTiling', - subTitle: '{pc.Vec2}', - description: 'Controls the 2D tiling of the normal detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmaptiling' -}, { - name: 'asset:material:normalDetailMapRotation', - title: 'normalDetailMapRotation', - subTitle: '{Number}', - description: 'Controls the 2D rotation (in degrees) of the normal detail map.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmaprotation' -}, { - name: 'asset:material:normalDetailMapBumpiness', - title: 'normalDetailMapBumpiness', - subTitle: '{Number}', - description: 'The bumpiness of the normal detail map. This value scales the impact of the normal detail map on the surface.', - url: 'https://api.playcanvas.com/engine/classes/StandardMaterial.html#normaldetailmapbumpiness' }, { name: 'asset:material:twoSidedLighting', title: 'twoSidedLighting', diff --git a/src/editor/attributes/reference/components/gsplat.ts b/src/editor/attributes/reference/components/gsplat.ts index d7bc3b200..2ca7e0cec 100644 --- a/src/editor/attributes/reference/components/gsplat.ts +++ b/src/editor/attributes/reference/components/gsplat.ts @@ -15,10 +15,4 @@ export const fields: AttributeReference[] = [{ title: 'layers', subTitle: '{Number[]}', description: 'The layers to which the gaussian splats should belong.' -}, { - name: 'gsplat:unified', - title: 'unified', - subTitle: '{Boolean}', - description: 'Whether to use the unified splat rendering path. When enabled, splats are rendered as part of the standard rendering pipeline, allowing them to be properly sorted and blended with mesh-based geometry.', - url: 'https://api.playcanvas.com/engine/classes/GSplatComponent.html#unified' }]; diff --git a/src/editor/entities/entities-migrations.ts b/src/editor/entities/entities-migrations.ts index 8d831c234..b7d1486b4 100644 --- a/src/editor/entities/entities-migrations.ts +++ b/src/editor/entities/entities-migrations.ts @@ -184,14 +184,6 @@ editor.once('load', () => { } } - // gsplat - if (entity.has('components.gsplat')) { - // unified - if (!entity.has('components.gsplat.unified')) { - entity.set('components.gsplat.unified', false); - } - } - // model if (entity.has('components.model')) { // isStatic diff --git a/src/editor/inspector/assets/material.ts b/src/editor/inspector/assets/material.ts index e475dce94..864c325fe 100644 --- a/src/editor/inspector/assets/material.ts +++ b/src/editor/inspector/assets/material.ts @@ -790,45 +790,6 @@ const IRIDESCENCE_ATTRIBUTES: (Attribute | Divider)[] = [{ } }]; -const DETAIL_ATTRIBUTES: (Attribute | Divider)[] = [ - ...createTextureAttribute('Diffuse Detail', 'diffuseDetail', TextureTypes.Color), { - label: 'Diffuse Detail Mode', - path: 'data.diffuseDetailMode', - type: 'select', - args: { - type: 'string', - options: [{ - v: 'mul', t: 'Multiply' - }, { - v: 'add', t: 'Add' - }, { - v: 'screen', t: 'Screen' - }, { - v: 'overlay', t: 'Overlay' - }, { - v: 'min', t: 'Min' - }, { - v: 'max', t: 'Max' - }] - }, - reference: 'asset:material:diffuseDetailMode' - }, { - type: 'divider' - }, - ...createTextureAttribute('Normal Detail', 'normalDetail', TextureTypes.Normal), { - label: 'Normal Detail Map Bump', - path: 'data.normalDetailMapBumpiness', - type: 'slider', - args: { - precision: 3, - step: 0.01, - min: 0, - max: 2 - }, - reference: 'asset:material:normalDetailMapBumpiness' - } -]; - const ENVIRONMENT_ATTRIBUTES: (Attribute | Divider)[] = [{ label: 'Sphere Map', path: 'data.sphereMap', @@ -1104,21 +1065,6 @@ const DOM = parent => [{ attributes: PARALLAX_ATTRIBUTES }) }] -}, { - root: { - detailPanel: new Panel({ - headerText: 'DETAIL', - collapsible: true, - collapsed: true - }) - }, - children: [{ - detailInspector: new AttributesInspector({ - assets: parent._args.assets, - history: parent._args.history, - attributes: DETAIL_ATTRIBUTES - }) - }] }, { root: { clearCoatPanel: new Panel({ @@ -1264,9 +1210,7 @@ const MAPS = { 'refraction': ['refractionInspector'], 'thickness': ['refractionInspector'], 'iridescence': ['iridescenceInspector'], - 'iridescenceThickness': ['iridescenceInspector'], - 'diffuseDetail': ['detailInspector'], - 'normalDetail': ['detailInspector'] + 'iridescenceThickness': ['iridescenceInspector'] }; const COLLAPSED_PANEL_DEPENDENCIES = { @@ -1281,8 +1225,7 @@ const COLLAPSED_PANEL_DEPENDENCIES = { '_normalsPanel': ['normalMap'], '_parallaxPanel': ['heightMap'], '_envPanel': ['sphereMap', 'cubeMap'], - '_lightmapPanel': ['lightMap'], - '_detailPanel': ['diffuseDetailMap', 'normalDetailMap'] + '_lightmapPanel': ['lightMap'] }; const BULK_SLOTS = { @@ -1305,9 +1248,7 @@ const BULK_SLOTS = { 'opacity': ['o', 't', 'opacity', 'alpha', 'transparency', 'gmat', 'gmao', 'gmaa', 'rgba', 'rmat', 'rmao', 'rmaa'], 'normal': ['n', 'norm', 'normal', 'normals'], 'height': ['p', 'h', 'height', 'parallax', 'bump'], - 'light': ['l', 'lm', 'light', 'lightmap'], - 'diffuseDetail': ['dd', 'diffusedetail', 'detaildiffuse'], - 'normalDetail': ['nd', 'normaldetail', 'detailnormal'] + 'light': ['l', 'lm', 'light', 'lightmap'] }; const POSTFIX_TO_BULK_SLOT = {}; @@ -1347,8 +1288,6 @@ class MaterialAssetInspector extends Container { this._opacityInspector.getField('data.opacityShadowDither').parent.hidden = !pathExists(pc, 'StandardMaterial.prototype.opacityShadowDither'); this._refractionInspector.getField('data.dispersion').parent.hidden = !pathExists(pc, 'StandardMaterial.prototype.dispersion'); this._ambientInspector.getField('data.aoIntensity').parent.hidden = !pathExists(pc, 'StandardMaterial.prototype.aoIntensity'); - this._detailInspector.getField('data.diffuseDetailMap').hidden = !pathExists(pc, 'StandardMaterial.prototype.diffuseDetailMap'); - this._detailInspector.getField('data.normalDetailMap').hidden = !pathExists(pc, 'StandardMaterial.prototype.normalDetailMap'); // separated out because it needs more work before release if (!editor.call('users:hasFlag', 'hasAnisoGGXSpec')) { @@ -2242,7 +2181,6 @@ class MaterialAssetInspector extends Container { this._opacityInspector.link(assets); this._normalsInspector.link(assets); this._parallaxInspector.link(assets); - this._detailInspector.link(assets); this._envInspector.link(assets); this._lightmapInspector.link(assets); this._otherInspector.link(assets); @@ -2369,7 +2307,6 @@ class MaterialAssetInspector extends Container { this._opacityInspector.unlink(); this._normalsInspector.unlink(); this._parallaxInspector.unlink(); - this._detailInspector.unlink(); this._envInspector.unlink(); this._lightmapInspector.unlink(); this._otherInspector.unlink(); diff --git a/src/editor/inspector/components/gsplat.ts b/src/editor/inspector/components/gsplat.ts index eddc2b6e9..003390120 100644 --- a/src/editor/inspector/components/gsplat.ts +++ b/src/editor/inspector/components/gsplat.ts @@ -1,6 +1,5 @@ import { LAYERID_DEPTH, LAYERID_SKYBOX, LAYERID_IMMEDIATE } from 'playcanvas'; -import { pathExists } from '@/common/utils'; import { ComponentInspector } from './component'; import type { Attribute } from '../attribute.type.d'; import { AttributesInspector } from '../attributes-inspector'; @@ -26,11 +25,6 @@ const ATTRIBUTES: Attribute[] = [{ LAYERID_IMMEDIATE ] } -}, { - label: 'Unified', - path: 'components.gsplat.unified', - reference: 'gsplat:unified', - type: 'boolean' }]; class GSplatComponentInspector extends ComponentInspector { @@ -51,8 +45,6 @@ class GSplatComponentInspector extends ComponentInspector { templateOverridesInspector: this._templateOverridesInspector }); this.append(this._attributesInspector); - - this._field('unified').parent.hidden = !pathExists(pc, 'GSplatComponent.prototype.unified'); } _field(name) { diff --git a/src/editor/inspector/components/light.ts b/src/editor/inspector/components/light.ts index 1fa3736f1..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, @@ -599,7 +600,7 @@ class LightComponentInspector extends ComponentInspector { this._field(field).parent.hidden = !castShadows || shadowTypeVsm; }); - this._field('penumbraSize').parent.hidden = !castShadows; + this._field('penumbraSize').parent.hidden = !castShadows || shadowType !== SHADOW_PCSS_32F; this._btnUpdateShadow.hidden = this._field('shadowUpdateMode').value !== SHADOWUPDATE_THISFRAME; }