[{"data":1,"prerenderedAt":1656},["ShallowReactive",2],{"\u002Fblog\u002Fwhats-new-october-2026":3,"author-alvarosabu":1631,"formatted-blog-post-\u002Fblog\u002Fwhats-new-october-2026":1650},{"id":4,"title":5,"author":6,"body":7,"category":1613,"date":1614,"description":1615,"draft":1616,"extension":1617,"meta":1618,"navigation":314,"path":1619,"rawbody":1620,"readingTime":1621,"seo":1626,"stem":1627,"thumbnail":1628,"url":1629,"__hash__":1630},"blog\u002Fblog\u002Fwhats-new-october-2026.md","The Loop Chronicles: October 2026 Recap","alvarosabu",{"type":8,"value":9,"toc":1590},"minimark",[10,36,41,47,57,62,84,87,106,121,125,135,147,150,155,162,175,184,188,208,594,601,695,718,738,746,750,756,803,813,859,881,912,930,934,948,1022,1042,1046,1069,1099,1141,1161,1165,1169,1260,1269,1273,1287,1296,1300,1306,1356,1360,1380,1384,1387,1433,1466,1470,1475,1479,1483,1502,1506,1521,1563,1571,1583,1586],[11,12,13,14,18,19,22,23,27,28,31,32,35],"p",{},"Yo! Welcome back to ",[15,16,17],"strong",{},"The Loop Chronicles"," 🎃 👻. This edition comes to you from Tokyo 🗼. October was a big month: TresJS was on stage ",[15,20,21],{},"twice"," at Vue Fes Japan 2026, and WebGPU stopped being a setup trick and became a proper entry point in ",[24,25,26],"code",{},"@tresjs\u002Fcore@5.10",", ",[24,29,30],{},"@tresjs\u002Fcientos@5.10"," and ",[24,33,34],{},"@tresjs\u002Fnuxt@5.8",". Let's go 🚀.",[37,38,40],"h2",{"id":39},"tresjs-at-vue-fes-japan-2026","TresJS at Vue Fes Japan 2026",[11,42,43],{},[44,45],"img",{"alt":40,"src":46},"\u002Fblog\u002Fwhats-new-october-2026\u002Fvuefes-japan-2026.png",[11,48,49,56],{},[50,51,55],"a",{"href":52,"rel":53},"https:\u002F\u002Fvuefes.jp\u002F2026\u002Fen",[54],"nofollow","Vue Fes Japan 2026"," took place on October 24 at Otemachi Place in Tokyo. Two of the talks were about TresJS, and for us that is a dream come true 🇯🇵.",[58,59,61],"h3",{"id":60},"spatial-computing-written-in-vue","Spatial Computing, Written in Vue",[11,63,64,69,70,75,76,83],{},[65,66],"magic-link",{"label":67,"to":68},"Shingo Hiranuma","https:\u002F\u002Fgithub.com\u002Fhiranuma"," (",[50,71,74],{"href":72,"rel":73},"https:\u002F\u002Fx.com\u002Fmistorun",[54],"@mistorun","), CTO at GENEROSITY inc., gave ",[50,77,80],{"href":78,"rel":79},"https:\u002F\u002Fvuefes.jp\u002F2026\u002Fen\u002Fspeaker\u002Fhiranuma",[54],[15,81,82],{},"Spatial Computing with Vue: Frontend Development for XR Devices Using TresJS and WebXR",".",[11,85,86],{},"The idea: you can build spatial computing apps for devices like the Meta Quest 3 and the Samsung Galaxy XR with the Vue Composition API you already know. No new framework to learn. Shingo showed implementation patterns for XR frontends with Vue, TresJS and WebXR:",[88,89,90],"prose-list",{},[91,92,93,97,100,103],"ul",{},[94,95,96],"li",{},"Gaze and gesture interaction",[94,98,99],{},"Declarative scene construction",[94,101,102],{},"Support for both hand tracking and controllers",[94,104,105],{},"Physics engine integration",[11,107,108,109,114,115,120],{},"With glasses-type devices like XREAL Project Aura and Snap Specs arriving this fall, this talk is a great map of where Vue can go next. The slides are available in ",[50,110,113],{"href":111,"rel":112},"https:\u002F\u002Fspeakerdeck.com\u002Fhiranuma\u002Fspatial-computing-written-in-vue-front-end-development-for-xr-devices-with-tresjs-and-webxr",[54],"English"," and in ",[50,116,119],{"href":117,"rel":118},"https:\u002F\u002Fspeakerdeck.com\u002Fhiranuma\u002Fvue-de-kaku-kuukan-tresjs-to-webxr-o-tsukata-xr-debaisu-no-furonto-endo-kaihatsu",[54],"Japanese",". Thank you, Shingo, for taking TresJS into XR 🥽🙌.",[58,122,124],{"id":123},"how-i-recreated-the-vue-fes-japan-2025-website-using-tresjs-and-tsl","How I recreated the Vue Fes Japan 2025 website using TresJS and TSL",[11,126,127,128,83],{},"Later that afternoon, I gave ",[50,129,132],{"href":130,"rel":131},"https:\u002F\u002Fvuefes.jp\u002F2026\u002Fen\u002Fspeaker\u002Falvarosabu",[54],[15,133,134],{},"How I recreated Vue Fes Japan 2025 website using TresJS and TSL (WebGPU)",[11,136,137,138,142,143,146],{},"The Vue Fes Japan 2025 website had a beautiful hero: a V-shaped cone for Vue and a sphere for the Hinomaru of the Japanese flag, both masked with a ",[139,140,141],"em",{},"suminagashi"," shader. Suminagashi is a Japanese ink-marbling technique that is hundreds of years old. The original scene was made with raw Three.js r178 by the ",[15,144,145],{},"Vue Fes Japan 2025 team",", and all credit for the design goes to them.",[11,148,149],{},"In the talk, I showed how I ported that scene to Vue with TresJS components, and how I moved the GLSL shader to TSL on top of WebGPU. We went through the FBM noise that flows through warped vector fields, the ink bands, and the color palettes that change over time.",[151,152],"blog-embed-lab",{"src":153,"title":154},"https:\u002F\u002Flab.tresjs.org\u002Fexperiments\u002Fvuefes-japan-2025\u002F","Vue Fes Japan 2025 hero demo",[11,156,157,158,83],{},"The live demo is in the ",[50,159,161],{"href":153,"rel":160},[54],"lab",[163,164,168],"read-more",{"icon":165,"title":166,"to":167},"i-lucide-presentation","Vue Fes Japan 2026 slides","https:\u002F\u002Fvuefesjapan-2026.alvarosabu.dev\u002F",[11,169,170,171,174],{},"See the ",[15,172,173],{},"slides"," of the talk.",[11,176,177,178,183],{},"A big thank you to the ",[50,179,182],{"href":180,"rel":181},"https:\u002F\u002Fgithub.com\u002Fvuejs-jp",[54],"Vue.js Japan User Group"," and all the Vue Fes Japan staff and volunteers. The event was organized with so much care, and the community made us feel at home ありがとうございます 🙏.",[37,185,187],{"id":186},"webgpu-gets-its-own-entry","WebGPU gets its own entry",[11,189,190,191,31,194,197,198,201,202,207],{},"The headline of this release. Until now, you had to pass a renderer factory to ",[24,192,193],{},"TresCanvas",[24,195,196],{},"extend()"," the node classes yourself to use WebGPU. In ",[24,199,200],{},"@tresjs\u002Fcore@5.10.0",", you change one import (",[50,203,206],{"href":204,"rel":205},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1543",[54],"#1543","):",[209,210,215],"pre",{"className":211,"code":212,"language":213,"meta":214,"style":214},"language-vue shiki shiki-themes catppuccin-latte catppuccin-latte catppuccin-frappe","\u003Cscript setup lang=\"ts\">\nimport { TresCanvas } from '@tresjs\u002Fcore\u002Fwebgpu'\nimport { color, mix, positionLocal, sin, time } from 'three\u002Ftsl'\n\nconst colorNode = mix(\n  color('#82dbc5'),\n  color('#fbb03b'),\n  sin(time.add(positionLocal.y.mul(4))).mul(0.5).add(0.5),\n)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CTresCanvas>\n    \u003CTresPerspectiveCamera :position=\"[3, 3, 3]\" :look-at=\"[0, 0, 0]\" \u002F>\n    \u003CTresMesh>\n      \u003CTresTorusKnotGeometry :args=\"[0.6, 0.2, 128, 32]\" \u002F>\n      \u003CTresMeshStandardNodeMaterial :color-node=\"colorNode\" :roughness=\"0.3\" \u002F>\n    \u003C\u002FTresMesh>\n    \u003CTresDirectionalLight :position=\"[3, 5, 2]\" \u002F>\n  \u003C\u002FTresCanvas>\n\u003C\u002Ftemplate>\n","vue","",[24,216,217,247,271,309,316,333,351,365,424,430,440,445,455,465,493,503,522,548,558,575,585],{"__ignoreMap":214},[218,219,222,226,230,234,237,240,244],"span",{"class":220,"line":221},"line",1,[218,223,225],{"class":224},"sWdzt","\u003C",[218,227,229],{"class":228},"slJ5s","script",[218,231,233],{"class":232},"s1cdE"," setup",[218,235,236],{"class":232}," lang",[218,238,239],{"class":224},"=",[218,241,243],{"class":242},"s9Zht","\"ts\"",[218,245,246],{"class":224},">\n",[218,248,250,254,258,262,265,268],{"class":220,"line":249},2,[218,251,253],{"class":252},"sZyUJ","import",[218,255,257],{"class":256},"spKPg"," {",[218,259,261],{"class":260},"s9Av-"," TresCanvas ",[218,263,264],{"class":256},"}",[218,266,267],{"class":252}," from",[218,269,270],{"class":242}," '@tresjs\u002Fcore\u002Fwebgpu'\n",[218,272,274,276,278,281,284,287,289,292,294,297,299,302,304,306],{"class":220,"line":273},3,[218,275,253],{"class":252},[218,277,257],{"class":256},[218,279,280],{"class":260}," color",[218,282,283],{"class":256},",",[218,285,286],{"class":260}," mix",[218,288,283],{"class":256},[218,290,291],{"class":260}," positionLocal",[218,293,283],{"class":256},[218,295,296],{"class":260}," sin",[218,298,283],{"class":256},[218,300,301],{"class":260}," time ",[218,303,264],{"class":256},[218,305,267],{"class":252},[218,307,308],{"class":242}," 'three\u002Ftsl'\n",[218,310,312],{"class":220,"line":311},4,[218,313,315],{"emptyLinePlaceholder":314},true,"\n",[218,317,319,322,325,327,330],{"class":220,"line":318},5,[218,320,321],{"class":252},"const",[218,323,324],{"class":260}," colorNode ",[218,326,239],{"class":224},[218,328,286],{"class":329},"s0faT",[218,331,332],{"class":260},"(\n",[218,334,336,339,342,345,348],{"class":220,"line":335},6,[218,337,338],{"class":329},"  color",[218,340,341],{"class":260},"(",[218,343,344],{"class":242},"'#82dbc5'",[218,346,347],{"class":260},")",[218,349,350],{"class":256},",\n",[218,352,354,356,358,361,363],{"class":220,"line":353},7,[218,355,338],{"class":329},[218,357,341],{"class":260},[218,359,360],{"class":242},"'#fbb03b'",[218,362,347],{"class":260},[218,364,350],{"class":256},[218,366,368,371,374,376,379,382,384,387,389,392,394,398,401,403,405,407,410,412,414,416,418,420,422],{"class":220,"line":367},8,[218,369,370],{"class":329},"  sin",[218,372,373],{"class":260},"(time",[218,375,83],{"class":224},[218,377,378],{"class":329},"add",[218,380,381],{"class":260},"(positionLocal",[218,383,83],{"class":224},[218,385,386],{"class":260},"y",[218,388,83],{"class":224},[218,390,391],{"class":329},"mul",[218,393,341],{"class":260},[218,395,397],{"class":396},"sREMW","4",[218,399,400],{"class":260},")))",[218,402,83],{"class":224},[218,404,391],{"class":329},[218,406,341],{"class":260},[218,408,409],{"class":396},"0.5",[218,411,347],{"class":260},[218,413,83],{"class":224},[218,415,378],{"class":329},[218,417,341],{"class":260},[218,419,409],{"class":396},[218,421,347],{"class":260},[218,423,350],{"class":256},[218,425,427],{"class":220,"line":426},9,[218,428,429],{"class":260},")\n",[218,431,433,436,438],{"class":220,"line":432},10,[218,434,435],{"class":224},"\u003C\u002F",[218,437,229],{"class":228},[218,439,246],{"class":224},[218,441,443],{"class":220,"line":442},11,[218,444,315],{"emptyLinePlaceholder":314},[218,446,448,450,453],{"class":220,"line":447},12,[218,449,225],{"class":224},[218,451,452],{"class":228},"template",[218,454,246],{"class":224},[218,456,458,461,463],{"class":220,"line":457},13,[218,459,460],{"class":224},"  \u003C",[218,462,193],{"class":228},[218,464,246],{"class":224},[218,466,468,471,474,477,479,482,485,487,490],{"class":220,"line":467},14,[218,469,470],{"class":224},"    \u003C",[218,472,473],{"class":228},"TresPerspectiveCamera",[218,475,476],{"class":232}," :position",[218,478,239],{"class":224},[218,480,481],{"class":242},"\"[3, 3, 3]\"",[218,483,484],{"class":232}," :look-at",[218,486,239],{"class":224},[218,488,489],{"class":242},"\"[0, 0, 0]\"",[218,491,492],{"class":224}," \u002F>\n",[218,494,496,498,501],{"class":220,"line":495},15,[218,497,470],{"class":224},[218,499,500],{"class":228},"TresMesh",[218,502,246],{"class":224},[218,504,506,509,512,515,517,520],{"class":220,"line":505},16,[218,507,508],{"class":224},"      \u003C",[218,510,511],{"class":228},"TresTorusKnotGeometry",[218,513,514],{"class":232}," :args",[218,516,239],{"class":224},[218,518,519],{"class":242},"\"[0.6, 0.2, 128, 32]\"",[218,521,492],{"class":224},[218,523,525,527,530,533,535,538,541,543,546],{"class":220,"line":524},17,[218,526,508],{"class":224},[218,528,529],{"class":228},"TresMeshStandardNodeMaterial",[218,531,532],{"class":232}," :color-node",[218,534,239],{"class":224},[218,536,537],{"class":242},"\"colorNode\"",[218,539,540],{"class":232}," :roughness",[218,542,239],{"class":224},[218,544,545],{"class":242},"\"0.3\"",[218,547,492],{"class":224},[218,549,551,554,556],{"class":220,"line":550},18,[218,552,553],{"class":224},"    \u003C\u002F",[218,555,500],{"class":228},[218,557,246],{"class":224},[218,559,561,563,566,568,570,573],{"class":220,"line":560},19,[218,562,470],{"class":224},[218,564,565],{"class":228},"TresDirectionalLight",[218,567,476],{"class":232},[218,569,239],{"class":224},[218,571,572],{"class":242},"\"[3, 5, 2]\"",[218,574,492],{"class":224},[218,576,578,581,583],{"class":220,"line":577},20,[218,579,580],{"class":224},"  \u003C\u002F",[218,582,193],{"class":228},[218,584,246],{"class":224},[218,586,588,590,592],{"class":220,"line":587},21,[218,589,435],{"class":224},[218,591,452],{"class":228},[218,593,246],{"class":224},[11,595,596,597,600],{},"What ",[24,598,599],{},"@tresjs\u002Fcore\u002Fwebgpu"," gives you:",[88,602,603],{},[91,604,605,640,657,676],{},[94,606,607,616,617,27,620,27,623,27,626,27,629,31,632,635,636,639],{},[15,608,609,610,612,613,83],{},"A ",[24,611,193],{}," that creates a ",[24,614,615],{},"WebGPURenderer"," It passes ",[24,618,619],{},"antialias",[24,621,622],{},"alpha",[24,624,625],{},"depth",[24,627,628],{},"stencil",[24,630,631],{},"powerPreference",[24,633,634],{},"logarithmicDepthBuffer"," to the renderer. The ",[24,637,638],{},"renderer"," prop is still there for other options.",[94,641,642,645,646,649,650,653,654,656],{},[15,643,644],{},"Node materials as tags."," The entry adds every class of ",[24,647,648],{},"three\u002Fwebgpu"," to the catalogue, so ",[24,651,652],{},"\u003CTresMeshStandardNodeMaterial>"," works with no ",[24,655,196],{},". The tags and their props are typed.",[94,658,659,665,666,668,669,671,672,675],{},[15,660,661,662,83],{},"A typed ",[24,663,664],{},"useTres()"," ",[24,667,638],{}," is a ",[24,670,615],{},", so ",[24,673,674],{},"renderer.backend"," needs no cast.",[94,677,678,685,686,688,689,694],{},[15,679,680,681,684],{},"No ",[24,682,683],{},"WebGLRenderer"," in your bundle."," An app that imports only from ",[24,687,599],{}," does not ship the WebGL renderer (",[50,690,693],{"href":691,"rel":692},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1544",[54],"#1544",").",[11,696,697,698,701,702,704,705,707,708,710,711,714,715,717],{},"The root entry ",[24,699,700],{},"@tresjs\u002Fcore"," does not change. Its ",[24,703,193],{}," still uses ",[24,706,683],{},", and a build check fails if the root entry can reach ",[24,709,648],{}," or ",[24,712,713],{},"three\u002Ftsl",". When the browser has no WebGPU, ",[24,716,615],{}," falls back to its WebGL2 backend, and node materials still work.",[11,719,720,721,724,725,730,731,31,734,737],{},"The same release fixes a bug that made TSL feel broken: patching a node prop such as ",[24,722,723],{},"colorNode"," now recompiles the node material (",[50,726,729],{"href":727,"rel":728},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1540",[54],"#1540","). Before, the renderer kept the old pipeline and nothing changed on screen. ",[24,732,733],{},"isNode",[24,735,736],{},"isNodeMaterial"," are new public exports.",[11,739,740,741,83],{},"Everything is in the ",[50,742,745],{"href":743,"rel":744},"https:\u002F\u002Fdocs.tresjs.org\u002Fapi\u002Fadvanced\u002Fweb-gpu",[54],"WebGPU guide",[58,747,749],{"id":748},"cientos-speaks-tsl","Cientos speaks TSL",[11,751,752,755],{},[24,753,754],{},"@tresjs\u002Fcientos\u002Fwebgpu"," has the same names and props as the root entry, so you only change the import path:",[209,757,761],{"className":758,"code":759,"language":760,"meta":214,"style":214},"language-ts shiki shiki-themes catppuccin-latte catppuccin-latte catppuccin-frappe","import { TresCanvas } from '@tresjs\u002Fcore\u002Fwebgpu'\nimport { OrbitControls, Sparkles, Stars } from '@tresjs\u002Fcientos\u002Fwebgpu'\n","ts",[24,762,763,777],{"__ignoreMap":214},[218,764,765,767,769,771,773,775],{"class":220,"line":221},[218,766,253],{"class":252},[218,768,257],{"class":256},[218,770,261],{"class":260},[218,772,264],{"class":256},[218,774,267],{"class":252},[218,776,270],{"class":242},[218,778,779,781,783,786,788,791,793,796,798,800],{"class":220,"line":249},[218,780,253],{"class":252},[218,782,257],{"class":256},[218,784,785],{"class":260}," OrbitControls",[218,787,283],{"class":256},[218,789,790],{"class":260}," Sparkles",[218,792,283],{"class":256},[218,794,795],{"class":260}," Stars ",[218,797,264],{"class":256},[218,799,267],{"class":252},[218,801,802],{"class":242}," '@tresjs\u002Fcientos\u002Fwebgpu'\n",[11,804,805,806,809,810,812],{},"Components that used GLSL in the root entry are now ",[15,807,808],{},"TSL ports"," in the WebGPU entry. ",[24,811,615],{}," compiles them to WGSL, or to GLSL on the WebGL2 fallback:",[88,814,815],{},[91,816,817,831,842],{},[94,818,819,27,822,27,825,31,828],{},[24,820,821],{},"Grid",[24,823,824],{},"Outline",[24,826,827],{},"Html",[24,829,830],{},"Image",[94,832,833,27,836,31,839],{},[24,834,835],{},"Sparkles",[24,837,838],{},"Stars",[24,840,841],{},"Precipitation",[94,843,844,27,847,27,850,27,853,31,856],{},[24,845,846],{},"HolographicMaterial",[24,848,849],{},"MeshGlassMaterial",[24,851,852],{},"MeshWobbleMaterial",[24,854,855],{},"MeshDiscardMaterial",[24,857,858],{},"PointMaterial",[11,860,861,862,865,866,27,868,31,870,872,873,876,877,880],{},"WebGPU draws ",[24,863,864],{},"Points"," at 1 pixel only, so ",[24,867,835],{},[24,869,838],{},[24,871,841],{}," render one instanced ",[24,874,875],{},"Sprite"," with ",[24,878,879],{},"PointsNodeMaterial"," in their WebGPU versions.",[11,882,883,884,27,887,27,890,893,894,27,897,27,900,903,904,906,907,83],{},"Some components are not ported yet: the ones that write GLSL with render targets (",[24,885,886],{},"ContactShadows",[24,888,889],{},"MeshTransmissionMaterial",[24,891,892],{},"MeshPortalMaterial","...), the line components, and the ones built on three-stdlib shaders (",[24,895,896],{},"Sky",[24,898,899],{},"Reflector",[24,901,902],{},"Stage","...). If you import one of them from ",[24,905,754],{},", the build and the type check fail and name the component. If you use one from the root entry on a WebGPU canvas, cientos logs one warning that names it. TSL versions will come one by one. The full list is in the ",[50,908,911],{"href":909,"rel":910},"https:\u002F\u002Fcientos.tresjs.org\u002Fgetting-started\u002Fwebgpu",[54],"Cientos WebGPU guide",[913,914,915],"prose-note",{},[11,916,917,919,920,923,924,926,927,929],{},[24,918,754],{}," needs ",[24,921,922],{},"three"," r171 or newer and ",[24,925,700],{}," 5.10 or newer. The root entry still supports ",[24,928,922],{}," r133 and newer.",[58,931,933],{"id":932},"nuxt-one-option","Nuxt: one option",[11,935,936,939,940,942,943,207],{},[24,937,938],{},"@tresjs\u002Fnuxt@5.8.0"," has a new ",[24,941,638],{}," option (",[50,944,947],{"href":945,"rel":946},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1527",[54],"#1527",[209,949,952],{"className":758,"code":950,"filename":951,"language":760,"meta":214,"style":214},"export default defineNuxtConfig({\n  modules: ['@tresjs\u002Fnuxt'],\n  tres: {\n    renderer: 'webgpu',\n  },\n})\n","nuxt.config.ts",[24,953,954,970,989,999,1011,1016],{"__ignoreMap":214},[218,955,956,959,962,965,967],{"class":220,"line":221},[218,957,958],{"class":252},"export",[218,960,961],{"class":252}," default",[218,963,964],{"class":329}," defineNuxtConfig",[218,966,341],{"class":260},[218,968,969],{"class":256},"{\n",[218,971,972,975,978,981,984,987],{"class":220,"line":249},[218,973,974],{"class":260},"  modules",[218,976,977],{"class":224},":",[218,979,980],{"class":260}," [",[218,982,983],{"class":242},"'@tresjs\u002Fnuxt'",[218,985,986],{"class":260},"]",[218,988,350],{"class":256},[218,990,991,994,996],{"class":220,"line":273},[218,992,993],{"class":260},"  tres",[218,995,977],{"class":224},[218,997,998],{"class":256}," {\n",[218,1000,1001,1004,1006,1009],{"class":220,"line":311},[218,1002,1003],{"class":260},"    renderer",[218,1005,977],{"class":224},[218,1007,1008],{"class":242}," 'webgpu'",[218,1010,350],{"class":256},[218,1012,1013],{"class":220,"line":318},[218,1014,1015],{"class":256},"  },\n",[218,1017,1018,1020],{"class":220,"line":335},[218,1019,264],{"class":256},[218,1021,429],{"class":260},[11,1023,1024,1025,27,1028,1030,1031,1034,1035,1038,1039,1041],{},"With it, ",[24,1026,1027],{},"\u003CTresCanvas>",[24,1029,664],{}," and the cientos components are auto-imported from the ",[24,1032,1033],{},"\u002Fwebgpu"," entries. A cientos component with no WebGPU version yet still resolves, but it throws an error that names it when it mounts, instead of Vue's generic \"Failed to resolve component\". ",[24,1036,1037],{},"@tresjs\u002Fpost-processing"," is not auto-imported in this mode, because its effects work only with ",[24,1040,683],{},", and the module tells you so.",[37,1043,1045],{"id":1044},"n8ao-ambient-occlusion","N8AO ambient occlusion",[11,1047,1048,1051,1052,1057,1058,69,1063,1068],{},[24,1049,1050],{},"@tresjs\u002Fpost-processing@3.10.0"," adds ",[50,1053,1056],{"href":1054,"rel":1055},"https:\u002F\u002Fgithub.com\u002FN8python\u002Fn8ao",[54],"N8AO",", the screen-space ambient occlusion pass by ",[50,1059,1062],{"href":1060,"rel":1061},"https:\u002F\u002Fgithub.com\u002FN8python",[54],"N8python",[50,1064,1067],{"href":1065,"rel":1066},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1518",[54],"#1518","). AO darkens corners, crevices and the contact areas below objects, so flat scenes get depth. It comes in both families:",[88,1070,1071],{},[91,1072,1073,1086],{},[94,1074,1075,1082,1083],{},[50,1076,1079],{"href":1077,"rel":1078},"https:\u002F\u002Fpost-processing.tresjs.org\u002Fapi\u002Fpmndrs\u002Fn8ao",[54],[24,1080,1081],{},"\u003CN8AOPmndrs \u002F>"," for ",[24,1084,1085],{},"\u003CEffectComposerPmndrs>",[94,1087,1088,1095,1096],{},[50,1089,1092],{"href":1090,"rel":1091},"https:\u002F\u002Fpost-processing.tresjs.org\u002Fapi\u002Fthree\u002Fn8ao",[54],[24,1093,1094],{},"\u003CN8AO \u002F>"," for the three family ",[24,1097,1098],{},"\u003CEffectComposer>",[209,1100,1102],{"className":211,"code":1101,"language":213,"meta":214,"style":214},"\u003CSuspense>\n  \u003CEffectComposerPmndrs :multisampling=\"0\">\n    \u003CN8AOPmndrs :ao-radius=\"2\" :intensity=\"3\" \u002F>\n    \u003CSMAAPmndrs \u002F>\n  \u003C\u002FEffectComposerPmndrs>\n\u003C\u002FSuspense>\n",[24,1103,1104,1113,1118,1123,1128,1133],{"__ignoreMap":214},[218,1105,1106,1108,1111],{"class":220,"line":221},[218,1107,225],{"class":224},[218,1109,1110],{"class":228},"Suspense",[218,1112,246],{"class":224},[218,1114,1115],{"class":220,"line":249},[218,1116,1117],{"class":260},"  \u003CEffectComposerPmndrs :multisampling=\"0\">\n",[218,1119,1120],{"class":220,"line":273},[218,1121,1122],{"class":260},"    \u003CN8AOPmndrs :ao-radius=\"2\" :intensity=\"3\" \u002F>\n",[218,1124,1125],{"class":220,"line":311},[218,1126,1127],{"class":260},"    \u003CSMAAPmndrs \u002F>\n",[218,1129,1130],{"class":220,"line":318},[218,1131,1132],{"class":260},"  \u003C\u002FEffectComposerPmndrs>\n",[218,1134,1135,1137,1139],{"class":220,"line":335},[218,1136,435],{"class":224},[218,1138,1110],{"class":228},[218,1140,246],{"class":224},[11,1142,1143,1144,1147,1148,710,1151,1154,1155,1160],{},"Every prop is reactive, and ",[24,1145,1146],{},"renderMode"," gives you debug views, including a split view with and without AO. Hardware multisampling does not work with AO, so add ",[24,1149,1150],{},"\u003CSMAAPmndrs \u002F>",[24,1152,1153],{},"\u003CFXAAPmndrs \u002F>"," after the pass. The ",[50,1156,1159],{"href":1157,"rel":1158},"https:\u002F\u002Flab.tresjs.org\u002Fexperiments\u002Frapier-object-clump\u002F",[54],"Rapier Object Clump"," experiment in the lab now uses the package component.",[37,1162,1164],{"id":1163},"fixes-worth-knowing-about","Fixes worth knowing about",[58,1166,1168],{"id":1167},"core","Core",[88,1170,1171],{},[91,1172,1173,1212,1223,1236],{},[94,1174,1175,69,1182,1187,1188,1191,1192,1194,1195,27,1198,27,1201,31,1204,1207,1208,1211],{},[15,1176,1177,1178,1181],{},"Awaiting ",[24,1179,1180],{},"useLoader"," returns everything",[50,1183,1186],{"href":1184,"rel":1185},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1548",[54],"#1548","). ",[24,1189,1190],{},"await useGLTF(...)",", or any loader built on ",[24,1193,1180],{},", resolved with a partial object and dropped ",[24,1196,1197],{},"nodes",[24,1199,1200],{},"materials",[24,1202,1203],{},"load",[24,1205,1206],{},"progress",". Now ",[24,1209,1210],{},"const { state, nodes } = await useGLTF('\u002Fmodel.glb')"," works as you would expect.",[94,1213,1214,69,1217,1222],{},[15,1215,1216],{},"On-demand scenes stay idle after a prop update",[50,1218,1221],{"href":1219,"rel":1220},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1499",[54],"#1499","). A component that created a fresh position array could make an on-demand scene render again and again.",[94,1224,1225,69,1228,1187,1233,1235],{},[15,1226,1227],{},"No devtools in production",[50,1229,1232],{"href":1230,"rel":1231},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1498",[54],"#1498",[24,1234,193],{}," registered the devtools in production builds too, and their performance monitor walked the scene even with on-demand rendering.",[94,1237,1238,69,1244,1249,1250,1253,1254,1256,1257,1259],{},[15,1239,1240,1243],{},[24,1241,1242],{},"PCFShadowMap"," on WebGPU",[50,1245,1248],{"href":1246,"rel":1247},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1508",[54],"#1508","). three r186 removed ",[24,1251,1252],{},"PCFSoftShadowMap"," from ",[24,1255,615],{}," and logged a warning on every WebGPU scene with shadows. From r186, ",[24,1258,1242],{}," is the default on WebGPU too, and it is already soft there, so you lose no quality.",[11,1261,1262,1263,1268],{},"The first two fixes come from ",[50,1264,1267],{"href":1265,"rel":1266},"https:\u002F\u002Fgithub.com\u002Ffelixschwamm",[54],"Felix Schwämmle",", in their first contributions to TresJS, with a reproduction test for each. Welcome, Felix 🎉!",[58,1270,1272],{"id":1271},"cientos","Cientos",[11,1274,1275,1277,1278,1187,1283,1286],{},[24,1276,858],{}," converted its color to sRGB twice (",[50,1279,1282],{"href":1280,"rel":1281},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1539",[54],"#1539",[24,1284,1285],{},"color=\"#ffa500\""," rendered yellow, now it renders orange.",[913,1288,1289],{},[11,1290,1291,1292,1295],{},"This changes how existing scenes look: dots are darker and more saturated, the same as with ",[24,1293,1294],{},"PointsMaterial",". If you tuned your colors for the old look, check them again.",[58,1297,1299],{"id":1298},"rapier","Rapier",[11,1301,1302,1305],{},[24,1303,1304],{},"@tresjs\u002Frapier@1.1.3"," brings two fixes:",[88,1307,1308],{},[91,1309,1310,1342],{},[94,1311,1312,69,1315,1320,1321,1324,1325,1328,1329,1332,1333,1335,1336,31,1338,1341],{},[15,1313,1314],{},"Custom colliders sit on their body",[50,1316,1319],{"href":1317,"rel":1318},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1515",[54],"#1515","). A ",[24,1322,1323],{},"\u003CCapsuleCollider>"," inside a ",[24,1326,1327],{},"\u003CRigidBody>"," with a ",[24,1330,1331],{},"position"," got the body offset twice, and a collider ",[24,1334,1331],{}," was read as a world position. Collider ",[24,1337,1331],{},[24,1339,1340],{},"rotation"," are now offsets from the body, as the types say. If you used world values to work around this, your colliders will move.",[94,1343,1344,69,1350,1355],{},[15,1345,1346,1349],{},[24,1347,1348],{},"\u003CPhysics debug>"," lines are visible",[50,1351,1354],{"href":1352,"rel":1353},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1514",[54],"#1514","). They were almost black, and colliders inside a mesh did not show. They now draw on top in Rapier's colors.",[58,1357,1359],{"id":1358},"tres-leches","Tres Leches",[11,1361,1362,1363,1368,1369,1374,1375,694],{},"Better dark mode contrast for folders and inputs (",[50,1364,1367],{"href":1365,"rel":1366},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1517",[54],"#1517","), slot content that stays visible when the panel height changes (",[50,1370,1373],{"href":1371,"rel":1372},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1523",[54],"#1523","), and a collapsed panel that keeps its size when the window resizes (",[50,1376,1379],{"href":1377,"rel":1378},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1546",[54],"#1546",[37,1381,1383],{"id":1382},"everything-in-sync","Everything in sync",[11,1385,1386],{},"The family moved together on October 6, October 22 and again on October 28. These are the latest:",[88,1388,1389],{},[91,1390,1391,1398,1405,1412,1419,1426],{},[94,1392,1393],{},[15,1394,1395],{},[24,1396,1397],{},"@tresjs\u002Fcore@5.10.1",[94,1399,1400],{},[15,1401,1402],{},[24,1403,1404],{},"@tresjs\u002Fcientos@5.10.1",[94,1406,1407],{},[15,1408,1409],{},[24,1410,1411],{},"@tresjs\u002Fnuxt@5.8.1",[94,1413,1414],{},[15,1415,1416],{},[24,1417,1418],{},"@tresjs\u002Fpost-processing@3.11.1",[94,1420,1421],{},[15,1422,1423],{},[24,1424,1425],{},"@tresjs\u002Frapier@1.2.1",[94,1427,1428],{},[15,1429,1430],{},[24,1431,1432],{},"@tresjs\u002Fleches@1.3.3",[209,1434,1438],{"className":1435,"code":1436,"language":1437,"meta":214,"style":214},"language-bash shiki shiki-themes catppuccin-latte catppuccin-latte catppuccin-frappe","pnpm up @tresjs\u002Fcore @tresjs\u002Fcientos @tresjs\u002Fnuxt @tresjs\u002Fpost-processing @tresjs\u002Frapier @tresjs\u002Fleches\n","bash",[24,1439,1440],{"__ignoreMap":214},[218,1441,1442,1445,1448,1451,1454,1457,1460,1463],{"class":220,"line":221},[218,1443,1444],{"class":329},"pnpm",[218,1446,1447],{"class":242}," up",[218,1449,1450],{"class":242}," @tresjs\u002Fcore",[218,1452,1453],{"class":242}," @tresjs\u002Fcientos",[218,1455,1456],{"class":242}," @tresjs\u002Fnuxt",[218,1458,1459],{"class":242}," @tresjs\u002Fpost-processing",[218,1461,1462],{"class":242}," @tresjs\u002Frapier",[218,1464,1465],{"class":242}," @tresjs\u002Fleches\n",[58,1467,1469],{"id":1468},"full-release-notes","👉 Full Release Notes",[163,1471],{"icon":1472,"title":1473,"to":1474},"i-lucide-scroll-text","Full Release Notes","https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Freleases",[37,1476,1478],{"id":1477},"from-the-community","From the community",[37,1480,1482],{"id":1481},"thanks","Thanks",[11,1484,1485,1486,1489,1490,1493,1494,1497,1498,1501],{},"Thank you to ",[50,1487,67],{"href":68,"rel":1488},[54]," for bringing TresJS to XR devices on the Vue Fes stage, to the Vue Fes Japan 2025 team for the design that inspired my talk, to the ",[50,1491,182],{"href":180,"rel":1492},[54]," for an amazing conference, to ",[50,1495,1267],{"href":1265,"rel":1496},[54]," for their first two core fixes, and to ",[50,1499,1062],{"href":1060,"rel":1500},[54]," for N8AO. And thanks to everyone who opened an issue this month 🙌.",[37,1503,1505],{"id":1504},"coming-next-tsl-composables","Coming next: TSL composables",[11,1507,1508,1510,1511,1082,1514,69,1516,694],{},[24,1509,1033],{}," is the foundation. The next step is in review: a set of ",[15,1512,1513],{},"experimental TSL composables",[24,1515,599],{},[50,1517,1520],{"href":1518,"rel":1519},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1545",[54],"#1545",[88,1522,1523],{},[91,1524,1525,1540,1551],{},[94,1526,1527,1535,1536,1539],{},[15,1528,1529,31,1532],{},[24,1530,1531],{},"useUniforms",[24,1533,1534],{},"useUniform"," bind plain values, refs, getters or Tres Leches controls to TSL uniforms. A change writes ",[24,1537,1538],{},"uniform.value"," with no shader recompile, and requests a frame in on-demand mode.",[94,1541,1542,1550],{},[15,1543,1544,31,1547],{},[24,1545,1546],{},"useNodes",[24,1548,1549],{},"useLocalNodes"," share node graphs between components in the same canvas.",[94,1552,1553,1558,1559,1562],{},[15,1554,1555],{},[24,1556,1557],{},"useRenderPipeline"," renders the canvas through three's ",[24,1560,1561],{},"RenderPipeline",", for post-processing on WebGPU.",[11,1564,1565,1566,83],{},"The API can still change, so watch the PR. If you have a TSL use case you want us to cover, ",[50,1567,1570],{"href":1568,"rel":1569},"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fissues",[54],"tell us",[11,1572,1573,1574,1579,1580,83],{},"Got something cool built with Tres? Share it in our ",[50,1575,1578],{"href":1576,"rel":1577},"https:\u002F\u002Fdiscord.gg\u002FUCr96AQmWn",[54],"Discord",". It might headline the next ",[139,1581,1582],{},"Loop Chronicles",[11,1584,1585],{},"Happy crafting ✌️.",[1587,1588,1589],"style",{},"html pre.shiki code .sWdzt, html code.shiki .sWdzt{--shiki-light:#179299;--shiki-default:#179299;--shiki-dark:#81C8BE}html pre.shiki code .slJ5s, html code.shiki .slJ5s{--shiki-light:#1E66F5;--shiki-default:#1E66F5;--shiki-dark:#8CAAEE}html pre.shiki code .s1cdE, html code.shiki .s1cdE{--shiki-light:#DF8E1D;--shiki-default:#DF8E1D;--shiki-dark:#E5C890}html pre.shiki code .s9Zht, html code.shiki .s9Zht{--shiki-light:#40A02B;--shiki-default:#40A02B;--shiki-dark:#A6D189}html pre.shiki code .sZyUJ, html code.shiki .sZyUJ{--shiki-light:#8839EF;--shiki-default:#8839EF;--shiki-dark:#CA9EE6}html pre.shiki code .spKPg, html code.shiki .spKPg{--shiki-light:#7C7F93;--shiki-default:#7C7F93;--shiki-dark:#949CBB}html pre.shiki code .s9Av-, html code.shiki .s9Av-{--shiki-light:#4C4F69;--shiki-default:#4C4F69;--shiki-dark:#C6D0F5}html pre.shiki code .s0faT, html code.shiki .s0faT{--shiki-light:#1E66F5;--shiki-light-font-style:italic;--shiki-default:#1E66F5;--shiki-default-font-style:italic;--shiki-dark:#8CAAEE;--shiki-dark-font-style:italic}html pre.shiki code .sREMW, html code.shiki .sREMW{--shiki-light:#FE640B;--shiki-default:#FE640B;--shiki-dark:#EF9F76}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":214,"searchDepth":249,"depth":249,"links":1591},[1592,1596,1600,1601,1607,1610,1611,1612],{"id":39,"depth":249,"text":40,"children":1593},[1594,1595],{"id":60,"depth":273,"text":61},{"id":123,"depth":273,"text":124},{"id":186,"depth":249,"text":187,"children":1597},[1598,1599],{"id":748,"depth":273,"text":749},{"id":932,"depth":273,"text":933},{"id":1044,"depth":249,"text":1045},{"id":1163,"depth":249,"text":1164,"children":1602},[1603,1604,1605,1606],{"id":1167,"depth":273,"text":1168},{"id":1271,"depth":273,"text":1272},{"id":1298,"depth":273,"text":1299},{"id":1358,"depth":273,"text":1359},{"id":1382,"depth":249,"text":1383,"children":1608},[1609],{"id":1468,"depth":273,"text":1469},{"id":1477,"depth":249,"text":1478},{"id":1481,"depth":249,"text":1482},{"id":1504,"depth":249,"text":1505},"updates","2026-10-29","WebGPU gets its own entry in TresJS! A recap of October 2026 - @tresjs\u002Fcore 5.10, TSL ports in Cientos, N8AO ambient occlusion and two TresJS talks at Vue Fes Japan 2026.",false,"md",{},"\u002Fblog\u002Fwhats-new-october-2026","---\ntitle: \"The Loop Chronicles: October 2026 Recap\"\nauthor: alvarosabu\ncategory: updates\ndate: 2026-10-29\ndescription: WebGPU gets its own entry in TresJS! A recap of October 2026 - @tresjs\u002Fcore 5.10, TSL ports in Cientos, N8AO ambient occlusion and two TresJS talks at Vue Fes Japan 2026.\ndraft: false\nthumbnail: \u002Fblog\u002Fwhats-new-october-2026\u002Fthe-loop-chronicles-october-2026.png\n---\n\nYo! Welcome back to **The Loop Chronicles** 🎃 👻. This edition comes to you from Tokyo 🗼. October was a big month: TresJS was on stage **twice** at Vue Fes Japan 2026, and WebGPU stopped being a setup trick and became a proper entry point in `@tresjs\u002Fcore@5.10`, `@tresjs\u002Fcientos@5.10` and `@tresjs\u002Fnuxt@5.8`. Let's go 🚀.\n\n## TresJS at Vue Fes Japan 2026\n\n![TresJS at Vue Fes Japan 2026](\u002Fblog\u002Fwhats-new-october-2026\u002Fvuefes-japan-2026.png)\n\n[Vue Fes Japan 2026](https:\u002F\u002Fvuefes.jp\u002F2026\u002Fen) took place on October 24 at Otemachi Place in Tokyo. Two of the talks were about TresJS, and for us that is a dream come true 🇯🇵.\n\n### Spatial Computing, Written in Vue\n\n:magic-link{label=\"Shingo Hiranuma\" to=\"https:\u002F\u002Fgithub.com\u002Fhiranuma\"} ([@mistorun](https:\u002F\u002Fx.com\u002Fmistorun)), CTO at GENEROSITY inc., gave [**Spatial Computing with Vue: Frontend Development for XR Devices Using TresJS and WebXR**](https:\u002F\u002Fvuefes.jp\u002F2026\u002Fen\u002Fspeaker\u002Fhiranuma).\n\nThe idea: you can build spatial computing apps for devices like the Meta Quest 3 and the Samsung Galaxy XR with the Vue Composition API you already know. No new framework to learn. Shingo showed implementation patterns for XR frontends with Vue, TresJS and WebXR:\n\n::prose-list\n- Gaze and gesture interaction\n- Declarative scene construction\n- Support for both hand tracking and controllers\n- Physics engine integration\n::\n\nWith glasses-type devices like XREAL Project Aura and Snap Specs arriving this fall, this talk is a great map of where Vue can go next. The slides are available in [English](https:\u002F\u002Fspeakerdeck.com\u002Fhiranuma\u002Fspatial-computing-written-in-vue-front-end-development-for-xr-devices-with-tresjs-and-webxr) and in [Japanese](https:\u002F\u002Fspeakerdeck.com\u002Fhiranuma\u002Fvue-de-kaku-kuukan-tresjs-to-webxr-o-tsukata-xr-debaisu-no-furonto-endo-kaihatsu). Thank you, Shingo, for taking TresJS into XR 🥽🙌.\n\n### How I recreated the Vue Fes Japan 2025 website using TresJS and TSL\n\nLater that afternoon, I gave [**How I recreated Vue Fes Japan 2025 website using TresJS and TSL (WebGPU)**](https:\u002F\u002Fvuefes.jp\u002F2026\u002Fen\u002Fspeaker\u002Falvarosabu).\n\nThe Vue Fes Japan 2025 website had a beautiful hero: a V-shaped cone for Vue and a sphere for the Hinomaru of the Japanese flag, both masked with a *suminagashi* shader. Suminagashi is a Japanese ink-marbling technique that is hundreds of years old. The original scene was made with raw Three.js r178 by the **Vue Fes Japan 2025 team**, and all credit for the design goes to them.\n\nIn the talk, I showed how I ported that scene to Vue with TresJS components, and how I moved the GLSL shader to TSL on top of WebGPU. We went through the FBM noise that flows through warped vector fields, the ink bands, and the color palettes that change over time.\n\n:blog-embed-lab{src=\"https:\u002F\u002Flab.tresjs.org\u002Fexperiments\u002Fvuefes-japan-2025\u002F\" title=\"Vue Fes Japan 2025 hero demo\"}\n\nThe live demo is in the [lab](https:\u002F\u002Flab.tresjs.org\u002Fexperiments\u002Fvuefes-japan-2025\u002F).\n\n::read-more{to=\"https:\u002F\u002Fvuefesjapan-2026.alvarosabu.dev\u002F\" title=\"Vue Fes Japan 2026 slides\" icon=\"i-lucide-presentation\"}\nSee the **slides** of the talk.\n::\n\nA big thank you to the [Vue.js Japan User Group](https:\u002F\u002Fgithub.com\u002Fvuejs-jp) and all the Vue Fes Japan staff and volunteers. The event was organized with so much care, and the community made us feel at home ありがとうございます 🙏.\n\n## WebGPU gets its own entry\n\nThe headline of this release. Until now, you had to pass a renderer factory to `TresCanvas` and `extend()` the node classes yourself to use WebGPU. In `@tresjs\u002Fcore@5.10.0`, you change one import ([#1543](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1543)):\n\n```vue\n\u003Cscript setup lang=\"ts\">\nimport { TresCanvas } from '@tresjs\u002Fcore\u002Fwebgpu'\nimport { color, mix, positionLocal, sin, time } from 'three\u002Ftsl'\n\nconst colorNode = mix(\n  color('#82dbc5'),\n  color('#fbb03b'),\n  sin(time.add(positionLocal.y.mul(4))).mul(0.5).add(0.5),\n)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CTresCanvas>\n    \u003CTresPerspectiveCamera :position=\"[3, 3, 3]\" :look-at=\"[0, 0, 0]\" \u002F>\n    \u003CTresMesh>\n      \u003CTresTorusKnotGeometry :args=\"[0.6, 0.2, 128, 32]\" \u002F>\n      \u003CTresMeshStandardNodeMaterial :color-node=\"colorNode\" :roughness=\"0.3\" \u002F>\n    \u003C\u002FTresMesh>\n    \u003CTresDirectionalLight :position=\"[3, 5, 2]\" \u002F>\n  \u003C\u002FTresCanvas>\n\u003C\u002Ftemplate>\n```\n\nWhat `@tresjs\u002Fcore\u002Fwebgpu` gives you:\n\n::prose-list\n- **A `TresCanvas` that creates a `WebGPURenderer`.** It passes `antialias`, `alpha`, `depth`, `stencil`, `powerPreference` and `logarithmicDepthBuffer` to the renderer. The `renderer` prop is still there for other options.\n- **Node materials as tags.** The entry adds every class of `three\u002Fwebgpu` to the catalogue, so `\u003CTresMeshStandardNodeMaterial>` works with no `extend()`. The tags and their props are typed.\n- **A typed `useTres()`.** `renderer` is a `WebGPURenderer`, so `renderer.backend` needs no cast.\n- **No `WebGLRenderer` in your bundle.** An app that imports only from `@tresjs\u002Fcore\u002Fwebgpu` does not ship the WebGL renderer ([#1544](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1544)).\n::\n\nThe root entry `@tresjs\u002Fcore` does not change. Its `TresCanvas` still uses `WebGLRenderer`, and a build check fails if the root entry can reach `three\u002Fwebgpu` or `three\u002Ftsl`. When the browser has no WebGPU, `WebGPURenderer` falls back to its WebGL2 backend, and node materials still work.\n\nThe same release fixes a bug that made TSL feel broken: patching a node prop such as `colorNode` now recompiles the node material ([#1540](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1540)). Before, the renderer kept the old pipeline and nothing changed on screen. `isNode` and `isNodeMaterial` are new public exports.\n\nEverything is in the [WebGPU guide](https:\u002F\u002Fdocs.tresjs.org\u002Fapi\u002Fadvanced\u002Fweb-gpu).\n\n### Cientos speaks TSL\n\n`@tresjs\u002Fcientos\u002Fwebgpu` has the same names and props as the root entry, so you only change the import path:\n\n```ts\nimport { TresCanvas } from '@tresjs\u002Fcore\u002Fwebgpu'\nimport { OrbitControls, Sparkles, Stars } from '@tresjs\u002Fcientos\u002Fwebgpu'\n```\n\nComponents that used GLSL in the root entry are now **TSL ports** in the WebGPU entry. `WebGPURenderer` compiles them to WGSL, or to GLSL on the WebGL2 fallback:\n\n::prose-list\n- `Grid`, `Outline`, `Html` and `Image`\n- `Sparkles`, `Stars` and `Precipitation`\n- `HolographicMaterial`, `MeshGlassMaterial`, `MeshWobbleMaterial`, `MeshDiscardMaterial` and `PointMaterial`\n::\n\nWebGPU draws `Points` at 1 pixel only, so `Sparkles`, `Stars` and `Precipitation` render one instanced `Sprite` with `PointsNodeMaterial` in their WebGPU versions.\n\nSome components are not ported yet: the ones that write GLSL with render targets (`ContactShadows`, `MeshTransmissionMaterial`, `MeshPortalMaterial`...), the line components, and the ones built on three-stdlib shaders (`Sky`, `Reflector`, `Stage`...). If you import one of them from `@tresjs\u002Fcientos\u002Fwebgpu`, the build and the type check fail and name the component. If you use one from the root entry on a WebGPU canvas, cientos logs one warning that names it. TSL versions will come one by one. The full list is in the [Cientos WebGPU guide](https:\u002F\u002Fcientos.tresjs.org\u002Fgetting-started\u002Fwebgpu).\n\n::prose-note\n`@tresjs\u002Fcientos\u002Fwebgpu` needs `three` r171 or newer and `@tresjs\u002Fcore` 5.10 or newer. The root entry still supports `three` r133 and newer.\n::\n\n### Nuxt: one option\n\n`@tresjs\u002Fnuxt@5.8.0` has a new `renderer` option ([#1527](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1527)):\n\n```ts [nuxt.config.ts]\nexport default defineNuxtConfig({\n  modules: ['@tresjs\u002Fnuxt'],\n  tres: {\n    renderer: 'webgpu',\n  },\n})\n```\n\nWith it, `\u003CTresCanvas>`, `useTres()` and the cientos components are auto-imported from the `\u002Fwebgpu` entries. A cientos component with no WebGPU version yet still resolves, but it throws an error that names it when it mounts, instead of Vue's generic \"Failed to resolve component\". `@tresjs\u002Fpost-processing` is not auto-imported in this mode, because its effects work only with `WebGLRenderer`, and the module tells you so.\n\n## N8AO ambient occlusion\n\n`@tresjs\u002Fpost-processing@3.10.0` adds [N8AO](https:\u002F\u002Fgithub.com\u002FN8python\u002Fn8ao), the screen-space ambient occlusion pass by [N8python](https:\u002F\u002Fgithub.com\u002FN8python) ([#1518](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1518)). AO darkens corners, crevices and the contact areas below objects, so flat scenes get depth. It comes in both families:\n\n::prose-list\n- [`\u003CN8AOPmndrs \u002F>`](https:\u002F\u002Fpost-processing.tresjs.org\u002Fapi\u002Fpmndrs\u002Fn8ao) for `\u003CEffectComposerPmndrs>`\n- [`\u003CN8AO \u002F>`](https:\u002F\u002Fpost-processing.tresjs.org\u002Fapi\u002Fthree\u002Fn8ao) for the three family `\u003CEffectComposer>`\n::\n\n```vue\n\u003CSuspense>\n  \u003CEffectComposerPmndrs :multisampling=\"0\">\n    \u003CN8AOPmndrs :ao-radius=\"2\" :intensity=\"3\" \u002F>\n    \u003CSMAAPmndrs \u002F>\n  \u003C\u002FEffectComposerPmndrs>\n\u003C\u002FSuspense>\n```\n\nEvery prop is reactive, and `renderMode` gives you debug views, including a split view with and without AO. Hardware multisampling does not work with AO, so add `\u003CSMAAPmndrs \u002F>` or `\u003CFXAAPmndrs \u002F>` after the pass. The [Rapier Object Clump](https:\u002F\u002Flab.tresjs.org\u002Fexperiments\u002Frapier-object-clump\u002F) experiment in the lab now uses the package component.\n\n## Fixes worth knowing about\n\n### Core\n\n::prose-list\n- **Awaiting `useLoader` returns everything** ([#1548](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1548)). `await useGLTF(...)`, or any loader built on `useLoader`, resolved with a partial object and dropped `nodes`, `materials`, `load` and `progress`. Now `const { state, nodes } = await useGLTF('\u002Fmodel.glb')` works as you would expect.\n- **On-demand scenes stay idle after a prop update** ([#1499](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1499)). A component that created a fresh position array could make an on-demand scene render again and again.\n- **No devtools in production** ([#1498](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1498)). `TresCanvas` registered the devtools in production builds too, and their performance monitor walked the scene even with on-demand rendering.\n- **`PCFShadowMap` on WebGPU** ([#1508](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1508)). three r186 removed `PCFSoftShadowMap` from `WebGPURenderer` and logged a warning on every WebGPU scene with shadows. From r186, `PCFShadowMap` is the default on WebGPU too, and it is already soft there, so you lose no quality.\n::\n\nThe first two fixes come from [Felix Schwämmle](https:\u002F\u002Fgithub.com\u002Ffelixschwamm), in their first contributions to TresJS, with a reproduction test for each. Welcome, Felix 🎉!\n\n### Cientos\n\n`PointMaterial` converted its color to sRGB twice ([#1539](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1539)). `color=\"#ffa500\"` rendered yellow, now it renders orange.\n\n::prose-note\nThis changes how existing scenes look: dots are darker and more saturated, the same as with `PointsMaterial`. If you tuned your colors for the old look, check them again.\n::\n\n### Rapier\n\n`@tresjs\u002Frapier@1.1.3` brings two fixes:\n\n::prose-list\n- **Custom colliders sit on their body** ([#1515](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1515)). A `\u003CCapsuleCollider>` inside a `\u003CRigidBody>` with a `position` got the body offset twice, and a collider `position` was read as a world position. Collider `position` and `rotation` are now offsets from the body, as the types say. If you used world values to work around this, your colliders will move.\n- **`\u003CPhysics debug>` lines are visible** ([#1514](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1514)). They were almost black, and colliders inside a mesh did not show. They now draw on top in Rapier's colors.\n::\n\n### Tres Leches\n\nBetter dark mode contrast for folders and inputs ([#1517](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1517)), slot content that stays visible when the panel height changes ([#1523](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1523)), and a collapsed panel that keeps its size when the window resizes ([#1546](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1546)).\n\n## Everything in sync\n\nThe family moved together on October 6, October 22 and again on October 28. These are the latest:\n\n::prose-list\n- **`@tresjs\u002Fcore@5.10.1`**\n- **`@tresjs\u002Fcientos@5.10.1`**\n- **`@tresjs\u002Fnuxt@5.8.1`**\n- **`@tresjs\u002Fpost-processing@3.11.1`**\n- **`@tresjs\u002Frapier@1.2.1`**\n- **`@tresjs\u002Fleches@1.3.3`**\n::\n\n```bash\npnpm up @tresjs\u002Fcore @tresjs\u002Fcientos @tresjs\u002Fnuxt @tresjs\u002Fpost-processing @tresjs\u002Frapier @tresjs\u002Fleches\n```\n\n### 👉 Full Release Notes\n\n::read-more{to=\"https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Freleases\" title=\"Full Release Notes\" icon=\"i-lucide-scroll-text\"}\n::\n\n## From the community\n\n\u003C!-- TODO(alvaro): add 3-5 verified community projects from October 2026 (Discord #showcase, X, Bluesky). Verify authorship and originality before featuring, see June post for the :magic-link format. -->\n\n## Thanks\n\nThank you to [Shingo Hiranuma](https:\u002F\u002Fgithub.com\u002Fhiranuma) for bringing TresJS to XR devices on the Vue Fes stage, to the Vue Fes Japan 2025 team for the design that inspired my talk, to the [Vue.js Japan User Group](https:\u002F\u002Fgithub.com\u002Fvuejs-jp) for an amazing conference, to [Felix Schwämmle](https:\u002F\u002Fgithub.com\u002Ffelixschwamm) for their first two core fixes, and to [N8python](https:\u002F\u002Fgithub.com\u002FN8python) for N8AO. And thanks to everyone who opened an issue this month 🙌.\n\n## Coming next: TSL composables\n\n`\u002Fwebgpu` is the foundation. The next step is in review: a set of **experimental TSL composables** for `@tresjs\u002Fcore\u002Fwebgpu` ([#1545](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fpull\u002F1545)).\n\n::prose-list\n- **`useUniforms` and `useUniform`** bind plain values, refs, getters or Tres Leches controls to TSL uniforms. A change writes `uniform.value` with no shader recompile, and requests a frame in on-demand mode.\n- **`useNodes` and `useLocalNodes`** share node graphs between components in the same canvas.\n- **`useRenderPipeline`** renders the canvas through three's `RenderPipeline`, for post-processing on WebGPU.\n::\n\nThe API can still change, so watch the PR. If you have a TSL use case you want us to cover, [tell us](https:\u002F\u002Fgithub.com\u002FTresjs\u002Ftres\u002Fissues).\n\nGot something cool built with Tres? Share it in our [Discord](https:\u002F\u002Fdiscord.gg\u002FUCr96AQmWn). It might headline the next *Loop Chronicles*.\n\nHappy crafting ✌️.\n",{"text":1622,"minutes":1623,"time":1624,"words":1625},"8 min read",7.465,447900,1493,{"title":5,"description":1615},"blog\u002Fwhats-new-october-2026","\u002Fblog\u002Fwhats-new-october-2026\u002Fthe-loop-chronicles-october-2026.png",null,"turJpy-nvAovCUgSs_UpKEdDhYQX6S4W5AY9EOlP-20",{"id":1632,"title":1633,"avatar":1634,"body":1635,"description":214,"email":1639,"extension":1617,"github":6,"meta":1640,"name":1644,"navigation":314,"path":1645,"seo":1646,"slug":6,"stem":1647,"twitter":6,"website":1648,"__hash__":1649},"authors\u002Fauthors\u002Falvarosabu.md","Alvarosabu","\u002Favatars\u002Falvarosabu.png",{"type":8,"value":1636,"toc":1637},[],{"title":214,"searchDepth":249,"depth":249,"links":1638},[],"hola@alvarosaburido.dev",{"readingTime":1641},{"text":1642,"minutes":1643,"time":1643,"words":1643},"0 min read",0,"Alvaro Saburido","\u002Fauthors\u002Falvarosabu",{"description":214},"authors\u002Falvarosabu","https:\u002F\u002Falvarosaburido.dev","CmwieKa4qc2RGTVr4mry8wF-8Mb9vtJoJrhpP_Qz5kk",{"id":4,"title":5,"author":6,"body":7,"category":1613,"date":1614,"description":1615,"draft":1616,"extension":1617,"meta":1618,"navigation":314,"path":1619,"rawbody":1620,"readingTime":1621,"seo":1626,"stem":1627,"thumbnail":1628,"url":1629,"__hash__":1630,"authors":1651},[1652],{"name":1644,"description":1653,"avatar":1654,"to":1648,"target":1655},"@alvarosabu",{"src":1634},"_blank",1793368619766]