mrdoob

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars13
mentions53
02468Oct 4Oct 18Nov 2
UTC days · repositories mrdoob owns7 repositories

Package downloads

Cumulative recorded downloads · since 2025-10-28

npm335
084168252336Oct 4Oct 18Nov 2
Oct 30npm: 1/2 packages observed

Across 2 known packages in repositories mrdoob owns. Cumulative totals include recorded downloads before the selected range. Missing observations leave gaps; totals may be incomplete.

Top repositories

mrdoob’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside mrdoob’s account where mrdoob opened or reviewed pull requests in the past 365 days.

Who noticed mrdoob

Everyone who starred or forked mrdoob’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

58posts
Nov 35 posts
  1. Reddit · · r/AnnArbor · u/mrubens · mrdoob/slop-newyork

    I made a drivable 3D Ann Arbor from the city’s open data I've been building a little open-world Ann Arbor you can walk, drive, bike, fly, or paddle around in: mrubens.github.io Not quite GTA 6, but GTAA will have to do for a couple more weeks. It's built on a ton of amazing open data and open source code: City of Ann Arbor - Building footprints: ckan.a2gov.org - Street trees: a2gov.org - Urban tree canopy: a2maps.a2gov.org - 2023 impervious surfaces (driveways and walks): a2maps.a2gov.org - Streetlights: a2gov.org - Road centerlines (speed limits): a2maps.a2gov.org - Fire hydrants: ckan.a2gov.org - Park amenities: ckan.a2gov.org - Address points: ckan.a2gov.org - Land use: ckan.a2gov.org - Historic districts: ckan.a2gov.org Live - National Weather Service (current conditions at Ann Arbor Municipal Airport): weather.gov - USGS Huron River at Ann Arbor gauge: waterdata.usgs.gov Transit - TheRide timetable feed: theride.org - Amtrak timetable feed (Wolverine): content.amtrak.com Maps and terrain - OpenStreetMap: openstreetmap.org - Terrain Tiles (Mapzen and USGS elevation): registry.opendata.aws Built on - Slop New York by Mr.doob, the game this started from (MIT license): mrdoob/slop-newyork - Mr.doob also made three.js, which the game is drawn with: threejs.org Source code if you want to report bugs or build on it: mrubens/go-to-ann-arbor

    365 points · 40 comments
  2. Three.js r187 compileAsync: 40 Desktop Starts, Measured > Originally published by Alicia on 1 November 2026 at Digital Garden. Original measurements and limitations are retained. On my RTX 5070 Ti, Three.js r187 reduced WebGPU precompile time from a median 1,399.8 ms to 227.8 ms in a controlled 48-tree grove. That is the useful result. It does not mean my production garden became six times faster, and it does not mean every startup hitch was shader compilation. I ran 40 independent Chrome starts: r186.1 and r187.0, each with and without compileAsync(), on both WebGPU and the WebGL2 backend of WebGPURenderer. Each setting has five trials. The fixture uses one of my own Houdini trees and deliberately different materials, with a fixed camera and resolution. The other result matters just as much: both versions' precompile groups had no observed main-thread task of 50 ms or longer during the measured operation. This experiment supports shorter waiting on r187. It does not support a claim that r187 alone made the loading screen responsive. Measured on 1 November 2026. Codex assisted the experiment, analysis and writing. This is an independent desktop fixture, not a production-site upgrade. !The actual controlled grove: 48 copies of an owned Houdini tree, rendered on WebGPU at 1280 by 720 Actual browser capture. The deliberately varied shaders make pipeline preparation measurable; they are not a claim about how many materials a production garden needs. Fixture and figures by Alicia, CC BY 4.0. What changed, and what I checked Three.js PR #34816 changes the shared renderer's asynchronous compilation scheduler. The pinned r187 source permits up to 16 pipelines in flight and cooperatively yields after roughly 8 ms of work. That is a scheduling budget, not a guarantee that every task or displayed frame lasts at most 8 ms. The PR author, sunag, reported approximately 12.8 seconds to 1.5 seconds on an i9-13900K. Those are the author's measurements, not mine. I checked the r187 release and the installed npm source before testing. My instrumented WebGPU calls reached 9–10 concurrent asynchronous pipeline creations on r187, against one on r186. They did not reach the source's cap of 16. The completed grove eventually created 50 render pipelines: 49 for the grove and ground, plus a separate output pipeline at the first render. This is a whole-version comparison. r187 contains other changes, so these timings cannot isolate the causal contribution of one PR. The live Digital Garden remains on its accepted production dependencies; I did not upgrade its rendering engine to manufacture a before-and-after claim. The fixture and the meaning of a fresh start The study runs on Windows 11, a Ryzen 9 9950X, 64 GB RAM and an NVIDIA GeForce RTX 5070 Ti with driver 617.42. Chrome reports version 156; the WebGPU adapter reports NVIDIA/Blackwell. Each trial saves its own browser and backend receipt. The scene contains 48 copies of an owned 400-triangle Houdini tree, a ground plane, two lights and 49 material instances. Different literal TSL expressions intentionally produce distinct programs. Every formal first render records 50 draw calls and 19,203 submitted triangles, including the output pass. The fixture has no production wind scheduler, LOD transitions, shadows, environment-map preprocessing or postprocessing stack. The viewport and renderer output are 1280 × 720 with renderer pixel ratio 1. The camera and lighting stay fixed. I used the same fixture bytes and application code for both versions, changing the import map to the pinned npm package. Each trial launches a dedicated, fresh Chrome user-data directory with the GPU shader disk cache disabled. Treatment order rotates between rounds. That gives independent browser profiles; it does not prove cold OS, driver or hardware caches. I therefore describe these as fresh-profile starts rather than claiming completely cold GPU compilations. Eight earlier pilots remain local and are excluded. During those pilots, automatic renderer-info reset could clear WebGPU counters while I waited for the GPU. The formal harness disables automatic reset and checks the actual draws and triangles. The raw receipts also retain an incidental missing-favicon 404; no application or shader errors were observed in the formal dataset. Three clocks that should not be combined I separate these measurements: 1. Precompile: wall time around the awaited renderer.compileAsync(scene, camera). 2. First render to completion: the first render() call through a completion fence. WebGPU uses device.queue.onSubmittedWorkDone(); WebGL2 uses gl.finish(). 3. Operation to completion: from immediately before optional precompile through that first completion fence. This is the relevant wait when deciding whether precompile adds or removes startup delay. The operation clock begins after renderer initialization, the local GLB load/parse and fixture construction. Raw receipts also preserve navigation-to-completion and setup marks, but the headline is not a network-loading benchmark. A GPU queue fence is not a monitor presentation timestamp. Nor is its entire duration a main-thread stall. In the WebGPU no-precompile trials, substantial time elapsed after the synchronous render() call returned while the GPU/driver completed the submitted work. Reporting all that time as a frozen JavaScript task would be wrong. I also collected PerformanceObserver long-task entries and a DOM animation's RAF timestamps during preparation. Long-task entries only cover tasks at least 50 ms long. A zero below means none above that threshold, not zero JavaScript work. I did not manually measure orbit-input latency or inspect a DevTools Performance trace, so neither appears as a completed acceptance claim. WebGPU: shorter preparation, similar prepared first render All numbers below are medians of five trials. Durations are milliseconds. The downloadable JSON and CSV retain every trial and range. | Setting | Precompile | First render to completion | Operation to completion | Longest observed operation task | | --- | --- | --- | --- | --- | | r186.1, no precompile | — | 1263.6 | 1263.6 | 143 | | r186.1, precompile | 1399.8 | 23.8 | 1424.6 | 0, none ≥50 ms | | r187.0, no precompile | — | 905.9 | 906.0 | 107 | | r187.0, precompile | 227.8 | 23.5 | 251.3 | 0, none ≥50 ms | !Five-trial median and full range for preparation through the first completed render, on WebGPU and the forced WebGL2 fallback The r187 WebGPU precompile range was 226.0–244.6 ms; r186 was 1394.9–1456.4 ms. Operation-to-completion moved from 1424.6 ms to 251.3 ms between the two precompiled configurations, about 5.7 times shorter in this fixture. The already-prepared first render stayed around 24 ms in both versions. The improvement was predominantly preparation, not a dramatic reduction in the cost of rendering the prepared grove. There is also an inconvenient r186 result worth keeping: precompile made total waiting slightly longer than the no-precompile setting, even though it removed the observed ≥50 ms operation tasks. Moving work behind a loading screen and shortening overall startup are different goals. !Precompile duration and full five-run ranges; WebGPU fell from about 1400 ms to 228 ms in this fixture The WebGL2 fallback is a separate result This group uses new WebGPURenderer({ forceWebGL: true }). It is not the older WebGLRenderer. The common renderer scheduler is still involved, so I tested it instead of assuming that the WebGPU result applied unchanged. | Setting | Precompile | First render to completion | Operation to completion | Longest observed operation task | | --- | --- | --- | --- | --- | | r186.1, no precompile | — | 1178.7 | 1178.7 | 1179 | | r186.1, precompile | 1650.2 | 14.5 | 1664.8 | 0, none ≥50 ms | | r187.0, no precompile | — | 991.6 | 991.7 | 992 | | r187.0, precompile | 228.6 | 14.8 | 243.2 | 0, none ≥50 ms | Here the synchronous no-precompile path produced a much longer main-thread task than WebGPU. Precompiling again changed where the work happened; the r187 precompile group also waited much less overall. I did not instrument WebGL driver compilation concurrency and did not test the legacy renderer's KHR_parallel_shader_compile behavior. A zero WebGPU-pipeline count in these WebGL2 receipts means that WebGPU API was not used, not that shaders needed no work. A smooth post-ready loop does not describe startup Every trial records the next 120 RAF intervals after the first completion fence: 4,800 intervals across the 40 formal starts. All eight settings had zero intervals over 50 ms in that window. That result does not cancel the startup waits in the tables. Starting a frame-time chart after expensive work can make every configuration look smooth. I retain the startup heartbeat and long-task records separately so that the measurement window is explicit. !Neither version's precompile group produced an observed operation task at least 50 ms long; zero is a thresholded observation Hidden trees still needed pipelines when revealed I ran four additional diagnostic starts, outside the 40-trial timing denominator: each version with a visibility/frustum control and a detached-group/target-scene control. For the visibility control, one tree had visible = false and another was positioned outside the camera frustum during precompile. Both versions prepared 47 pipelines. The first render added the output pipeline. Revealing the two trees then created two additional pipelines. So I would not tell an artist that calling compileAsync() once prepares everything that might ever appear. In this fixture it follows visibility and camera coverage. Streaming, alternate materials and later scene changes still need explicit planning. The target-scene control moved the tree meshes into a detached group, compiled that group with the scene's lighting context and then attached it: // Verified on both pinned versions in this controlled fixture. await renderer.compileAsync(nextGroup, camera, scene); scene.add(nextGroup); Both versions prepared 48 pipelines for the detached trees; the ground and output pipelines were added when rendering the full scene. The three-argument signature is supported by the pinned renderer source, rather than being copied from a different renderer's API. This does not verify arbitrary moving lights, shadows, render targets or a postprocessing pass graph. Match the compilation context to the eventual render and measure new pipeline creation when the object appears. Where I would use this in a garden loader First finish the scene's intended materials, lights and camera, then await precompile while an honest loading indicator is visible. Keep first-render completion and the total preparation wait in the same log. For incoming groups, supply the destination scene so that compiling without its lights does not become a misleading warmup. Avoid automatically making every invisible object visible in the production scene just to warm it. That can change what the user sees or submit an unexpectedly large workload. A controlled offscreen warmup is its own integration task, with the eventual render format, material state and coverage verified. This fixture deliberately avoids large image textures. It cannot show that compileAsync() removes texture decode or upload cost, GLB download, Draco/Meshopt decode, or instance-buffer preparation. Those belong to the separate GLB loading and first-frame study. Mesh-detail tradeoffs are covered in the vegetation LOD measurements, and backend comparisons in the instanced plant study. Those older articles and their dates are unchanged. Before a production upgrade, read the r186-to-r187 migration guide. This test does not accept every migration change, PMREM output difference or application-specific shader. Phones, Safari/Firefox, a second GPU, shadows, texture-heavy scenes and the production garden remain untested. Data and reproduction Study ZIP · Package size and SHA-256 · Results JSON and ranges · Trial CSV · Source hashes · Environment and limits. The package includes the pinned dependency manifest, owned GLB, measurement harness, all 40 formal receipts, four final diagnostic receipts, selected browser captures, figures and four saved diagnostic recordings. It excludes browser profiles, account information, production assets and the eight local pilots. An initial control runner used the old entrypoint before a local server restart, so its target-scene claims were rejected and all four controls rerun with an execution marker. One earlier video export also failed. Both issues remain documented rather than being counted as successful final controls. Code, fixture and figures are by Alicia, CC BY 4.0; Three.js retains its MIT license. The result is a measured reason to test r187's preparation path on this hardware, with explicit clocks and coverage limits. It is not a promise that a version bump removes every garden loading hitch. Explore the Three.js rendering field guide. The ZIP preserves the measured manuscript snapshot; this canonical page also carries the current navigation links. Original article, data and updates.

  3. I was wondering when Three.js was going to get something like Nanite. And then I saw the PR for a meshlet rendering pipeline was merged <24 hours ago! three.js#35191 Here's a demo scene rendering 1B triangles at 150FPS. raw.githack.com This is huge! 🤯 t.co

    221 likes · 16 reposts · 7,501 views
  4. プロシージャル3Dカエル はじめに プログラマーの皆さん、3Dモデリングって正直ちょっと面倒じゃないですか?😅 私は昔から、普通の3Dソフトではなく、World Machineのようにノードとプロシージャル技術で何でも作れる、自分専用のソフトを作るのが夢でした。そこで今日、その第一歩を作ってみました。 その名も「Pondwork」です🐸 最初のバージョンはMVPなので、アニメキャラも街も作れません。作れるのは、ちょっとおかしな、デフォルメされたカエルだけです。 Frogノード:seed(乱数の種)から、世界に1匹だけのカエルを生成する Combineノード:2匹のカエルをつないで、どの特徴を引き継ぐかを選ぶ 狙いは、ランダムな出力を「完成品」ではなく「出発点」にして、そこから自分の創造性を足していくことです。 アプリはmacOSのネイティブアプリとして作りました。ウィンドウ、グラフ、コントロール、プロジェクトファイルはSwiftUIが担当し、3Dプレビューはアプリの中に組み込んだローカルのThree.jsで描画しています。別のブラウザウィンドウが開くことはありません。今のビルドはApple SiliconとmacOS 14以降が対象です。 この記事では、仕組みを3つに分けて紹介します。 カエルの設計図(FrogGenome)をseedから作る部分 その設計図を3Dにするレンダラー 2匹の特徴を混ぜるCombineノード コードは実装からの抜粋で、あくまでMVP時点のものです。最後に「次に直したいところ」もまとめました。間違いや、もっと良い方法があれば、ぜひ教えてください! 全体の流れ まず、仕組みの全体像です。グラフの中では、カエル1匹が小さなゲノム(カエルの設計図になるデータ)として保存されています。Combineノードは、つながっている入力を読み、指定された特徴のグループだけを混ぜて、新しいゲノムをビューポートに送ります。どのノードを選んでも、左側のプレビューが更新されます。 アプリを開くと、frog1とfrog2がcombine1につながった状態から始まります。グラフは「作業のレシピ」です。このカエルがどこから来て、どんな選択をした結果なのかが残ります。 FrogGenome:seedがデザインになる Swift側のモデルでは、デザインの決定と3Dの描画を分けています。seedを1つ決めると、体型・頭の形・目・口・足・配色・模様が選ばれ、さらに体の比率などの連続的な値もいくつか決まります。 static func make(seed: UInt32) -> FrogGenome { var random = SeedRandom(seed: UInt64(seed)) return FrogGenome( seed: seed, bodyShape: random.int(upperBound: 9), headShape: random.int(upperBound: 5), eyeStyle: random.int(upperBound: 5), mouthStyle: random.int(upperBound: 5), legStyle: random.int(upperBound: 5), palette: random.int(upperBound: 4), markings: random.int(upperBound: 6), bodyWidth: random.range(0.84, 1.17), bodyHeight: random.range(0.84, 1.18), eyeScale: random.range(0.82, 1.23), legLength: random.range(0.76, 1.30), patternScale: random.range(0.72, 1.34) ) } 同じseedなら必ず同じカエルになるので、結果を再現できます。 この7種類の選択肢だけで、組み合わせは135,000通りあります。一方、スライダーで触れる項目は、体のつくり・頭の形・足の長さ・毛色の調整くらいに絞っています。全部の組み合わせを手動で触れるようにしてしまうと、Combineノードの出番がなくなってしまうからです。 カエルを追加するときは、256個の候補ゲノムを作ります。そのうち、今のグラフにあまり出ていない体型や配色を優先して、既存のカエルたちとの「デザインの距離」がいちばん離れている候補を選びます。つまり、一番近いカエルとの違いが最大になる候補を採用する、というシンプルな多様性の工夫です。 ただ、これは「追加したカエルが必ず魅力的になる」仕組みではありません。連続で追加したときに、同じ体の色違いばかりになりにくくなる、という程度のものです。 レンダラー:1つのプロファイルから、丸い体をたくさん作る レンダラーは、球から始めます。球の頂点を、角度ごとの体のプロファイル(輪郭の形を決める関数)に沿って動かすことで、体の形を作ります。定番のカエルの輪郭には、私の弟が描いてくれたかわいいカエルのデザインをもとに、手で形を整えた曲線を使いました。他にも、丸・四角・ハート・楕円・三角・しずく・カプセル・ワイドといった体型を用意しています。目、口、手足、指、おなか、模様は、同じゲノムから位置を決めて配置します。 function bodyGeometry(shape, headShape, rx, ry, rz) { const geometry = new THREE.SphereGeometry(1, 72, 56); const position = geometry.attributes.position; const v = new THREE.Vector3(); for (let i = 0; i < position.count; i++) { v.fromBufferAttribute(position, i); const radius = Math.hypot(v.x, v.y); const point = bodyProfilePoint( cropperPoint(Math.atan2(v.y, v.x), shape), radius, shape, headShape ); position.setXYZ(i, point.x * rx, point.y * ry, v.z * rz); } geometry.computeVertexNormals(); return geometry; } Three.jsのジオメトリやメッシュの扱いは、GitHubのThree.js geometriesのサンプルを参考にしました。カエル自体はPondworkのコードで組み立てていて、できあいのカエルのモデルを読み込んでいるわけではありません。丸みのある部分にはThree.jsの球やカプセルを使い、色はトゥーンマテリアルでフラットに、ライトと影は読みやすさを保つためにシンプルにしています。 ここで1つ、正直に書いておきたいことがあります。デザインはプロシージャルに生成していますが、描画の段階では、結局ポリゴンのメッシュに変換しています。 スケールするインプリシットサーフェス(数式で表す曲面)や、スカルプトのような仕組みは、まだ作れていません。Pondworkをこの小さな「つるっとしたキャラ」より先に広げるなら、ここが課題になると思っています。 模様がカエルの外に出るバグ いろいろなseedを試していたら、小さな3Dの模様が、体の横に浮いてしまうバグを見つけました🐛 原因は、模様の位置を「ざっくりした球」として計算していたことです。体のほうは独自の輪郭に変形しているので、位置が合わなくなっていました。 直し方は、体と模様で同じプロファイルの変換を使うことです。 const point = bodyProfilePoint( cropperPoint(angle, genes.bodyShape), radius, genes.bodyShape, genes.headShape ); const x = point.x * rx; const y = centerY + point.y * ry; const z = rz * Math.sqrt(1 - radius * radius) + 0.006; const r = (genes.markings === 2 ? 0.018 : 0.035) - genes.patternScale * (0.66 + rnd() * 0.70); const spotMat = material(placed % 3 === 0 ? palette.belly : palette.spot); blob(group, spotMat, [x, y, z], [r * (0.82 + rnd() * 0.5), r, 0.012]); これで、模様が体と同じ変形した表面の上に乗るようになりました。別々の形から位置を計算していたのが、そもそもの原因でした。 Combine:欲しいところだけ引き継ぐ Combineノードのインスペクタには、ドロップダウンがあります。選べるのは「All traits」「Head」「Body」「Legs」「Coat」です。スライダーは、親Aと親Bのどちらの影響を強くするかを決めます。 たとえば、体が横に広いカエルと、好みの顔をしたカエルをつなぎます。そこで「Head」を選んでスライダーを顔の好みなカエル側へ動かせば、体は片方のまま、顔だけをもう片方に寄せられます。 仕組みはこうです。体の比率のような連続した値は、そのまま補間(なめらかに混ぜる)します。一方、体型や目の種類のような「選択肢」の値は、スライダーが半分を超えたところで親Bに切り替わります。どの項目を切り替えてよいかは、選んだグループで決まります。 let t = amount.clamped(to: 0...1) let takeB = t >= 0.5 var result = self if group == .all || group == .body { result.bodyWidth = mix(bodyWidth, other.bodyWidth, t) result.bodyHeight = mix(bodyHeight, other.bodyHeight, t) if takeB { result.bodyShape = other.bodyShape } } おかげで、グラフのデータはとてもコンパクトです。Combineノードが持つのは、2本の入力接続、特徴のグループ、混ぜる量だけです。出力のゲノムは、その入力から毎回計算されるので、ノードを選べばビューポートに結果が表示されます。 次に直したいところ 1. グラフを使いやすくする グラフはこのアプリの核ですが、今いちばん弱いところでもあります。接続がやりづらいですし、ノードが増えると配置もごちゃごちゃします。入力の受け口をわかりやすくして、自動レイアウトやズームして全体表示する機能、各ノードにプレビューを表示する機能を足せば、長いレシピも追いやすくなるはずです。 2. カエルの品質を上げて、ジオメトリの不具合をなくす 最初のプロトタイプより、カエルの種類は増えました。でも、モデルの品質はまだ荒いです。組み合わせによっては、体・顔・手足が不自然に重なることもあります。今の体のプロファイルと、別々に作った丸いパーツの組み合わせは、「引き継ぎ」の仕組みを試すには十分です。ただ、完成と呼べるようにするには、比率の見直し、つなぎ目のきれいな処理、シルエットのチェックが必要です。 3. モデリングノードを増やして、エクスポートを作る 目、口、ポーズ、足、模様、アクセサリー、体の比率を、それぞれ別のステップで操作できるノードを増やしたいです。形が安定してきたら、次に実用的なのは、生成したカエルをUnityで使える形式で書き出すことです。glTFでのエクスポートか、Unityにそのまま入れられるパッケージを考えています。今のSaveは、完成した3Dアセットではなく、グラフのレシピを保存しているだけです。 4. カエル以外にも広げる 長い目で見ると、再利用できるプロシージャルなキャラクターシステムにしたいです。グラフと特徴の引き継ぎの流れはそのままに、別のクリーチャーやキャラクターの種類を、それぞれのジェネレーターで足していきます。ただ、アニメキャラや動物、街のような環境に広げる前に、まず1つの種類をちゃんと魅力的で、編集しやすいものにしたいです。 おわりに Pondworkは、ずっとやりたかったことの小さな実験です。細部を1つずつ彫刻する代わりに、プロシージャルな部品を組み合わせてキャラクターを作る、というアイデアです。今の部品は、あえてシンプルにしています。 seed付きのFrogノードが、毎回同じになる、個性のある出発点を作る Combineノードが、2つのデザインの間で選んだ特徴を受け渡す ビューポートが、グラフの結果をそのまま表示する このアプリで確かめられたのは、このワークフローがMacのネイティブアプリとして動く、ということです。逆に、モデルが完成していることや、グラフが十分に使いやすいこと、このやり方があらゆる3Dアセットに通用することは、まだ確かめられていません。次は、ノード操作の体験を磨き、カエルのジオメトリを安定させ、本物のモデルエクスポートを足してから、Pondworkに何を作らせるかを考えます。 ここはまだ、小さな池です🐸 でも、大きなアイデアを試すには、ちゃんと動く池になりました。

  5. Today's #ThreeJS PR: Spatiotemporal blue noise based upon EA's FAST method. three.js#35244

    7 likes
  6. High Roughness, Sharp Highlights: Auditing a glTF Material in Three.js An imported car-body model still showed sharp highlights on its hood and rear fender after switching to a preset labeled Matte. The overall reflection became weaker, but some bright patches remained. That observation prompted a material audit: what did the preset actually change, and what properties had arrived with the imported asset? Affiliation: This case comes from WrapPrism, a project I work on. The browser capture session and file checks described below took place on October 27, 2026. Establishing a comparable capture sequence The comparison used one BMW M4 G82 ADRO-kit body study in the same Chrome tab and the same initial front three-quarter view. Between captures, there was no rotation, zoom, camera reset, vehicle switch, navigation, or window resizing. | Recorded item | Capture conditions | | --- | --- | | Renderer marker | Three.js r186 | | Viewport | 1470 × 775 CSS pixels; device pixel ratio 2 | | 3D canvas | 881 × 565 CSS pixels; drawing buffer 1762 × 1130 | | Reported camera distance | 7.8000 in every capture | | Environment | Same RoomEnvironment / PMREM setup | | Lighting configuration | Hemisphere light intensity 1.2; directional light intensity 2.5 at (4, 8, 3) | | Exposure | 0.9 | | Base-color inputs | #AB645B and #343B3A | | Finish presets | Gloss, Satin, Matte | The lighting settings were checked against the inspected application source snapshot and the script loaded by the browser. GPU uniforms were not inspected directly. Camera azimuth, elevation, and the complete Chrome version were not recorded either, so this is an application-level comparison with repeatability evidence, rather than a claim of pixel-identical reproduction across devices. Two colors across three finishes produced six conditions. Two return-to-baseline captures brought the total to eight unmodified screenshots. Color changes were visible on the hood, doors, and fenders, while the glass, wheels, and dark carbon components retained their appearance. Both colors showed changes between Gloss and Matte, although some sharp highlights remained under Matte. The dark-gray sequence was Satin → Gloss → Matte → Satin. A second sequence switched away from the copper-colored Satin condition and then restored it. In both cases, the returning screenshot had the same whole-file SHA-256 hash as its corresponding baseline. That supports the absence of visible framing or scene drift within these sequences. The original screenshots and model binary are not distributed with this article because their source-license provenance still needs clarification. The tables below summarize retained internal records; the exact asset-specific images cannot be independently reproduced from this article alone. One preset changed more than one parameter The finish mapping was verified in the script loaded by the browser: | Preset | Base roughness | Metalness | | --- | ---: | ---: | | Gloss | 0.16 | 0.24 | | Satin | 0.42 | 0.24 | | Matte | 0.86 | 0.02 | Of these two parameters, only roughness changed between Gloss and Satin. Switching to Matte also changed metalness. Consequently, the full three-preset comparison does not isolate roughness. Three.js defines roughness and metalness as separate material properties; metalness is not a general-purpose gloss control. MeshStandardMaterial documentation The original rationale for these values was not established, and no physical film samples were used for calibration. They are application presets, not universal physical definitions of gloss, satin, or matte. To check that the changes extended beyond the selected UI control, the screenshots were compared using mean absolute differences in decoded RGB values: | Comparison | Mean absolute difference, 0–255 | | --- | ---: | | Copper Satin / dark-gray Satin | 6.996 | | Dark-gray Satin / dark-gray Gloss | 1.047 | | Dark-gray Gloss / dark-gray Matte | 1.765 | | Copper Satin / copper Gloss | 0.700 | | Copper Gloss / copper Matte | 1.542 | | Each of the two baseline-return comparisons | 0 | The comparison region was the same screenshot rectangle: x = 100…959, y = 130…684. It includes background pixels, and the originals are JPEGs. These values establish image changes and returns to baseline within this capture session. They are not ΔE measurements, physical gloss readings, or material-accuracy scores. The imported material had another reflective layer The paint material in the actual GLB contained these extension fields: { "extensions": { "KHR_materials_clearcoat": { "clearcoatFactor": 1, "clearcoatRoughnessFactor": 0.04 } } } The Khronos extension defines a clearcoat layer over the base material, with its own intensity and roughness. Setting clearcoatFactor to zero disables that layer. KHR_materials_clearcoat specification Three.js exposes the corresponding clearcoat and clearcoatRoughness properties. A rough base can therefore have a much smoother coating above it. MeshPhysicalMaterial documentation The r186 loader provides a concrete explanation of how those properties enter the scene. When the clearcoat extension is present, GLTFLoader selects MeshPhysicalMaterial and maps the glTF factors to its clearcoat properties. Three.js r186 GLTFLoader source The inspected application path then clones the imported material and replaces its base roughness, metalness, and color map without resetting clearcoat. The r186 material-copy implementation preserves the clearcoat properties and associated maps. Three.js r186 material-copy source Along that code path, a base roughness of 0.86 can coexist with a clearcoat roughness of 0.04. The base roughness value alone does not describe the complete material. This is a plausible explanation for the remaining highlights, not an experimentally established cause. The capture session did not include a clearcoat-disabled comparison or direct inspection of the final material uniforms. Surface normals, bright regions in the environment, and other material settings can also affect the image. A preset named Matte does not imply zero reflection. A follow-up comparison that could distinguish the causes The next diagnostic step would keep the model, camera, color, base roughness, metalness, and environment fixed in an isolated scene: | Proposed condition | Base roughness | Metalness | Clearcoat | Clearcoat roughness | | --- | ---: | ---: | ---: | ---: | | A: retain the coating | 0.86 | 0.02 | 1 | 0.04 | | B: disable only the coating | 0.86 | 0.02 | 0 | 0.04 | | C: increase only coating roughness | 0.86 | 0.02 | 1 | 0.86 | A/B would examine the coating's contribution. A/C would examine the effect of its roughness. These comparisons have not been performed, and no results are claimed here. The values are diagnostic choices, not calibrated settings for a real wrap film. For a similar investigation: 1. Record the actual material type, asset version, and glTF extensions. 2. List every property changed by the UI action. 3. Inspect the base and coating layers separately, including their maps and normals. 4. Keep the camera, environment, exposure, and output pipeline fixed while changing one diagnostic variable. 5. Return to the starting condition and capture it again. Keep the color pipeline consistent as well. Three.js distinguishes color inputs, its linear working space, and display output. A base-color input is not a promise that the illuminated body will have the same pixel values. Color textures and roughness-data textures also require different color-space treatment. Three.js Color Management manual The eight captures establish recoverable image changes between color and finish presets. The asset fields, loader, and copy implementation establish a documented route by which an imported coating can survive those preset changes. Whether that coating caused the particular sharp highlights remains a question for the next controlled comparison.

    5 reactions · 1 comment
  7. Today's #ThreeJS PR: High accuracy, spatio-temporal de-noised 1 ray/pixel Screen Space Reflections (SSR) re-write @ 60 FPS + coverage output. three.js#35228

    9 likes
  8. Today's #ThreeJS PR: High accuracy, spatio-temporal de-noised 1 ray/pixel Screen Space Reflections (SSR) re-write @ 60 FPS + coverage output. three.js#35228 t.co

    39 likes · 4 reposts · 1,968 views
  9. AI 모션그래픽 저장소 20개 모음 모션그래픽 제작에 쓰는 저장소 20개를 기획·에셋·움직임·입체 장면·출력 순서로 정리했습니다. 필요한 도구만 조합하고 각 저장소의 설치 안내와 이용 조건을 확인하면 됩니다. 도구·자료 주소 penpot/penpot excalidraw/excalidraw fontsource/fontsource lucide-icons/lucide svg/svgo lovell/sharp airbnb/lottie-web rive-app/rive-wasm motiondivision/motion greensock/GSAP juliangarnier/anime theatre-js/theatre mrdoob/three.js pmndrs/react-three-fiber pmndrs/drei pmndrs/postprocessing remotion-dev/remotion remotion-dev/skills FFmpeg/FFmpeg Vanilagy/mediabunny #모션그래픽 #개발도구 #AI활용 #투더제이 [en-US] 20 AI Motion Graphics Resources Collection We have organized 20 repositories used for motion graphics production in the order of Planning, Assets, Motion, 3D Scenes, and Output. Simply combine the tools you need and check the installation instructions and terms of use for each repository. Tool/Resource Addresses penpot/penpot excalidraw/excalidraw fontsource/fontsource lucide-icons/lucide svg/svgo lovell/sharp airbnb/lottie-web rive-app/rive-wasm motiondivision/motion greensock/GSAP gi thub.com/juliangarnier/anime theatre-js/theatre mrdoob/three.js pmndrs/react-three-fiber pmndrs/drei pmndrs/postprocessing remotion-dev/remotion remotion-dev/skills FFmpeg/FFmpeg Vanilagy/mediabunny #MotionGraphics #DevelopmentTools #AIUtilization #ToTheJ

    81 likes · 2 comments · 2,503 views
  10. Reddit · · r/threejs · u/Icy-Currency7754 · mrdoob/slop-newyork

    Flying car simulator over a 1:1 Manhattan, built on mrdoob's Slop New York (three.js WebGPU) I took mrdoob's Slop New York and had Claude Opus 5.5 turn it into a flying car sim. You drive a Roadster through Manhattan, jump, and fly it with thrusters. Press U for Ludicrous mode (unlimited air). - Built with three.js WebGPU - 1:1 Manhattan streets, real landmarks, live traffic - The flight in the video is an autopilot script. Cruise sped up 1.5x, clips cut together Play: flyingcarsimulator.io Original: mrdoob/slop-newyork Happy to answer questions about how it's put together.

    10 comments
Trending awards, every completed day and week
Gold
01st place finishes
Silver
22nd place finishes
Bronze
33rd place finishes
Awarded repositories
2Owned by mrdoob now

Repositories

Ordered by gold, then silver, then bronze.

  1. three.jsBest: 2nd by stars, 87 stars013
  2. texgen.jsBest: 2nd by stars, 645 stars010

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.