diff --git a/examples/eslint.config.mjs b/examples/eslint.config.mjs index e661a640307..2c28eced7fc 100644 --- a/examples/eslint.config.mjs +++ b/examples/eslint.config.mjs @@ -20,6 +20,7 @@ const booleanFlags = new Set([ ]); const engineTypes = new Set(['development', 'performance', 'debug']); const creditFields = ['title', 'author', 'source', 'license']; +const requiredCreditFields = ['title', 'author']; const creditFieldSet = new Set(creditFields); const splitFlag = (line) => { @@ -134,7 +135,7 @@ const configBlockShape = { return null; } - const missing = creditFields.filter(field => !credit.fields[field]); + const missing = requiredCreditFields.filter(field => !credit.fields[field]); if (missing.length) { report(line, 'missingCreditFields', { fields: missing.join(', ') }); } diff --git a/examples/iframe/runtime.mjs b/examples/iframe/runtime.mjs index 63b163a8c7e..2c49432ed34 100644 --- a/examples/iframe/runtime.mjs +++ b/examples/iframe/runtime.mjs @@ -36,6 +36,7 @@ const moduleUrls = new Map(); const moduleUrlTasks = new Map(); const configRegex = /^[ \t]*\/\/ @config[ \t]*(?:\r?\n[ \t]*\/\/[^\r\n]*)*(?:\r?\n|$)/gm; const CREDIT_FIELDS = ['title', 'author', 'source', 'license']; +const REQUIRED_CREDIT_FIELDS = ['title', 'author']; const CREDIT_FIELD_SET = new Set(CREDIT_FIELDS); const parseValue = (val) => { @@ -52,7 +53,7 @@ const parseExampleConfig = (block, config) => { let credit = null; const completeCredit = () => { - const missing = CREDIT_FIELDS.filter(field => !credit[field]); + const missing = REQUIRED_CREDIT_FIELDS.filter(field => !credit[field]); if (missing.length) { throw new Error(`Incomplete @credit: missing ${missing.join(', ')}`); } @@ -118,7 +119,21 @@ const parseExampleConfig = (block, config) => { completeCredit(); } - const text = description.join('\n').trim(); + const paragraphs = []; + let current = []; + for (const line of description) { + const trimmed = line.trim(); + if (trimmed) { + current.push(trimmed); + } else if (current.length) { + paragraphs.push(current.join(' ')); + current = []; + } + } + if (current.length) { + paragraphs.push(current.join(' ')); + } + const text = paragraphs.join('\n').trim(); if (text) { config.DESCRIPTION = text; } diff --git a/examples/src/app/components/Example.mjs b/examples/src/app/components/Example.mjs index f296b2e4364..341b6894e7b 100644 --- a/examples/src/app/components/Example.mjs +++ b/examples/src/app/components/Example.mjs @@ -493,23 +493,26 @@ class Example extends TypedComponent { * @returns {ReactElement} rendered credit row. */ renderCredit(credit, index) { - const source = URL_IN_TEXT_PATTERN.exec(credit.source); + const source = credit.source ? URL_IN_TEXT_PATTERN.exec(credit.source) : null; const label = fragment( jsx('span', { className: 'example-credit-title' }, credit.title), ' by ', jsx('span', { className: 'example-credit-author' }, credit.author) ); + const children = [source ? this.renderCreditLink(source[1], label) : label]; + if (!source && credit.source) { + children.push(' \u00b7 ', credit.source); + } + if (credit.license) { + children.push(' \u00b7 ', this.renderLicenseLink(credit.license)); + } return jsx( 'p', { className: 'example-credit', key: index }, - source ? this.renderCreditLink(source[1], label) : label, - source ? null : ' \u00b7 ', - source ? null : credit.source, - ' \u00b7 ', - this.renderLicenseLink(credit.license) + ...children ); } diff --git a/examples/src/app/events.js b/examples/src/app/events.js index 07889eea59c..a7483af4f2e 100644 --- a/examples/src/app/events.js +++ b/examples/src/app/events.js @@ -14,8 +14,8 @@ * @typedef {object} Credit * @property {string} title - The credit title. * @property {string} author - The credit author. - * @property {string} source - The credit source. - * @property {string} license - The credit license. + * @property {string} [source] - The credit source (optional). + * @property {string} [license] - The credit license (optional). * * @typedef {object} StateEventDetail * @property {Observer} observer - The PCUI observer. diff --git a/examples/src/examples/camera/first-person.example.mjs b/examples/src/examples/camera/first-person.example.mjs index d3471263d34..ba6b5dfe526 100644 --- a/examples/src/examples/camera/first-person.example.mjs +++ b/examples/src/examples/camera/first-person.example.mjs @@ -1,6 +1,12 @@ // @config // // `WASD` Move · `Space` Jump · `Mouse` Look +// +// @credit +// title: De Dust 2 with Real Light +// author: Sketchfab +// source: https://sketchfab.com/3d-models/de-dust-2-with-real-light-4ce74cd95c584ce9b12b5ed9dc418db5 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; import { FirstPersonController } from 'playcanvas/scripts/esm/first-person-controller.mjs'; diff --git a/examples/src/examples/compute/edge-detect.example.mjs b/examples/src/examples/compute/edge-detect.example.mjs index d292973a0b5..a52bd6f2ce2 100644 --- a/examples/src/examples/compute/edge-detect.example.mjs +++ b/examples/src/examples/compute/edge-detect.example.mjs @@ -4,6 +4,12 @@ // red. // // @flag WEBGL_DISABLED +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/compute/histogram.example.mjs b/examples/src/examples/compute/histogram.example.mjs index 69f426fcb8e..009b6a81e28 100644 --- a/examples/src/examples/compute/histogram.example.mjs +++ b/examples/src/examples/compute/histogram.example.mjs @@ -1,5 +1,11 @@ // @config // @flag WEBGL_DISABLED +// +// @credit +// title: UXR Icosahedron +// author: enealefons +// source: https://sketchfab.com/3d-models/uxr-icosahedron-66c69bd0538a455197aebe81ae3a4961 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/compute/indirect-dispatch.example.mjs b/examples/src/examples/compute/indirect-dispatch.example.mjs index cb64f91d0df..45feb1e7968 100644 --- a/examples/src/examples/compute/indirect-dispatch.example.mjs +++ b/examples/src/examples/compute/indirect-dispatch.example.mjs @@ -5,6 +5,12 @@ // edge (red) and smooth (blue) regions. // // @flag WEBGL_DISABLED +// +// @credit +// title: Wide Street 02 +// author: Poly Haven +// source: https://polyhaven.com/a/wide_street_02 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/compute/texture-gen.example.mjs b/examples/src/examples/compute/texture-gen.example.mjs index 8cbd27c0c1e..41054927d2a 100644 --- a/examples/src/examples/compute/texture-gen.example.mjs +++ b/examples/src/examples/compute/texture-gen.example.mjs @@ -1,5 +1,11 @@ // @config // @flag WEBGL_DISABLED +// +// @credit +// title: UXR Icosahedron +// author: enealefons +// source: https://sketchfab.com/3d-models/uxr-icosahedron-66c69bd0538a455197aebe81ae3a4961 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/gaussian-splatting-xr/vr-lod.example.mjs b/examples/src/examples/gaussian-splatting-xr/vr-lod.example.mjs index 72298f98333..0616a1b095b 100644 --- a/examples/src/examples/gaussian-splatting-xr/vr-lod.example.mjs +++ b/examples/src/examples/gaussian-splatting-xr/vr-lod.example.mjs @@ -1,6 +1,11 @@ // @config // @flag HIDDEN // @flag NO_MINISTATS +// +// @credit +// title: Roman Parish +// author: Andrii Shramko +// source: https://www.linkedin.com/in/andrii-shramko/ import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/annotations.example.mjs b/examples/src/examples/gaussian-splatting/annotations.example.mjs index c27d7b60df6..08bac9d4292 100644 --- a/examples/src/examples/gaussian-splatting/annotations.example.mjs +++ b/examples/src/examples/gaussian-splatting/annotations.example.mjs @@ -2,6 +2,11 @@ // // Interactive 3D annotations on a gaussian splat model. Click hotspots to reveal product details with // tooltips that follow the 3D positions. +// +// @credit +// title: Bicycle +// author: Stéphane Agullo +// source: https://www.stephane-agullo.fr/ import * as pc from 'playcanvas'; import { Annotation, AnnotationManager } from 'playcanvas/scripts/esm/annotations.mjs'; diff --git a/examples/src/examples/gaussian-splatting/benchmark.example.mjs b/examples/src/examples/gaussian-splatting/benchmark.example.mjs index 1d6fec7e086..069492cdb4b 100644 --- a/examples/src/examples/gaussian-splatting/benchmark.example.mjs +++ b/examples/src/examples/gaussian-splatting/benchmark.example.mjs @@ -6,6 +6,11 @@ // @flag NO_DEVICE_SELECTOR // @flag WEBGPU_DISABLED // @flag WEBGL_DISABLED +// +// @credit +// title: Roman Parish +// author: Andrii Shramko +// source: https://www.linkedin.com/in/andrii-shramko/ import * as pc from 'playcanvas'; diff --git a/examples/src/examples/gaussian-splatting/editor.example.mjs b/examples/src/examples/gaussian-splatting/editor.example.mjs index b9c305f58e2..5d829d5b3ad 100644 --- a/examples/src/examples/gaussian-splatting/editor.example.mjs +++ b/examples/src/examples/gaussian-splatting/editor.example.mjs @@ -3,6 +3,12 @@ // GSplat editor with AABB selection, deletion, and cloning using GSplatProcessor. // // `Select button` Show selection box · `Gizmo` Move selection box · `LMB` Orbit +// +// @credit +// title: SA3D_R&D_XP47 +// author: Stephane Agullo +// source: https://superspl.at/view?id=cdcec084 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/gaussian-splatting/flipbook.example.mjs b/examples/src/examples/gaussian-splatting/flipbook.example.mjs index 4451a8e2a36..4c100980f95 100644 --- a/examples/src/examples/gaussian-splatting/flipbook.example.mjs +++ b/examples/src/examples/gaussian-splatting/flipbook.example.mjs @@ -4,6 +4,16 @@ // files. // // @flag NO_MINISTATS +// +// @credit +// title: Mirror's Edge Apartment - Interior Scene +// author: Aurélien Martel +// source: https://sketchfab.com/3d-models/mirrors-edge-apartment-interior-scene-9804e9f2fe284070b081c96ceaf8af96 +// license: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/) +// +// @credit +// title: Basketball Player +// author: azad_geniusxr import * as pc from 'playcanvas'; import { GsplatFlipbook } from 'playcanvas/scripts/esm/gsplat/gsplat-flipbook.mjs'; diff --git a/examples/src/examples/gaussian-splatting/lod-instances.example.mjs b/examples/src/examples/gaussian-splatting/lod-instances.example.mjs index d9d8a10894e..799fc82d1d1 100644 --- a/examples/src/examples/gaussian-splatting/lod-instances.example.mjs +++ b/examples/src/examples/gaussian-splatting/lod-instances.example.mjs @@ -2,6 +2,12 @@ // // Demonstrates a grid of Gaussian Splat instances using the LOD system for stable performance, with a // custom data stream storing IDs to colorize splats via a color lookup texture. +// +// @credit +// title: PLAYBOT +// author: Stephane Agullo +// source: https://superspl.at/view?id=ee6d8bc4 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/lod-streaming-sh.example.mjs b/examples/src/examples/gaussian-splatting/lod-streaming-sh.example.mjs index 42a203e3f84..45058d50d51 100644 --- a/examples/src/examples/gaussian-splatting/lod-streaming-sh.example.mjs +++ b/examples/src/examples/gaussian-splatting/lod-streaming-sh.example.mjs @@ -1,6 +1,11 @@ // @config // // Demonstrates LOD streaming combined with spherical harmonics for view-dependent effects. +// +// @credit +// title: Skatepark +// author: Christoph Schindelar +// source: https://superspl.at/user?id=schindelar3d import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/lod-streaming.example.mjs b/examples/src/examples/gaussian-splatting/lod-streaming.example.mjs index 5fc0246281e..9bd51a45cb4 100644 --- a/examples/src/examples/gaussian-splatting/lod-streaming.example.mjs +++ b/examples/src/examples/gaussian-splatting/lod-streaming.example.mjs @@ -3,6 +3,11 @@ // Demonstrates LOD streaming with radial reveal effect for progressive loading of Gaussian Splats. // // @flag NO_MINISTATS +// +// @credit +// title: Roman Parish +// author: Andrii Shramko +// source: https://www.linkedin.com/in/andrii-shramko/ import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/multi-splat.example.mjs b/examples/src/examples/gaussian-splatting/multi-splat.example.mjs index cbe8fdfdcee..2affe05b87e 100644 --- a/examples/src/examples/gaussian-splatting/multi-splat.example.mjs +++ b/examples/src/examples/gaussian-splatting/multi-splat.example.mjs @@ -1,6 +1,12 @@ // @config // // Shows multiple Gaussian Splat objects in a gallery scene with custom vertex shaders. +// +// @credit +// title: VR Gallery +// author: Sketchfab +// source: https://sketchfab.com/3d-models/vr-gallery-1e087aa25dc742e680accb15249bd6be +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/gaussian-splatting/paint.example.mjs b/examples/src/examples/gaussian-splatting/paint.example.mjs index bd71827150d..cc46c166052 100644 --- a/examples/src/examples/gaussian-splatting/paint.example.mjs +++ b/examples/src/examples/gaussian-splatting/paint.example.mjs @@ -3,6 +3,12 @@ // 3D painting on gaussian splats using GSplatProcessor. // // `RMB` Paint · `LMB` Orbit +// +// @credit +// title: SA3D_R&D_XP47 +// author: Stephane Agullo +// source: https://superspl.at/view?id=cdcec084 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/gaussian-splatting/procedural-mesh.example.mjs b/examples/src/examples/gaussian-splatting/procedural-mesh.example.mjs index e1d955c7397..5494c7b37e1 100644 --- a/examples/src/examples/gaussian-splatting/procedural-mesh.example.mjs +++ b/examples/src/examples/gaussian-splatting/procedural-mesh.example.mjs @@ -2,6 +2,12 @@ // // Procedural mesh converted to gaussian splats. Demonstrates converting a terrain scene with animated // clouds to splat representation. +// +// @credit +// title: Terrain Low Poly +// author: Sketchfab +// source: https://sketchfab.com/3d-models/terrain-low-poly-248b21331315466e98d20c441935d99d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; import { GsplatMesh } from 'playcanvas/scripts/esm/gsplat/gsplat-mesh.mjs'; diff --git a/examples/src/examples/gaussian-splatting/procedural-shapes.example.mjs b/examples/src/examples/gaussian-splatting/procedural-shapes.example.mjs index e8351266eb7..551dededa6a 100644 --- a/examples/src/examples/gaussian-splatting/procedural-shapes.example.mjs +++ b/examples/src/examples/gaussian-splatting/procedural-shapes.example.mjs @@ -1,6 +1,11 @@ // @config // // Procedural shapes rendered using gaussian splats. Demonstrates lines, text and image-based splats. +// +// @credit +// title: Bicycle +// author: Stéphane Agullo +// source: https://www.stephane-agullo.fr/ import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/shadows.example.mjs b/examples/src/examples/gaussian-splatting/shadows.example.mjs index 4e8be677974..b886931246a 100644 --- a/examples/src/examples/gaussian-splatting/shadows.example.mjs +++ b/examples/src/examples/gaussian-splatting/shadows.example.mjs @@ -3,6 +3,12 @@ // Demonstrates shadow catching with Gaussian Splats. // // @flag HIDDEN +// +// @credit +// title: St Peter's Square Night +// author: Poly Haven +// source: https://polyhaven.com/a/st_peters_square_night +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; import { ShadowCatcher } from 'playcanvas/scripts/esm/shadow-catcher.mjs'; diff --git a/examples/src/examples/gaussian-splatting/splat-portal.example.mjs b/examples/src/examples/gaussian-splatting/splat-portal.example.mjs index 69055f19227..b9df3b56fbc 100644 --- a/examples/src/examples/gaussian-splatting/splat-portal.example.mjs +++ b/examples/src/examples/gaussian-splatting/splat-portal.example.mjs @@ -4,6 +4,22 @@ // through it. // // @flag NO_MINISTATS +// +// @credit +// title: Portal Frame +// author: Sketchfab +// source: https://sketchfab.com/3d-models/portal-frame-da34b37a224e4e49b307c0b17a50af2c +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Roman Parish +// author: Andrii Shramko +// source: https://www.linkedin.com/in/andrii-shramko/ +// +// @credit +// title: Skatepark +// author: Christoph Schindelar +// source: https://superspl.at/user?id=schindelar3d import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/viewer.example.mjs b/examples/src/examples/gaussian-splatting/viewer.example.mjs index 5f65b9c3ba1..ddc18f6900e 100644 --- a/examples/src/examples/gaussian-splatting/viewer.example.mjs +++ b/examples/src/examples/gaussian-splatting/viewer.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Wide Street 02 +// author: Poly Haven +// source: https://polyhaven.com/a/wide_street_02 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/gaussian-splatting/weather.example.mjs b/examples/src/examples/gaussian-splatting/weather.example.mjs index 1a7ba94d373..b25b4175787 100644 --- a/examples/src/examples/gaussian-splatting/weather.example.mjs +++ b/examples/src/examples/gaussian-splatting/weather.example.mjs @@ -4,6 +4,11 @@ // Particles follow the camera using a deterministic 3D grid with hash-based positioning and animation. // // @flag NO_MINISTATS +// +// @credit +// title: Roman Parish +// author: Andrii Shramko +// source: https://www.linkedin.com/in/andrii-shramko/ import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/gaussian-splatting/world.example.mjs b/examples/src/examples/gaussian-splatting/world.example.mjs index 1bdd0702ff5..93fb1b8128a 100644 --- a/examples/src/examples/gaussian-splatting/world.example.mjs +++ b/examples/src/examples/gaussian-splatting/world.example.mjs @@ -1,6 +1,11 @@ // @config // // Shows a large world scene with LOD streaming and additional moving splats. +// +// @credit +// title: Skatepark +// author: Christoph Schindelar +// source: https://superspl.at/user?id=schindelar3d import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/graphics/ambient-occlusion.example.mjs b/examples/src/examples/graphics/ambient-occlusion.example.mjs index 397bbd44dfd..368ee0459cf 100644 --- a/examples/src/examples/graphics/ambient-occlusion.example.mjs +++ b/examples/src/examples/graphics/ambient-occlusion.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Laboratory +// author: Sketchfab +// source: https://sketchfab.com/3d-models/laboratory-e860e49837c044478db650868866a448 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/asset-viewer.example.mjs b/examples/src/examples/graphics/asset-viewer.example.mjs index 2fc1256c5e5..4dc77093402 100644 --- a/examples/src/examples/graphics/asset-viewer.example.mjs +++ b/examples/src/examples/graphics/asset-viewer.example.mjs @@ -1,3 +1,29 @@ +// @config +// +// @credit +// title: Iridescent Dish with Olives +// author: Wayfair LLC +// source: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/IridescentDishWithOlives +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Real-time Refraction Demo: Mosquito in Amber +// author: Sketchfab +// source: https://sketchfab.com/3d-models/real-time-refraction-demo-mosquito-in-amber-37233d6ed84844fea1ebe88069ea58d1 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Sheen Chair +// author: Wayfair LLC +// source: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/SheenChair +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Stained Glass Lamp +// author: Wayfair LLC +// source: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/StainedGlassLamp +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/custom-compose-shader.example.mjs b/examples/src/examples/graphics/custom-compose-shader.example.mjs index a7925c6ff9d..85a87454336 100644 --- a/examples/src/examples/graphics/custom-compose-shader.example.mjs +++ b/examples/src/examples/graphics/custom-compose-shader.example.mjs @@ -3,6 +3,18 @@ // This example shows how to customize the final compose pass by injecting a simple pixelation // post-effect. Useful if no additional render passes are needed. Changes are applied globally to all // CameraFrames. +// +// @credit +// title: Mirror's Edge Apartment - Interior Scene +// author: Aurélien Martel +// source: https://sketchfab.com/3d-models/mirrors-edge-apartment-interior-scene-9804e9f2fe284070b081c96ceaf8af96 +// license: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/) +// +// @credit +// title: Love neon sign 02 +// author: daysena +// source: https://sketchfab.com/3d-models/love-neon-sign-02-9add8bfcb25943d0aae87e0af07c8e4d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/graphics/depth-of-field.example.mjs b/examples/src/examples/graphics/depth-of-field.example.mjs index 0103163ef90..6b8280c7bdf 100644 --- a/examples/src/examples/graphics/depth-of-field.example.mjs +++ b/examples/src/examples/graphics/depth-of-field.example.mjs @@ -1,3 +1,23 @@ +// @config +// +// @credit +// title: Mirror's Edge Apartment - Interior Scene +// author: Aurélien Martel +// source: https://sketchfab.com/3d-models/mirrors-edge-apartment-interior-scene-9804e9f2fe284070b081c96ceaf8af96 +// license: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/) +// +// @credit +// title: Love neon sign 02 +// author: daysena +// source: https://sketchfab.com/3d-models/love-neon-sign-02-9add8bfcb25943d0aae87e0af07c8e4d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Egyptian Cat Statue +// author: Ankledot +// source: https://sketchfab.com/3d-models/egyptian-cat-statue-02b0456362f9442da46d39fb34b3ee5b +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/dithered-transparency.example.mjs b/examples/src/examples/graphics/dithered-transparency.example.mjs index e2dc3b972cf..198569502b9 100644 --- a/examples/src/examples/graphics/dithered-transparency.example.mjs +++ b/examples/src/examples/graphics/dithered-transparency.example.mjs @@ -1,11 +1,15 @@ // @config // -//
-// Independent strengths for alpha blending and opacity dithering. Both tables have alpha -// blending and dither enabled. Left: alphaDither untouched — opacity drives both -// blend and dither (legacy behavior). Right: alphaDither driven by its slider — -// opacity drives only blend; Alpha Dither drives only dither. -//
+// Independent strengths for alpha blending and opacity dithering. Both tables have alpha blending +// and dither enabled. Left: `alphaDither` untouched — opacity drives both blend and dither +// (legacy behavior). Right: `alphaDither` driven by its slider — opacity drives only blend; +// **Alpha Dither** drives only dither. +// +// @credit +// title: Low-poly Glass Table +// author: Sketchfab +// source: https://sketchfab.com/3d-models/low-poly-glass-table-6acac6d9201e448b92dff859b6f63aad +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/graphics/hdr.example.mjs b/examples/src/examples/graphics/hdr.example.mjs index c46e9b04dca..f4562660ac0 100644 --- a/examples/src/examples/graphics/hdr.example.mjs +++ b/examples/src/examples/graphics/hdr.example.mjs @@ -1,3 +1,17 @@ +// @config +// +// @credit +// title: Mirror's Edge Apartment - Interior Scene +// author: Aurélien Martel +// source: https://sketchfab.com/3d-models/mirrors-edge-apartment-interior-scene-9804e9f2fe284070b081c96ceaf8af96 +// license: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/) +// +// @credit +// title: Love neon sign 02 +// author: daysena +// source: https://sketchfab.com/3d-models/love-neon-sign-02-9add8bfcb25943d0aae87e0af07c8e4d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/instancing-gooch.example.mjs b/examples/src/examples/graphics/instancing-gooch.example.mjs index 9ab40f9c2b1..0be98feac10 100644 --- a/examples/src/examples/graphics/instancing-gooch.example.mjs +++ b/examples/src/examples/graphics/instancing-gooch.example.mjs @@ -2,6 +2,12 @@ // // This example demonstrates how a custom shader can be used to render instanced geometry, but also // skinned, morphed and static geometry. A simple Gooch shading shader is used. +// +// @credit +// title: Low-poly Tree with Twisting Branches +// author: Sketchfab +// source: https://sketchfab.com/3d-models/low-poly-tree-with-twisting-branches-4e2589134f2442bcbdab51c1f306cd58 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/graphics/light-physical-units.example.mjs b/examples/src/examples/graphics/light-physical-units.example.mjs index 67d86f67c76..71cbc183d0d 100644 --- a/examples/src/examples/graphics/light-physical-units.example.mjs +++ b/examples/src/examples/graphics/light-physical-units.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Sheen Chair +// author: Wayfair LLC +// source: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/SheenChair +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType, win } from 'examples/context'; diff --git a/examples/src/examples/graphics/lights-baked-a-o.example.mjs b/examples/src/examples/graphics/lights-baked-a-o.example.mjs index 577a0e6a10b..486b427b0f8 100644 --- a/examples/src/examples/graphics/lights-baked-a-o.example.mjs +++ b/examples/src/examples/graphics/lights-baked-a-o.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: House Scene +// author: Sketchfab +// source: https://sketchfab.com/3d-models/house-scene-52772448c62348e0a4951b51758d5587 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/mesh-morph-many.example.mjs b/examples/src/examples/graphics/mesh-morph-many.example.mjs index 8f3d27d72e1..a991b2bc599 100644 --- a/examples/src/examples/graphics/mesh-morph-many.example.mjs +++ b/examples/src/examples/graphics/mesh-morph-many.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: MorphStressTest +// author: Ed Mackey +// source: https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/MorphStressTest/README.md +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/multi-draw.example.mjs b/examples/src/examples/graphics/multi-draw.example.mjs index 3cfda88a083..e8bbbc64140 100644 --- a/examples/src/examples/graphics/multi-draw.example.mjs +++ b/examples/src/examples/graphics/multi-draw.example.mjs @@ -2,6 +2,12 @@ // // Terrain rendering using a single draw call built from a grid of displaced planes. Each patch is a // sub-draw and can be culled (hidden) dynamically. +// +// @credit +// title: Canyon and River Height Map +// author: Motion Forge Pictures +// source: https://www.motionforgepictures.com/height-maps/ +// license: CC0 1.0 Universal (https://creativecommons.org/publicdomain/zero/1.0/) import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/graphics/multi-render-targets.example.mjs b/examples/src/examples/graphics/multi-render-targets.example.mjs index aa23a2428e7..a969d4e90c5 100644 --- a/examples/src/examples/graphics/multi-render-targets.example.mjs +++ b/examples/src/examples/graphics/multi-render-targets.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/multi-view.example.mjs b/examples/src/examples/graphics/multi-view.example.mjs index 4d8fa6ec50e..1e0ffe95663 100644 --- a/examples/src/examples/graphics/multi-view.example.mjs +++ b/examples/src/examples/graphics/multi-view.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/outlines-colored.example.mjs b/examples/src/examples/graphics/outlines-colored.example.mjs index ee9a30ae41c..47d94aff2a6 100644 --- a/examples/src/examples/graphics/outlines-colored.example.mjs +++ b/examples/src/examples/graphics/outlines-colored.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Laboratory +// author: Sketchfab +// source: https://sketchfab.com/3d-models/laboratory-e860e49837c044478db650868866a448 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/portal.example.mjs b/examples/src/examples/graphics/portal.example.mjs index bc607858c3d..c9346313741 100644 --- a/examples/src/examples/graphics/portal.example.mjs +++ b/examples/src/examples/graphics/portal.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Portal Frame +// author: Sketchfab +// source: https://sketchfab.com/3d-models/portal-frame-da34b37a224e4e49b307c0b17a50af2c +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/post-effects.example.mjs b/examples/src/examples/graphics/post-effects.example.mjs index 703144f5c90..c63045c9cb5 100644 --- a/examples/src/examples/graphics/post-effects.example.mjs +++ b/examples/src/examples/graphics/post-effects.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/post-processing.example.mjs b/examples/src/examples/graphics/post-processing.example.mjs index 36eddc08d2c..96c9c5da047 100644 --- a/examples/src/examples/graphics/post-processing.example.mjs +++ b/examples/src/examples/graphics/post-processing.example.mjs @@ -1,3 +1,17 @@ +// @config +// +// @credit +// title: Real-time Refraction Demo: Mosquito in Amber +// author: Sketchfab +// source: https://sketchfab.com/3d-models/real-time-refraction-demo-mosquito-in-amber-37233d6ed84844fea1ebe88069ea58d1 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Scifi Platform Stage Scene (Baked) +// author: Sketchfab +// source: https://sketchfab.com/3d-models/scifi-platform-stage-scene-baked-64adb59a716d43e5a8705ff6fe86c0ce +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/render-pass.example.mjs b/examples/src/examples/graphics/render-pass.example.mjs index 373f40244d5..0b83798702e 100644 --- a/examples/src/examples/graphics/render-pass.example.mjs +++ b/examples/src/examples/graphics/render-pass.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/shadow-cascades.example.mjs b/examples/src/examples/graphics/shadow-cascades.example.mjs index 4a7d99a41e3..2ae8a559ce1 100644 --- a/examples/src/examples/graphics/shadow-cascades.example.mjs +++ b/examples/src/examples/graphics/shadow-cascades.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Terrain Low Poly +// author: Sketchfab +// source: https://sketchfab.com/3d-models/terrain-low-poly-248b21331315466e98d20c441935d99d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/shadow-catcher.example.mjs b/examples/src/examples/graphics/shadow-catcher.example.mjs index d52a7a162fb..30e494c8f14 100644 --- a/examples/src/examples/graphics/shadow-catcher.example.mjs +++ b/examples/src/examples/graphics/shadow-catcher.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: St Peter's Square Night +// author: Poly Haven +// source: https://polyhaven.com/a/st_peters_square_night +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { ShadowCatcher } from 'playcanvas/scripts/esm/shadow-catcher.mjs'; diff --git a/examples/src/examples/graphics/shadow-soft.example.mjs b/examples/src/examples/graphics/shadow-soft.example.mjs index e7327003663..a4e0d63fe85 100644 --- a/examples/src/examples/graphics/shadow-soft.example.mjs +++ b/examples/src/examples/graphics/shadow-soft.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Terrain Low Poly +// author: Sketchfab +// source: https://sketchfab.com/3d-models/terrain-low-poly-248b21331315466e98d20c441935d99d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/sky.example.mjs b/examples/src/examples/graphics/sky.example.mjs index 7bbaaa5bc4f..67c25a82d50 100644 --- a/examples/src/examples/graphics/sky.example.mjs +++ b/examples/src/examples/graphics/sky.example.mjs @@ -1,3 +1,17 @@ +// @config +// +// @credit +// title: Wide Street 02 +// author: Poly Haven +// source: https://polyhaven.com/a/wide_street_02 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Small Empty Room 2 +// author: Poly Haven +// source: https://polyhaven.com/a/small_empty_room_2 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/graphics/taa.example.mjs b/examples/src/examples/graphics/taa.example.mjs index fae3420e4d0..eb29f5018cf 100644 --- a/examples/src/examples/graphics/taa.example.mjs +++ b/examples/src/examples/graphics/taa.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: House 03 PBR +// author: Sketchfab +// source: https://sketchfab.com/3d-models/house-03-pbr-c56521b89188460a99235dec8bcd0ed3 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/loaders/gltf-export.example.mjs b/examples/src/examples/loaders/gltf-export.example.mjs index 3e9da2cf3ed..f99119b093a 100644 --- a/examples/src/examples/loaders/gltf-export.example.mjs +++ b/examples/src/examples/loaders/gltf-export.example.mjs @@ -1,3 +1,17 @@ +// @config +// +// @credit +// title: bench_wooden_01 +// author: Sketchfab +// source: https://sketchfab.com/3d-models/bench-wooden-01-1400c9340d5049589deb43601462ac55 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/loaders/usdz-export.example.mjs b/examples/src/examples/loaders/usdz-export.example.mjs index 9dec95b562e..0da7c618fd2 100644 --- a/examples/src/examples/loaders/usdz-export.example.mjs +++ b/examples/src/examples/loaders/usdz-export.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: bench_wooden_01 +// author: Sketchfab +// source: https://sketchfab.com/3d-models/bench-wooden-01-1400c9340d5049589deb43601462ac55 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/materials/normals-and-tangents.example.mjs b/examples/src/examples/materials/normals-and-tangents.example.mjs index 86a7a529f9c..ac6fb8b68fe 100644 --- a/examples/src/examples/materials/normals-and-tangents.example.mjs +++ b/examples/src/examples/materials/normals-and-tangents.example.mjs @@ -1,5 +1,11 @@ // @config // @flag HIDDEN +// +// @credit +// title: NormalTangentTest +// author: Ed Mackey +// source: https://github.com/KhronosGroup/glTF-Sample-Models/blob/main/2.0/NormalTangentTest/README.md +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/misc/annotations.example.mjs b/examples/src/examples/misc/annotations.example.mjs index f6fafe8fba4..572def1f3fb 100644 --- a/examples/src/examples/misc/annotations.example.mjs +++ b/examples/src/examples/misc/annotations.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Mitsubishi F-2 - Fighter Jet - Free +// author: bohmerang +// source: https://sketchfab.com/3d-models/mitsubishi-f-2-fighter-jet-free-d3d7244554974f499b106e6c11fe3aaf +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { Annotation, AnnotationManager } from 'playcanvas/scripts/esm/annotations.mjs'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; diff --git a/examples/src/examples/shaders/cloud-shadows.example.mjs b/examples/src/examples/shaders/cloud-shadows.example.mjs index d1b11708a00..2672bb32da2 100644 --- a/examples/src/examples/shaders/cloud-shadows.example.mjs +++ b/examples/src/examples/shaders/cloud-shadows.example.mjs @@ -2,6 +2,12 @@ // // This example demonstrates scrolling cloud shadows using a shader chunk // override on {accent:StandardMaterial}. +// +// @credit +// title: Low-poly Tree with Twisting Branches +// author: Sketchfab +// source: https://sketchfab.com/3d-models/low-poly-tree-with-twisting-branches-4e2589134f2442bcbdab51c1f306cd58 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/shaders/ground-fog.example.mjs b/examples/src/examples/shaders/ground-fog.example.mjs index abe6be10989..89891d66733 100644 --- a/examples/src/examples/shaders/ground-fog.example.mjs +++ b/examples/src/examples/shaders/ground-fog.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: Terrain Low Poly +// author: Sketchfab +// source: https://sketchfab.com/3d-models/terrain-low-poly-248b21331315466e98d20c441935d99d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { data, deviceType } from 'examples/context'; diff --git a/examples/src/examples/shaders/shader-hatch.example.mjs b/examples/src/examples/shaders/shader-hatch.example.mjs index 99e3b7ac0d2..108bcd5cffb 100644 --- a/examples/src/examples/shaders/shader-hatch.example.mjs +++ b/examples/src/examples/shaders/shader-hatch.example.mjs @@ -1,3 +1,23 @@ +// @config +// +// @credit +// title: Chess Board +// author: Idmental +// source: https://sketchfab.com/3d-models/chess-board-901eeeca884f4622ac37b7e8f7cb82c3 +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: MorphStressTest +// author: Ed Mackey +// source: https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/MorphStressTest/README.md +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) +// +// @credit +// title: Cross-hatching textures +// author: Jaume Sanchez (spite) +// source: https://github.com/spite/cross-hatching +// license: MIT + import * as pc from 'playcanvas'; import { createHatchMaterial } from 'examples/assets/scripts/misc/hatch-material.mjs'; diff --git a/examples/src/examples/shaders/trees.example.mjs b/examples/src/examples/shaders/trees.example.mjs index a578f2e0a9a..3b6f9c3554e 100644 --- a/examples/src/examples/shaders/trees.example.mjs +++ b/examples/src/examples/shaders/trees.example.mjs @@ -1,6 +1,12 @@ // @config // // This example shows how to override shader chunks of {accent:StandardMaterial}. +// +// @credit +// title: Low-poly Tree with Twisting Branches +// author: Sketchfab +// source: https://sketchfab.com/3d-models/low-poly-tree-with-twisting-branches-4e2589134f2442bcbdab51c1f306cd58 +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/test/contact-hardening-shadows.example.mjs b/examples/src/examples/test/contact-hardening-shadows.example.mjs index e338e1c04a3..3b4d3f38cb9 100644 --- a/examples/src/examples/test/contact-hardening-shadows.example.mjs +++ b/examples/src/examples/test/contact-hardening-shadows.example.mjs @@ -1,6 +1,12 @@ // @config // @flag HIDDEN // @flag WEBGPU_DISABLED +// +// @credit +// title: Black Honey Robotic Arm +// author: Sketchfab +// source: https://sketchfab.com/3d-models/black-honey-robotic-arm-c50671f2a8e74de2a2e687103fdc93ab +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/test/global-shader-properties.example.mjs b/examples/src/examples/test/global-shader-properties.example.mjs index b48148ddbfe..435be987dda 100644 --- a/examples/src/examples/test/global-shader-properties.example.mjs +++ b/examples/src/examples/test/global-shader-properties.example.mjs @@ -1,5 +1,11 @@ // @config // @flag HIDDEN +// +// @credit +// title: Terrain Low Poly +// author: Sketchfab +// source: https://sketchfab.com/3d-models/terrain-low-poly-248b21331315466e98d20c441935d99d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/test/specular.example.mjs b/examples/src/examples/test/specular.example.mjs index 5724a07b1ed..7af7f931069 100644 --- a/examples/src/examples/test/specular.example.mjs +++ b/examples/src/examples/test/specular.example.mjs @@ -5,6 +5,12 @@ // matching factor), and the last sphere on row 7 should look like a mirror ball. // // @flag HIDDEN +// +// @credit +// title: Specular Test +// author: Ed Mackey / Analytical Graphics, Inc. +// source: https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/SpecularTest +// license: CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/test/xr-views.example.mjs b/examples/src/examples/test/xr-views.example.mjs index 258f37a1ca8..d5a7352ab2b 100644 --- a/examples/src/examples/test/xr-views.example.mjs +++ b/examples/src/examples/test/xr-views.example.mjs @@ -1,5 +1,11 @@ // @config // @flag HIDDEN +// +// @credit +// title: Terrain Low Poly +// author: Sketchfab +// source: https://sketchfab.com/3d-models/terrain-low-poly-248b21331315466e98d20c441935d99d +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) import * as pc from 'playcanvas'; diff --git a/examples/src/examples/xr/vr-basic.example.mjs b/examples/src/examples/xr/vr-basic.example.mjs index 21a32b78886..d0b3b255055 100644 --- a/examples/src/examples/xr/vr-basic.example.mjs +++ b/examples/src/examples/xr/vr-basic.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: XR VR Gallery Space +// author: Josh Johanson +// source: https://sketchfab.com/3d-models/xr-vr-gallery-space-873a1808080e47d2a804f3c991e33b4f +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { deviceType } from 'examples/context'; diff --git a/examples/src/examples/xr/vr-test-bed.example.mjs b/examples/src/examples/xr/vr-test-bed.example.mjs index 533de6a6c7e..1734e571c8b 100644 --- a/examples/src/examples/xr/vr-test-bed.example.mjs +++ b/examples/src/examples/xr/vr-test-bed.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: XR VR Gallery Space +// author: Josh Johanson +// source: https://sketchfab.com/3d-models/xr-vr-gallery-space-873a1808080e47d2a804f3c991e33b4f +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { XrMenu } from 'playcanvas/scripts/esm/xr-menu.mjs'; diff --git a/examples/src/examples/xr/xr-menu.example.mjs b/examples/src/examples/xr/xr-menu.example.mjs index 95ceb835f6a..89015d71e53 100644 --- a/examples/src/examples/xr/xr-menu.example.mjs +++ b/examples/src/examples/xr/xr-menu.example.mjs @@ -1,3 +1,11 @@ +// @config +// +// @credit +// title: VR Gallery +// author: Sketchfab +// source: https://sketchfab.com/3d-models/vr-gallery-1e087aa25dc742e680accb15249bd6be +// license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) + import * as pc from 'playcanvas'; import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs'; import { XrControllers } from 'playcanvas/scripts/esm/xr-controllers.mjs'; diff --git a/examples/utils/example-source.mjs b/examples/utils/example-source.mjs index e60573b838f..0d788c336f9 100644 --- a/examples/utils/example-source.mjs +++ b/examples/utils/example-source.mjs @@ -6,6 +6,7 @@ const regexPatterns = [ ]; const configRegex = /^[ \t]*\/\/ @config[ \t]*(?:\r?\n[ \t]*\/\/[^\r\n]*)*(?:\r?\n|$)/gm; const CREDIT_FIELDS = ['title', 'author', 'source', 'license']; +const REQUIRED_CREDIT_FIELDS = ['title', 'author']; const CREDIT_FIELD_SET = new Set(CREDIT_FIELDS); const parseValue = (val) => { @@ -22,7 +23,7 @@ const parseExampleConfig = (block, config) => { let credit = null; const completeCredit = () => { - const missing = CREDIT_FIELDS.filter(field => !credit[field]); + const missing = REQUIRED_CREDIT_FIELDS.filter(field => !credit[field]); if (missing.length) { throw new Error(`Incomplete @credit: missing ${missing.join(', ')}`); } @@ -88,7 +89,21 @@ const parseExampleConfig = (block, config) => { completeCredit(); } - const text = description.join('\n').trim(); + const paragraphs = []; + let current = []; + for (const line of description) { + const trimmed = line.trim(); + if (trimmed) { + current.push(trimmed); + } else if (current.length) { + paragraphs.push(current.join(' ')); + current = []; + } + } + if (current.length) { + paragraphs.push(current.join(' ')); + } + const text = paragraphs.join('\n').trim(); if (text) { config.DESCRIPTION = text; } @@ -125,7 +140,7 @@ export const stripConfig = (source) => { /** * @typedef {object} ExampleConfig * @property {string} [DESCRIPTION] - The example description. - * @property {{ title: string, author: string, source: string, license: string }[]} [CREDITS] - Scene credits. + * @property {{ title: string, author: string, source?: string, license?: string }[]} [CREDITS] - Scene credits. * @property {boolean} [HIDDEN] - The example is hidden from the sidebar list in production builds (`npm run build`). It is still built and reachable via its URL. In development (`npm run develop`) it is still shown in the sidebar. * @property {'development' | 'performance' | 'debug'} [ENGINE] - The engine type. * @property {boolean} [NO_DEVICE_SELECTOR] - No device selector.