RenderConfig#mipmapRegenerationoption allows certain framebuffer-based objects to use mipmaps if the game is configured to use mipmaps. This has a cost because mipmaps must be recreated after every change. Currently it only applies to DynamicTextures; Filters cannot render mipmaps. Thanks @Flow!Layeris now a trueGameObject. This fixes numerous small inconsistencies, and some big issues such as Filters not working. Thanks @rexrainbow for reporting the initial issue!- The base filter
Controllernow hasgetPaddingCeil(), which returns the ceiling of the current padding. This is mostly used internally to avoid quality loss from fractional padding. If your code callsgetPadding()on a filter controller (typically in a custom render node), you should replace it withgetPaddingCeil(). - Experimental
WEBGL3Drenderer: a new minimal 3D backend targeting WebGL2. Games opt in viatype: Phaser.WEBGL3Dand gain access to a compact 3D pipeline. Seedocs/WEBGL3D.mdfor the full API reference andexamples/vite-3d/for a runnable demo. - New
Phaser.WEBGL3Drenderer type constant (value9). Never selected byPhaser.AUTO; must be requested explicitly. Requires WebGL2, with no fallback. - New
Phaser.Cameras.ThreeDnamespace withCamera3D(base),PerspectiveCamera,OrthographicCameraandFrustum. Every camera carries a view frustum that is rebuilt every frame from its view-projection matrix and powers bounding-sphere culling in the renderer. - New
CameraManager3DScene plugin, auto-injected asthis.cameras3din every Scene when the renderer is built in. Providesthis.cameras3d.main,addPerspective,addOrthographic,addExisting,setMainandremove. Auto-resizes every registered camera on Scale Manager RESIZE. - New
Phaser.GameObjects3Dnamespace withObject3D(base node with transform, parent/children and world matrix),Mesh3D(drawable Object3D with geometry, material and bounding sphere), plusCubeandPlaneprimitives. Shared geometry is cached at module scope and GPU buffers are uploaded lazily on first draw, so instancing hundreds of the same primitive is cheap. - New
GameObjectFactory3DScene plugin, auto-injected asthis.add3Din every Scene. Providesthis.add3D.material(type, config),cube(materialOrConfig),plane(materialOrConfig),gltf(key, options),object3D(),mesh(geometry, material),existing(node)andremove(node). Meshes added via the factory are automatically part ofscene.displayList3D; children of a registered root are walked recursively soadd3D.existingonly needs the root. - Scene graph:
Object3D#parent,#children,add(child),remove(child),getLocalMatrix()andgetWorldMatrix().Mesh3Dnow extendsObject3Dand the renderer walks the tree in depth-first order, pruning whole subtrees when a node hasvisible = false. - New
Phaser.Renderer.WebGL3Dnamespace exposingWebGL3DRenderer,MaterialManager,Materialand the built-in shader sources (Shaders.UnlitColor,Shaders.UnlitTextured,Shaders.LitColor,Shaders.LitTextured). The renderer implements the Texture Manager hooks (createTextureFromSource,createCanvasTexture,createVideoTexture,createUint8ArrayTexture) so the standard Loader and Texture Manager workflows work for 3D materials. - Four built-in shaders with optional stylization controls:
vertexSnap(quantises clip-space XY to a pixel grid) andaffineUV(uses affine UV interpolation by cancelling perspective correction, since WebGL2 reserves but does not implement thenoperspectivequalifier). All shaders support optional per-vertex colours and distance fog. The newlit_*variants add Lambertian diffuse shading, au_normalMatrixfor correct lighting under non-uniform scaling, and a runtimeshadingtoggle between smooth and flat using GLSL ES 3.00'sflatqualifier. - New
Phaser.Lights3Dnamespace withLight3D(base),AmbientLight3D,DirectionalLight3D,PointLight3DandLightManager3D. Lights carrycolor,intensityandenabled; directional lights adddirection; point lights addpositionand arangefor smoothstep attenuation. - New
LightManager3DScene plugin, auto-injected asthis.lights3din every Scene. Providespreset('studio' | 'moody' | 'none'),setAmbient(cfg),setDirectional(cfg),addPoint(cfg),remove(light)andclearPoints(). Caps point lights to four active slots to match the shader uniform arrays. Directional direction is normalised once per frame inupdate(). - Lit materials:
Materialnow accepts'lit_color'and'lit_textured'types, plus ashading: 'smooth' | 'flat'parameter that can be toggled at runtime. Unlit materials ('unlit_color','unlit_textured') remain as the emissive / UI path and ignore the lighting rig entirely. CubeandPlaneprimitives now supply per-face normals alongside positions and UVs, so they light correctly under the newlit_*shaders out of the box. Custom meshes can supplygeometry.normals(same layout as positions) to opt in; meshes without normals get a constant(0, 1, 0)fallback so lit materials still render.Materialgainstransparent,blendMode('normal'/'additive'/'multiply'),fog,vertexColorsandshadingproperties. Transparency is auto-detected fromcolor[3] < 1. The renderer now runs two passes: an opaque pass (depth write on, front-to-back for early-Z) and a transparent pass (depth write off, back-to-front painter's sort).- Distance fog on
Camera3D:camera.setFog(color, near, far)+clearFog(). Shared across materials, per-material opt-out viamaterial.fog = false. Implemented as a linear blend betweenu_fogNearandu_fogFarin the built-in shaders. - Per-vertex colours: supply
geometry.colors(tightly packed RGB floats) and setmaterial.vertexColors = true. Meshes without a colour stream fall back to constant white viagl.vertexAttrib3f, so the same shader path runs regardless. - Frustum culling:
CubeandPlaneship with tight bounding spheres; the renderer rejects any mesh whose world-space bounding sphere sits outside the active camera's frustum. Opt out per camera viacamera.frustumCulling = false. - New per-frame
renderer.statsobject (drawCalls,meshesDrawn,meshesCulled), reset inpreRender. Useful for HUDs and debugging the culler. - New
Features.webGL2capability flag onPhaser.Device.Features, true when the browser exposes a workingWebGL2RenderingContext. - New
Phaser.Loader3Dnamespace withGLTFParser,GLTFAssetandGLTFFile. Provides a minimal but complete glTF 2.0 loader for the 3D renderer. Supports both.glbbinary containers (including embedded buffers and images) and.gltfJSON files with external.bin/ image sidecars anddata:URIs. Parses accessors (with de-interleaving when needed), builds tight bounding spheres from accessor min/max, converts node rotations from quaternion to Phaser's Euler YXZ convention and decomposesnode.matrixinto TRS when provided. - New
this.load.gltf(key, url)Loader file type, registered viaFileTypesManagerunder theWEBGL3D_RENDERERbuild flag. Produces aGLTFModelAssettemplate cached in the newthis.cache.gltf(Phaser.Cache.CacheManager#gltf). The parser emitsasset.warnings[]for every PBR feature it has to drop and logs them as a singleconsole.infowhen the file finishes processing, so artists can see at a glance what survived the downgrade. - PBR metallic-roughness materials are downgraded to
lit_color/lit_textured:baseColorFactorbecomescolor,baseColorTexturebecomestexture,doubleSided: truemaps tocullFace: 'none',alphaMode: 'BLEND'enables the transparent pass, andalphaMode: 'MASK'is honoured natively via shader-side alpha test (see separate changelog entry). Metallic, roughness, normal, occlusion and emissive maps, extensions like KHR_materials_* and Draco / meshopt / KTX2 are collected into the warnings array and otherwise ignored. - Geometry support in the glTF loader:
POSITION,NORMAL,TEXCOORD_0andCOLOR_0attributes,indicesaccessors (UNSIGNED_BYTEauto-promoted toUNSIGNED_SHORT,UNSIGNED_INTforwarded). Triangles only — other primitive modes raise a warning and are skipped. - New
this.add3D.gltf(key, options)factory method. Clones the cachedGLTFModelAssetinto a liveObject3Dtree withMesh3Dleaves, sharing the underlying geometry andMaterialinstances across every instance spawned from the same key (first instantiation creates the materials and uploads textures; subsequent instances reuse them). glTF textures are uploaded withflipY = false, straight alpha, and the asset'ssamplers[]filter / wrap state. Options include{ includeLights: true }(default),{ instanceName: string }, transform shorthand (x,y,z,scale,scaleX/Y/Z,rotationX/Y/Z),animation(true, index, name orfalse) andmaterial('lit','unlit', a replacement Material or a callback). KHR_lights_punctualimport: directional and point lights are forwarded toLightManager3D.setDirectional/addPoint. Spot lights are currently skipped with a warning (no spot shader yet). Light colour and intensity come straight from glTF; pointrangemaps onto the existing smoothstep attenuation.WebGL3DRenderernow honours the index buffer type declared by the mesh. Uint8 indices are treated asUNSIGNED_BYTE, Uint32 indices asUNSIGNED_INT(WebGL2 core, no extension required), enabling glTF meshes with more than 65535 vertices without manual splitting.- New
WEBGL3D_RENDERERwebpack flag, wired intoconfig/webpack.config.js,config/webpack-nospector.config.jsandconfig/webpack.dist.config.js. Whentruethe 3D namespaces (Phaser.Renderer.WebGL3D,Phaser.Cameras.ThreeD,Phaser.GameObjects3D,Phaser.Lights3D,Phaser.Loader3D,Phaser.Animation3D), Scene plugins (this.cameras3d,this.add3D,this.lights3d) and the glTF loader (this.load.gltf,this.cache.gltf) are included; whenfalsethe 3D code is tree-shaken out and requestingPhaser.WEBGL3Dthrows at boot. - glTF animation playback: the loader now parses
animations[]into sharedGLTFAnimationCliptemplates (name, duration, samplers withLINEAR/STEPinterpolation, channels targetingtranslation/rotation/scale).CUBICSPLINEinterpolation is downgraded toLINEARwith a warning;weights(morph target) channels are dropped with a warning. - New
Phaser.Animation3Dnamespace withAnimationMixer3D. The factory (this.add3D.gltf) allocates a per-instance mixer bound to the instance'sObject3Dnodes and exposes it asroot.mixer. The mixer supportsplay(clipName, opts),stop,stopAll,crossFade(clipName, duration, opts),getCurrentAction()andupdate(dt). Multiple simultaneous actions blend by weight (spherical interpolation for rotation, weighted sum for translation / scale). It auto-subscribes toscene.events.UPDATEunless the factory is called withautoUpdate: false. - New
animationoption onthis.add3D.gltf(key, opts). Passtrueor0to start the first clip, a numeric clip index, a string to start a named clip, orfalseto keep the instance in bind pose. The olderautoPlayoption remains supported (trueor clip name).autoUpdate(defaulttrue) controls the Scene UPDATE subscription. - Linear-blend skinning: new
Phaser.GameObjects3D.SkinnedMesh3DextendingMesh3D. Holds a sharedjoints: Object3D[]reference list, per-vertexjointIndices/jointWeightsattribute arrays,inverseBindMatrices(shared with the asset template) and a per-instancejointMatricesbuffer (64 matrices, uploaded each frame asu_jointMatrix[]).updateJointMatrices()multipliesjoint[j].getWorldMatrix()withinverseBindMatrices[j]for every active bone and zeroes the unused tail.SkinnedMesh3D.MAX_JOINTSis64, matching the shader uniform array size. - Four new built-in shader variants:
UnlitColorSkinned,UnlitTexturedSkinned,LitColorSkinned,LitTexturedSkinned. They add two vertex attribute inputs (a_joints: uvec4,a_weights: vec4) and au_jointMatrix[MAX_JOINTS]uniform array, replaceu_model * positionwith a per-vertex blended skin matrix, and (for the lit variants) derive the normal matrix from the same skin matrix so skinning works under non-uniform bone scale.MaterialManagercompiles the eight programs up front and keys them by(type, skinned);Material#skinned: trueselects the skinned variant. WebGL3DRenderernow uploadsJOINTS_0(gl.UNSIGNED_SHORT, viavertexAttribIPointerat location 4) andWEIGHTS_0(gl.FLOATat location 5) VBOs for every skinned mesh, skipsu_model/u_normalMatrixuploads for skinned programs and writesu_jointMatrixonce per skinned draw call. Skinned materials paired with non-skinned meshes fall back to the static program.GLTFAsset.buildnow parsesskins[](inverseBindMatrices,joints[]→ glTF node indices) and recordsJOINTS_0/WEIGHTS_0attributes on primitives (promoted toUint16ArrayandFloat32Array, with aprimitive.skinnedboolean).asset.statsgainsanimationCountandskinCount; nodes carry the originalrotationQuatalongside the Euler YXZ rotation so the mixer can interpolate without a round-trip through Euler.this.add3D.gltf(key)now instantiates aSkinnedMesh3D(instead ofMesh3D) for every skinned primitive, automatically builds a parallel skinnedMaterialcache and wires joint references across the scene graph. Skinned meshes disable frustum culling by default (boundingSphere = null) because the bind-pose bound is invalidated once joints animate; users can assign a manual bound when their animation stays inside a known envelope.WebGL3DRenderer#_collectnow recognisesSkinnedMesh3DalongsideMesh3Dwhen walking the display list. Previously skinned meshes were silently skipped by the opaque/transparent classifier even though their joints and animation mixer were running; they now take part in frustum-culling, sorting and both render passes.- Vite demo (
examples/vite-3d/) now focuses on the high-level Phaser-style API:this.load.gltf,this.add3D.gltf({ x, y, z, scale, animation, material }),this.add3D.material, primitive config shorthands andthis.lights3d.preset(). It loads the LISA rigged character, adds a few simple primitives and keeps the previous runtime.glbhelpers available as fixtures for renderer experiments. examples/vite-3d/now includes a routed WEBGL3D mini-game gallery with Crystal Collector, Lane Runner and Dungeon Crawler examples. The games stay intentionally small and composable, using primitives, camera helpers, blob shadows, raycast picking, simple state machines and DOM HUDs rather than adding physics or collision systems.Materialgains analphaTestproperty (0..1, default 0) consumed by the four textured shader variants (unlit_textured,lit_texturedand their:skinnedcounterparts). When greater than zero the fragment shaderdiscards any pixel whose sampled alpha (multiplied by the tint alpha) falls below the cutoff - cut-out materials (foliage, chain-link, hair cards, Silent-Hill-style PS2 characters) can therefore render in the opaque pass with correct depth write and sorting, instead of being forced through the transparent pass. Colour-only materials ignore the flag (no texture to sample).GLTFAsset._buildMaterialnow honoursalphaMode: "MASK"natively:alphaCutoffis copied into the material template's newalphaTestfield,transparentstaysfalse, and the factory propagates the cutoff into the instantiatedMaterial. Previously MASK materials were downgraded to BLEND (transparent pass, no depth write) which broke sorting against the surrounding opaque scene. WhenalphaCutoffis absent the glTF 2.0 default of0.5is used; MASK on a non-textured material records adowngradenote and the cutoff is dropped.- New coarse WEBGL3D picking helpers:
Phaser.Cameras.ThreeD.Ray3D,Camera3D#getRay(x, y, width, height),this.add3D.raycast(ray, roots?)andthis.add3D.raycastFromPointer(pointer, options?). The first pass tests against world-space bounding spheres and returns nearest-first hit records with{ object, root, distance, point, sphere }.SkinnedMesh3Dpreserves its bind-pose bound aspickSphereso rigged characters can still be selected without re-enabling frustum culling. - New high-level
Camera3Dcontrol helpers:fixed(position, target),follow(target, { offset, lookAtOffset }),orbit(target, { distance, yaw, pitch, lookAtOffset }),firstPerson(position, yaw, pitch)andclearControl().followandorbitrecompute from anObject3Dtarget duringcamera.update(), so common third-person, model-viewer and fixed-angle cameras no longer need manual Scene update code. - New
Billboard3DandBlobShadow3Dgame objects, exposed throughthis.add3D.billboard(config)andthis.add3D.blobShadow(target, config). Billboards are upright camera-facing planes for pickups, labels and simple 3D UI. Blob shadows are cheap transparent planes that follow a target on X/Z to provide visual contact without shadow maps. - glTF instances returned by
this.add3D.gltf(...)now exposefindNode,findNodes,findMeshandfindMesheshelpers for searching the live cloned hierarchy by name or predicate. This makes it easier to attach props to sockets, inspect imported rigs and customise individual mesh materials. Object3Dnow has alookAt(x, y, z, yawOnly?)helper (also acceptsObject3Dand vector-like targets) that rotates local +Z toward a target point. Small 3D games can turn enemies, pickups, props and projectiles toward a target without hand-written yaw / pitch math; passtrueforyawOnlyto keep the node upright.GLTFAsset._buildMaterialnow honoursKHR_materials_unlitnatively: materials that declare it are routed through theunlit_*shader family, so prelit, viewer-style assets render without manualmaterial: 'unlit'overrides. Material templates exposefamily('lit'or'unlit') and a convenienceunlitboolean. The factory's_buildMaterialnow respects the template'sfamily, and the loader allowlistsKHR_materials_unlit(the extension no longer surfaces as an "ignored extension" warning).Materialgainsemissive(RGB),emissiveIntensity(scalar, default1) andemissiveTexture(only consumed by*_texturedflavours). The eight built-in shaders sum the emissive contribution after lighting and before fog, so emissive surfaces pulse / glow independently of the directional / point lights.Material#setEmissive(r, g, b, intensity?)updates them in place.WebGL3DRendererpremultiplies the colour by intensity on CPU and binds the optional emissive map to texture unit 1, gated byu_useEmissiveTexture.GLTFAsset._buildMaterialnow mapsemissiveFactorandemissiveTextureonto the newMaterialfields. The'emissive* -> ignored'downgrade is gone; onlytexCoord != 0onemissiveTextureproduces a downgrade note (the loader still samples withTEXCOORD_0).Materialgains an explicitdepthWriteflag (defaults to!transparent).WebGL3DRenderernow drivesgl.depthMaskper draw frommaterial.depthWriteinstead of forcing it from the opaque / transparent split, so alpha-tested cards can keep depth write while sliding into the transparent pass and overlay decals can stay transparent without occluding geometry below them.Material#setDepthWrite(bool)exposes the flag for runtime tweaks.- New
webgl3d.colorSpaceGame config option ('linear'default,'srgb'opt-in). When set to'srgb', the eight built-in shaders treat user-supplied colours (Material#color,Material#emissive, ambient / directional / point lights, fog) andbaseColor/emissiveTexturesamples as sRGB, run lighting in linear space, and gamma-encode the final fragment. The active mode is exposed at runtime asgame.renderer.colorSpace.'linear'preserves the historical no-op pipeline so existing demos look the same. MaterialgainsnormalTexture(tangent-space normal map) andnormalScale.lit_texturedandlit_textured:skinnednow support normal mapping using a derivative-based TBN, so meshes do not need to ship explicitTANGENTattributes.Material#setNormalMap(texture, scale?)updates them in place.WebGL3DRendererbinds the normal map to texture unit 2, gated byu_useNormalTextureso the lit_color and unlit programs are unaffected.GLTFAsset._buildMaterialnow mapsnormalTextureandnormalTexture.scaleonto the newMaterialfields; the'normalTexture -> ignored'downgrade is gone.Materialgainsspecular(RGB, default[0,0,0]) andshininess(default32). All fourlit_*shader variants (color/textured + skinned) now sum a Blinn-Phong specular lobe per directional and point light, gated byu_useSpecularso unused materials skip the cost.Material#setSpecular(r, g, b, shininess?)is the chainable setter. The renderer uploadsu_viewPosand the specular uniforms only on lit draw calls. The lobe is intentionally Phong-family, not PBR.MaterialgainsocclusionTextureandocclusionStrength.lit_texturedandlit_textured:skinnednow multiply the diffuse lobe bymix(1.0, occlusion.r, strength)before specular and emissive are added.Material#setOcclusionMap(texture, strength?)is the chainable setter.WebGL3DRendererbinds the AO map to texture unit 3, gated byu_useOcclusionTextureso the lit_color and unlit programs are unaffected.GLTFAsset._buildMaterialnow mapsocclusionTextureandocclusionTexture.strengthonto the newMaterialfields; the'occlusionTexture -> ignored'downgrade is gone.MaterialgainstextureTransform({ offset, scale, rotation }). The four*_texturedshader programs (lit/unlit + skinned) now multiply UVs by a per-materialmat3(u_uvTransform) before sampling, so the same matrix drivesbaseColor,emissive,normalandocclusionlookups.Material#setTextureTransform(spec)is the chainable setter (passnullto clear).WebGL3DRendererbuilds the column-majorT(offset) * R(rotation) * S(scale)matrix per draw and skips the upload (identity) on color-only programs.GLTFAsset._buildMaterialnow readsKHR_texture_transformfrompbrMetallicRoughness.baseColorTextureand forwards it; divergent transforms onemissiveTexture/normalTexture/occlusionTextureare surfaced asdowngradenotes (one transform applies to every map).KHR_texture_transformis added toSUPPORTED_EXTENSIONS, so the loader no longer reports it as an "ignored extension". This implements the glTFKHR_texture_transformextension and is the recommended path for runtime UV scrolling, atlas slicing and texture rotation.MaterialgainstexCoord(0or1). The four*_texturedshader programs (lit/unlit + skinned) now declare a second UV attribute at location 6 and switch the active set per draw via the newu_useUV1uniform; the renderer falls back to TEXCOORD_0 when the mesh does not provide a second UV channel so a partial import never samples uninitialised data.Material#setTexCoord(channel)is the chainable setter.Mesh3Dexposes a newuvs2field, mirrored ongeometry.uvs2.WebGL3DRenderer._ensureMeshGPUallocates the corresponding VBO whenuvs2is present and disables attribute 6 otherwise.GLTFAssetnow readsTEXCOORD_1off mesh primitives, propagates the active channel frompbrMetallicRoughness.baseColorTexture.texCoord(only0and1are honoured; higher channels fall back with a downgrade note), and reports any divergenttexCoordonemissiveTexture/normalTexture/occlusionTextureviamaterial.downgrade[].TEXCOORD_2and higher are dropped at load time.metallicRoughnessTexture,metallicFactorandroughnessFactordowngrade messages are now action-oriented (they suggest usingMaterial#specular/Material#shininessor baking the look into baseColor) instead of just saying "ignored". The "ignored extension" message also lists each unsupported extension by name and notes the WEBGL3D allowlist.- New
Phaser.GameObjects3D.InstancedMesh3Dclass + GPU instancing path. The mesh keeps a single shared geometry / material / VAO and drawscountcopies through onegl.drawElementsInstancedcall. Per-instance state lives in two typed arrays exposed on the mesh:instanceMatrices(Float32Array,maxInstances * 16, column-major mat4 per slot) and the optionalinstanceColors(Float32Array,maxInstances * 3). Setters:setMatrixAt(i, mat),setPositionAt(i, x, y, z),setPositionScaleAt(i, x, y, z, scale),setColorAt(i, r, g, b),getMatrixAt(i, out?),commitInstances(). Four new instanced shader variants (unlit_color:instanced,unlit_textured:instanced,lit_color:instanced,lit_textured:instanced) declaremat4 a_instanceMatrix(locations 7–10) andvec3 a_instanceColor(location 11), composeworld = u_model * a_instanceMatrix * a_position, and approximate per-instance normals asu_normalMatrix * mat3(a_instanceMatrix) * a_normal(exact for rotations + uniform scales).MaterialManager.getProgramnow accepts an object variant{ skinned, instanced }(the legacy boolean still works).WebGL3DRenderer._ensureMeshGPUallocates a dynamic-draw matrix VBO + optional colour VBO and binds them withvertexAttribDivisor(loc, 1);_drawMeshre-uploads viabufferSubDatawheneverinstancesDirtyis set, then issuesdrawElementsInstanced. New factories:add3D.instancedMesh(geometry, material, max),add3D.instancedCube(config),add3D.instancedPlane(config). Skinning + instancing is intentionally unsupported in this iteration;_drawable: truelets custom Mesh3D subclasses opt into the renderer's collect whitelist without registering by name. - New
Phaser.Lights3D.SpotLight3Dlighting type.LightManager3Dexposes a fourth slot (lights3d.spots[], capped at four entries) plusaddSpot(config)/addExistingSpot(light)/clearSpots(), mirroring the point-light API. Each spot carriesposition,direction,range,innerCone(radians) andouterCone(radians);setCone(inner, outer?)is the chainable cone-only setter. The fourlit_*shader programs (color/textured + skinned) now sum a per-spot lobe with the same1 - smoothstep(0, range, dist)distance falloff used by point lights, multiplied by a cone gatesmoothstep(cos(outerCone), cos(innerCone), dot(-L, dir)). Spot specular contribution piggybacks onMaterial#specular/Material#shininess.WebGL3DRendererprecomputes the cone cosines on upload and packs scratch buffers (u_spotPos,u_spotDir,u_spotColor,u_spotIntensity,u_spotRange,u_spotInnerCos,u_spotOuterCos) at the same shape as the point arrays.LightManager3D.updatenow also caches a normalised copy of every spot direction so the renderer skips the per-draw normalise.GLTFAsset._buildLightsandGameObjectFactory3D._applyLightsnow honourKHR_lights_punctualtype: "spot"(withinnerConeAngle/outerConeAngledefaults from the spec); the previous'spot light dropped'warning is gone.
- Fix reversions in rounded rectangle handling. Thanks @laineus!
- Remove duplicate function definition and exposed internal code docs from
RectangleCanvasRenderer. - Fix duplicate texture name resulting from
RenderTexture#saveTexture. Thanks @UnaiNeuronUp! - Fix framebuffers (in filters and DynamicTextures) using mipmaps incorrectly. Now filters do not render with mipmaps. Thanks @Flow!
- Fix lack of default export in ESM build. Thanks @kibertoad!
- Fix lack of Class and LOG_VERSION export in ESM build. Thanks to many users including @Flow and @rex for helping investigate this!