voxel-three 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -13,7 +13,7 @@ scene.add(new Voxel({ worker: new Worker() }))
13
13
 
14
14
  ## なぜ voxel-three か
15
15
 
16
- `voxelized-js` はすでに、惑星規模のボクセルワールドを描画するための難所を引き受けている。Web メルカトルに基づくリージョンのストリーミング、アトラス画像のフェッチ、グリーディメッシュ化、優先度スケジューリング、スロット割り当てなど。いっぽうで、そのエンジンを Three.js に接続する部分は提供されていない。結果として、`voxelized-js` を利用する Three.js プロジェクトはどれも同じグルーコードを書き直すことになり、以下の 3 つの問題が発生していた。
16
+ `voxelized-js` はすでに、都市規模のボクセルワールドを描画するための難所を引き受けている。Web メルカトルに基づくリージョンのストリーミング、アトラス画像のフェッチ、グリーディメッシュ化、優先度スケジューリング、スロット割り当てなど。いっぽうで、そのエンジンを Three.js に接続する部分は提供されていない。結果として、`voxelized-js` を利用する Three.js プロジェクトはどれも同じグルーコードを書き直すことになり、以下の 3 つの問題が発生していた。
17
17
 
18
18
  重複。各プロジェクトが `4096 × 4096 × 16` の `DataArrayTexture` を確保し、Morton 曲線で UV を求める TSL シェーダを組み立て、毎フレーム `voxel.updates(...)` を呼び、`copyTextureToTexture` でアトラススロットをアップロードし、ユニフォーム配列を更新し、メッシュがオーバーフローしたときに instanced buffer attribute を作り直していた。コピー間の微妙な差異は避けがたかった。
19
19
 
@@ -29,9 +29,7 @@ scene.add(new Voxel({ worker: new Worker() }))
29
29
 
30
30
  デフォルトエクスポートは `THREE.InstancedMesh` を継承したクラス。コンストラクタで、ボクセルパイプラインに必要なリソースをすべて配線する。
31
31
 
32
- `NearestFilter`、`ClampToEdgeWrapping`、mipmap 無効、`SRGBColorSpace` で構成された `4096 × 4096 × 16` の `DataArrayTexture`。これは `this.atlasNode` として公開される。スロットごとのオフセットを保持する 16 要素の `uniformArray<'vec3'>`。これは `this.offsetNode` として公開される。`positionNode` が `offset + pos + positionLocal * scl` を返し、`colorNode` が Morton 曲線の `atlas(ivec3)` TSL ヘルパーを経由してアトラスをサンプリングする `MeshBasicNodeMaterial`。`pos`(`vec3`)、`scl`(`vec3`)、`aid`(`float`)の各 instanced attribute がエンジンから供給される `BoxGeometry`。そして `this.voxel` に格納された `voxelized-js` エンジン本体と、`this.center` に格納されたその中心座標。
33
-
34
- 描画ループ全体は `onBeforeRender` の中で動く。これは Three.js が各オブジェクトに対して標準で呼び出すフック。`useFrame` も `voxel.updates()` の手動呼び出しも、外部からのテクスチャアップロードも不要で、Three がシーングラフを辿る過程でクラスがすべてを処理する。
32
+ `NearestFilter`、`ClampToEdgeWrapping`、mipmap 無効、`SRGBColorSpace` で構成された `4096 × 4096 × 16` の `DataArrayTexture`。これは `this.dstTexture` として公開される。スロットごとのオフセットを保持する 16 要素の `uniformArray<'vec3'>`。これは `this.offsetNode` として公開される。`positionNode` が `offset + pos + positionLocal * scl` を返し、`colorNode` が Morton 曲線の `atlas(ivec3)` TSL ヘルパーを経由してアトラスをサンプリングする `MeshBasicNodeMaterial`。`pos`(`vec3`)、`scl`(`vec3`)、`aid`(`float`)の各 instanced attribute がエンジンから供給される `BoxGeometry`。そして `this.voxel` に格納された `voxelized-js` エンジン本体と、`this.center` に格納されたその中心座標。
35
33
 
36
34
  ### `atlas(ivec3)`、`xyz2m(ivec3)`、`m2uv(int)` — 共有 TSL ヘルパー
37
35
 
@@ -59,7 +57,7 @@ import { atlas, xyz2m, m2uv } from 'voxel-three'
59
57
 
60
58
  ## 使い方
61
59
 
62
- ### 素の Three.js
60
+ ### Plain Three.js
63
61
 
64
62
  ```ts
65
63
  import * as THREE from 'three'
@@ -100,7 +98,7 @@ const App = () => (
100
98
 
101
99
  ### アトラスを読む compute シェーダ
102
100
 
103
- `this.atlasNode` と `this.offsetNode` はそのまま TSL ノードなので、ユーザ定義の compute シェーダから直接参照できる。以下の例は、ワールド座標における地面の高さを求めるため、アトラスのスロットを上から下へ走査している。
101
+ `this.dstTexture` と `this.offsetNode` はそのまま TSL ノードなので、ユーザ定義の compute シェーダから直接参照できる。以下の例は、ワールド座標における地面の高さを求めるため、アトラスのスロットを上から下へ走査している。
104
102
 
105
103
  <!-- prettier-ignore -->
106
104
  ```ts
@@ -109,7 +107,7 @@ import { atlas } from 'voxel-three'
109
107
 
110
108
  const findGround = (voxel) =>
111
109
  Fn(([wx, wz]) => {
112
- const iAtlas = voxel.atlasNode
110
+ const iAtlas = voxel.dstTexture
113
111
  const iOffset = voxel.offsetNode
114
112
  // ... iOffset を走査して一致するスロットを探す
115
113
  // ... そのうえで y を Loop し、textureLoad(iAtlas, atlas(ivec3(lx, y, lz)), int(0)) を呼ぶ
@@ -136,14 +134,12 @@ new Voxel({
136
134
 
137
135
  ## 公開フィールドとメソッド
138
136
 
139
- `voxel` は `voxelized-js` のエンジン本体を保持する。`voxel.cam.turn(...)`、`voxel.pick(x, y, z)`、`voxel.map` など、コアライブラリとまったく同じ API がそのまま使える。`atlasNode` はマテリアルがサンプリングする `DataArrayTexture` を保持する。`offsetNode` は `-center` で事前にシフト済みのスロットオフセットを持つ `uniformArray<'vec3'>` を保持する。`center` は絶対メルカトル空間における元の `[cx, cz]` 中心値を保持しており、絶対座標が依然として必要なユーザ側コード(たとえばピンのジオコーディング)はこの値を加算し直すことで得られる。
137
+ `voxel` は `voxelized-js` のエンジン本体を保持する。`voxel.cam.turn(...)`、`voxel.pick(x, y, z)`、`voxel.map` など、コアライブラリとまったく同じ API がそのまま使える。`dstTexture` はマテリアルがサンプリングする `DataArrayTexture` を保持する。`offsetNode` は `-center` で事前にシフト済みのスロットオフセットを持つ `uniformArray<'vec3'>` を保持する。`center` は絶対メルカトル空間における元の `[cx, cz]` 中心値を保持しており、絶対座標が依然として必要なユーザ側コード(たとえばピンのジオコーディング)はこの値を加算し直すことで得られる。
140
138
 
141
139
  ## 互換性と設計メモ
142
140
 
143
141
  `voxelized-js` 本体には一切手を入れていない。リージョンカリング、スロット管理、ワーカブリッジ、優先度スケジューリング、デバッグフックは、コアパッケージのドキュメント通りに動き続ける。`voxel-three` は厳密に公開 API の上に立っているだけなので、エンジンを手書きで駆動し続けたいプロジェクトは今までどおり利用できる。
144
142
 
145
- デフォルトエクスポートと名前付きエクスポート `Voxel` は同一のクラスを指し、`import Voxel from 'voxel-three'` と `import { Voxel } from 'voxel-three'` の双方で動く。`./src` サブパスエクスポートは、モノレポ内から tsup ビルドを経由せずソースを直接 import したい利用者向けで、`voxelized-js` と同じ規約に揃えている。
146
-
147
143
  ## 動作要件
148
144
 
149
145
  Three.js `>= 0.180`、かつ `three/webgpu` と `three/tsl` が利用可能なこと。マテリアルが `MeshBasicNodeMaterial` の上に構築されているため、WebGPU 対応ブラウザ(または `WebGPURenderer` のフォールバック経路)が必要。`voxelized-js` の Web Worker インスタンスも必要で、通常は `new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' })` か、バンドラ固有の `?worker` import で生成する。
package/README.md CHANGED
@@ -13,7 +13,7 @@ scene.add(new Voxel({ worker: new Worker() }))
13
13
 
14
14
  ## Why voxel-three
15
15
 
16
- `voxelized-js` already handles the hard parts of rendering a planet-scale voxel world: web-mercator region streaming, atlas image fetching, greedy meshing, priority scheduling, and slot allocation. What it does not do is talk to Three.js. Every Three.js project that wanted to consume the engine ended up re-writing the same glue code, which had three problems:
16
+ `voxelized-js` already handles the hard parts of rendering a city-scale voxel world: web-mercator region streaming, atlas image fetching, greedy meshing, priority scheduling, and slot allocation. What it does not do is talk to Three.js. Every Three.js project that wanted to consume the engine ended up re-writing the same glue code, which had three problems:
17
17
 
18
18
  Duplication. Every consumer had to allocate a 4096 × 4096 × 16 `DataArrayTexture`, build a TSL shader with Morton-curve UV lookups, call `voxel.updates(...)` each frame, upload atlas slots through `copyTextureToTexture`, refresh uniform arrays, and rebuild instanced buffer attributes when the mesh overflowed. Minor drift between copies was unavoidable.
19
19
 
@@ -29,9 +29,7 @@ Camera bridging. Some projects drive the engine from a Three camera (OrbitContro
29
29
 
30
30
  The default export is a class that extends `THREE.InstancedMesh`. Construction wires up every resource the voxel pipeline needs:
31
31
 
32
- A `DataArrayTexture` of size `4096 × 4096 × 16`, configured with `NearestFilter`, `ClampToEdgeWrapping`, no mipmaps, `SRGBColorSpace`, and exposed as `this.atlasNode`. A 16-element `uniformArray<'vec3'>` of slot offsets, exposed as `this.offsetNode`. A `MeshBasicNodeMaterial` whose `positionNode` evaluates `offset + pos + positionLocal * scl` and whose `colorNode` samples the atlas via a Morton-curve `atlas(ivec3)` TSL helper. A `BoxGeometry` with instanced `pos` (`vec3`), `scl` (`vec3`) and `aid` (`float`) attributes populated from the engine. A `voxelized-js` engine instance stored at `this.voxel`, plus its center coordinates at `this.center`.
33
-
34
- The whole render loop runs inside `onBeforeRender`, which is Three.js's standard per-object hook. No `useFrame`, no manual `voxel.updates()` call, and no external texture upload — the class handles it all while Three walks the scene graph.
32
+ A `DataArrayTexture` of size `4096 × 4096 × 16`, configured with `NearestFilter`, `ClampToEdgeWrapping`, no mipmaps, `SRGBColorSpace`, and exposed as `this.dstTexture`. A 16-element `uniformArray<'vec3'>` of slot offsets, exposed as `this.offsetNode`. A `MeshBasicNodeMaterial` whose `positionNode` evaluates `offset + pos + positionLocal * scl` and whose `colorNode` samples the atlas via a Morton-curve `atlas(ivec3)` TSL helper. A `BoxGeometry` with instanced `pos` (`vec3`), `scl` (`vec3`) and `aid` (`float`) attributes populated from the engine. A `voxelized-js` engine instance stored at `this.voxel`, plus its center coordinates at `this.center`.
35
33
 
36
34
  ### `atlas(ivec3)`, `xyz2m(ivec3)`, `m2uv(int)` — shared TSL helpers
37
35
 
@@ -100,7 +98,7 @@ const App = () => (
100
98
 
101
99
  ### Compute shaders that read the atlas
102
100
 
103
- Because `this.atlasNode` and `this.offsetNode` are plain TSL nodes, user-authored compute shaders can reference them directly. This example finds the ground height at a world coordinate by walking the atlas slots from top to bottom:
101
+ Because `this.dstTexture` and `this.offsetNode` are plain TSL nodes, user-authored compute shaders can reference them directly. This example finds the ground height at a world coordinate by walking the atlas slots from top to bottom:
104
102
 
105
103
  <!-- prettier-ignore -->
106
104
  ```ts
@@ -109,7 +107,7 @@ import { atlas } from 'voxel-three'
109
107
 
110
108
  const findGround = (voxel) =>
111
109
  Fn(([wx, wz]) => {
112
- const iAtlas = voxel.atlasNode
110
+ const iAtlas = voxel.dstTexture
113
111
  const iOffset = voxel.offsetNode
114
112
  // ... walk iOffset to find the matching slot
115
113
  // ... then Loop over y and textureLoad(iAtlas, atlas(ivec3(lx, y, lz)), int(0))
@@ -136,14 +134,12 @@ Any additional keys are forwarded to `voxelized-js`'s `createVoxel` factory, so
136
134
 
137
135
  ## Exposed fields and methods
138
136
 
139
- `voxel` holds the underlying `voxelized-js` engine. Call `voxel.cam.turn(...)`, `voxel.pick(x, y, z)`, read `voxel.map`, and so on, exactly as in the base library. `atlasNode` holds the `DataArrayTexture` that the material samples. `offsetNode` holds the `uniformArray<'vec3'>` of slot offsets, already pre-shifted by `-center`. `center` holds the original `[cx, cz]` center in absolute mercator space, so user code that still needs absolute coordinates (for example, to geocode a pin) can add it back.
137
+ `voxel` holds the underlying `voxelized-js` engine. Call `voxel.cam.turn(...)`, `voxel.pick(x, y, z)`, read `voxel.map`, and so on, exactly as in the base library. `dstTexture` holds the `DataArrayTexture` that the material samples. `offsetNode` holds the `uniformArray<'vec3'>` of slot offsets, already pre-shifted by `-center`. `center` holds the original `[cx, cz]` center in absolute mercator space, so user code that still needs absolute coordinates (for example, to geocode a pin) can add it back.
140
138
 
141
139
  ## Compatibility and design notes
142
140
 
143
141
  `voxelized-js` itself is completely untouched: region culling, slot management, the worker bridge, priority scheduling, and the debug hooks all behave exactly as documented in the core package. `voxel-three` sits strictly above the public API, so any project that wants to keep driving the engine by hand can continue to do so.
144
142
 
145
- The default export and the named `Voxel` export are the same class, supporting both `import Voxel from 'voxel-three'` and `import { Voxel } from 'voxel-three'`. The `./src` subpath export is available for monorepo consumers that want to import directly from source without going through the tsup build, matching the convention used by `voxelized-js`.
146
-
147
143
  ## Requirements
148
144
 
149
145
  Three.js `>= 0.180` with access to `three/webgpu` and `three/tsl`. A WebGPU-capable browser (or the `WebGPURenderer` fallback path) is required because the material is built on `MeshBasicNodeMaterial`. A `voxelized-js` Web Worker instance is required, typically created with `new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' })` or a bundler-specific `?worker` import.
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ declare class Voxel extends three_webgpu.InstancedMesh {
14
14
  voxel: Res;
15
15
  offsetNode: UniformArrayNode<'vec3'>;
16
16
  dstTexture: DataArrayTexture;
17
+ private _context;
17
18
  private _texture;
18
19
  private _isThree;
19
20
  constructor(params: Req & {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var I=Object.create;var x=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var P=(r,t,e)=>t in r?x(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var W=(r,t)=>{for(var e in t)x(r,e,{get:t[e],enumerable:!0})},L=(r,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of j(t))!G.call(r,a)&&a!==e&&x(r,a,{get:()=>t[a],enumerable:!(i=k(t,a))||i.enumerable});return r};var C=(r,t,e)=>(e=r!=null?I(z(r)):{},L(t||!r||!r.__esModule?x(e,"default",{value:r,enumerable:!0}):e,r)),q=r=>L(x({},"__esModule",{value:!0}),r);var u=(r,t,e)=>P(r,typeof t!="symbol"?t+"":t,e);var et={};W(et,{Voxel:()=>m,atlas:()=>V,default:()=>tt,m2uv:()=>B,xyz2m:()=>M});module.exports=q(et);var o=C(require("three/webgpu")),n=require("three/tsl"),D=C(require("voxelized-js/src"));var s=require("three/tsl"),M=(0,s.Fn)(([r])=>{let t=r.x.toVar(),e=r.y.toVar(),i=r.z.toVar();return t.assign(t.bitOr(t.shiftLeft((0,s.int)(16)))),e.assign(e.bitOr(e.shiftLeft((0,s.int)(16)))),i.assign(i.bitOr(i.shiftLeft((0,s.int)(16)))),t.assign(t.bitAnd((0,s.int)(-16776961))),e.assign(e.bitAnd((0,s.int)(-16776961))),i.assign(i.bitAnd((0,s.int)(-16776961))),t.assign(t.bitOr(t.shiftLeft((0,s.int)(8)))),e.assign(e.bitOr(e.shiftLeft((0,s.int)(8)))),i.assign(i.bitOr(i.shiftLeft((0,s.int)(8)))),t.assign(t.bitAnd((0,s.int)(50393103))),e.assign(e.bitAnd((0,s.int)(50393103))),i.assign(i.bitAnd((0,s.int)(50393103))),t.assign(t.bitOr(t.shiftLeft((0,s.int)(4)))),e.assign(e.bitOr(e.shiftLeft((0,s.int)(4)))),i.assign(i.bitOr(i.shiftLeft((0,s.int)(4)))),t.assign(t.bitAnd((0,s.int)(51130563))),e.assign(e.bitAnd((0,s.int)(51130563))),i.assign(i.bitAnd((0,s.int)(51130563))),t.assign(t.bitOr(t.shiftLeft((0,s.int)(2)))),e.assign(e.bitOr(e.shiftLeft((0,s.int)(2)))),i.assign(i.bitOr(i.shiftLeft((0,s.int)(2)))),t.assign(t.bitAnd((0,s.int)(153391689))),e.assign(e.bitAnd((0,s.int)(153391689))),i.assign(i.bitAnd((0,s.int)(153391689))),t.bitOr(e.shiftLeft((0,s.int)(1))).bitOr(i.shiftLeft((0,s.int)(2)))}),B=(0,s.Fn)(([r])=>{let t=r.toVar(),e=r.shiftRight((0,s.int)(1)).toVar();return t.assign(t.bitAnd((0,s.int)(1431655765))),e.assign(e.bitAnd((0,s.int)(1431655765))),t.assign(t.bitOr(t.shiftRight((0,s.int)(1)))),e.assign(e.bitOr(e.shiftRight((0,s.int)(1)))),t.assign(t.bitAnd((0,s.int)(858993459))),e.assign(e.bitAnd((0,s.int)(858993459))),t.assign(t.bitOr(t.shiftRight((0,s.int)(2)))),e.assign(e.bitOr(e.shiftRight((0,s.int)(2)))),t.assign(t.bitAnd((0,s.int)(252645135))),e.assign(e.bitAnd((0,s.int)(252645135))),t.assign(t.bitOr(t.shiftRight((0,s.int)(4)))),e.assign(e.bitOr(e.shiftRight((0,s.int)(4)))),t.assign(t.bitAnd((0,s.int)(16711935))),e.assign(e.bitAnd((0,s.int)(16711935))),t.assign(t.bitOr(t.shiftRight((0,s.int)(8)))),e.assign(e.bitOr(e.shiftRight((0,s.int)(8)))),t.assign(t.bitAnd((0,s.int)(65535))),e.assign(e.bitAnd((0,s.int)(65535))),(0,s.ivec2)(t,e)}),V=(0,s.Fn)(([r])=>B(M(r)));var Y=new o.Vector2,N=new o.Vector3,_=new o.Matrix4,U=new o.Matrix4,J=(r,t,e,i,a)=>{let f=a.getSize(Y);r.update(f.x/f.y),t.position.set(r.pos[0]-e,r.pos[1],r.pos[2]-i),N.set(r.eye[0]-e,r.eye[1],r.eye[2]-i),t.lookAt(N),t.updateMatrixWorld(),t.updateProjectionMatrix()},K=(r,t,e,i)=>{_.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),U.makeTranslation(-e,0,-i),_.multiply(U);for(let a=0;a<16;a++)r.mvp[a]=_.elements[a];r.pos[0]=t.position.x+e,r.pos[1]=t.position.y,r.pos[2]=t.position.z+i},Q=(r=16)=>{let t=new o.DataArrayTexture(null,4096,4096,r);return t.minFilter=t.magFilter=o.NearestFilter,t.wrapS=t.wrapT=o.ClampToEdgeWrapping,t.generateMipmaps=!1,t.needsUpdate=!0,t.source.dataReady=!1,t.colorSpace=o.SRGBColorSpace,t},X=()=>new o.Vector3,Z=()=>new o.BoxGeometry,$=(r,t)=>{let e=(0,n.attribute)("pos","vec3"),i=(0,n.attribute)("scl","vec3"),a=(0,n.attribute)("aid","float"),f=(0,n.Fn)(([c,g])=>(0,n.textureLoad)(r,g,(0,n.int)(0)).depth(c.toInt())),d=(0,n.Fn)(([c])=>(0,n.vec3)(-.33,.77,.55).normalize().dot(c).mul(.5).add(.5)),A=(0,n.Fn)(()=>t.element(a.toInt()).add(e.add(n.positionLocal.mul(i)))),R=(0,n.Fn)(()=>e.add(n.positionGeometry.mul(i)).sub(n.normalLocal.sign().mul((0,n.float)(.5))).floor()),p=(0,n.varying)(a,"vAid"),v=(0,n.varying)(d(n.normalLocal),"vDiff"),h=(0,n.varying)(R(),"vCenter"),T=(0,n.Fn)(()=>{let c=(0,n.ivec3)(h),g=V(c).toVar("uv"),b=f(p,g).rgb.mul(v).toVar("rgb");return(0,n.vec4)(b,1)}),l=new o.MeshBasicNodeMaterial({side:o.FrontSide});return l.positionNode=A(),l.colorNode=T(),l},m=class extends o.InstancedMesh{constructor(e){let{slot:i=16,controls:a}=e,f=(0,n.uniformArray)(Array.from({length:i},X),"vec3"),d=Q(i);super(Z(),$(d,f),1);u(this,"voxel");u(this,"offsetNode");u(this,"dstTexture");u(this,"_texture");u(this,"_isThree");this.offsetNode=f,this.dstTexture=d,this.frustumCulled=!1,this.voxel=(0,D.default)(e),this._texture=new o.Texture,this._texture.flipY=this._texture.generateMipmaps=!1,this._isThree=a!=="voxel",this._setAttribute()}onBeforeRender(e,i,a){let{dstTexture:f,offsetNode:d,voxel:A,_isThree:R,_texture:p}=this,{center:v,cam:h,updates:T,updated:l,count:c,overflow:g}=A,[b,y]=v;R?K(h,a,b,y):J(h,a,b,y,e);let w=d,F=w.array;if(T(({at:H,atlas:S,offset:O})=>{F[H].set(O[0]-b,O[1],O[2]-y),p.image=S,p.needsUpdate=w.needsUpdate=!0,e.copyTextureToTexture(p,f,null,N.set(0,0,H))}),!l())return;if(g())return this._setAttribute();let E=this.geometry;E.getAttribute("pos").needsUpdate=!0,E.getAttribute("scl").needsUpdate=!0,E.getAttribute("aid").needsUpdate=!0,this.count=c()}_setAttribute(){let{geometry:e,voxel:i}=this,{pos:a,scl:f,aid:d}=i;e.setAttribute("pos",new o.InstancedBufferAttribute(a(),3)),e.setAttribute("scl",new o.InstancedBufferAttribute(f(),3)),e.setAttribute("aid",new o.InstancedBufferAttribute(d(),1))}},tt=m;0&&(module.exports={Voxel,atlas,m2uv,xyz2m});
1
+ "use strict";var k=Object.create;var x=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var P=(s,t,e)=>t in s?x(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var q=(s,t)=>{for(var e in t)x(s,e,{get:t[e],enumerable:!0})},L=(s,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of z(t))!W.call(s,a)&&a!==e&&x(s,a,{get:()=>t[a],enumerable:!(n=j(t,a))||n.enumerable});return s};var F=(s,t,e)=>(e=s!=null?k(G(s)):{},L(t||!s||!s.__esModule?x(e,"default",{value:s,enumerable:!0}):e,s)),Y=s=>L(x({},"__esModule",{value:!0}),s);var u=(s,t,e)=>P(s,typeof t!="symbol"?t+"":t,e);var nt={};q(nt,{Voxel:()=>m,atlas:()=>H,default:()=>rt,m2uv:()=>B,xyz2m:()=>M});module.exports=Y(nt);var o=F(require("three/webgpu")),i=require("three/tsl"),U=F(require("voxelized-js/src"));var r=require("three/tsl"),M=(0,r.Fn)(([s])=>{let t=s.x.toVar(),e=s.y.toVar(),n=s.z.toVar();return t.assign(t.bitOr(t.shiftLeft((0,r.int)(16)))),e.assign(e.bitOr(e.shiftLeft((0,r.int)(16)))),n.assign(n.bitOr(n.shiftLeft((0,r.int)(16)))),t.assign(t.bitAnd((0,r.int)(-16776961))),e.assign(e.bitAnd((0,r.int)(-16776961))),n.assign(n.bitAnd((0,r.int)(-16776961))),t.assign(t.bitOr(t.shiftLeft((0,r.int)(8)))),e.assign(e.bitOr(e.shiftLeft((0,r.int)(8)))),n.assign(n.bitOr(n.shiftLeft((0,r.int)(8)))),t.assign(t.bitAnd((0,r.int)(50393103))),e.assign(e.bitAnd((0,r.int)(50393103))),n.assign(n.bitAnd((0,r.int)(50393103))),t.assign(t.bitOr(t.shiftLeft((0,r.int)(4)))),e.assign(e.bitOr(e.shiftLeft((0,r.int)(4)))),n.assign(n.bitOr(n.shiftLeft((0,r.int)(4)))),t.assign(t.bitAnd((0,r.int)(51130563))),e.assign(e.bitAnd((0,r.int)(51130563))),n.assign(n.bitAnd((0,r.int)(51130563))),t.assign(t.bitOr(t.shiftLeft((0,r.int)(2)))),e.assign(e.bitOr(e.shiftLeft((0,r.int)(2)))),n.assign(n.bitOr(n.shiftLeft((0,r.int)(2)))),t.assign(t.bitAnd((0,r.int)(153391689))),e.assign(e.bitAnd((0,r.int)(153391689))),n.assign(n.bitAnd((0,r.int)(153391689))),t.bitOr(e.shiftLeft((0,r.int)(1))).bitOr(n.shiftLeft((0,r.int)(2)))}),B=(0,r.Fn)(([s])=>{let t=s.toVar(),e=s.shiftRight((0,r.int)(1)).toVar();return t.assign(t.bitAnd((0,r.int)(1431655765))),e.assign(e.bitAnd((0,r.int)(1431655765))),t.assign(t.bitOr(t.shiftRight((0,r.int)(1)))),e.assign(e.bitOr(e.shiftRight((0,r.int)(1)))),t.assign(t.bitAnd((0,r.int)(858993459))),e.assign(e.bitAnd((0,r.int)(858993459))),t.assign(t.bitOr(t.shiftRight((0,r.int)(2)))),e.assign(e.bitOr(e.shiftRight((0,r.int)(2)))),t.assign(t.bitAnd((0,r.int)(252645135))),e.assign(e.bitAnd((0,r.int)(252645135))),t.assign(t.bitOr(t.shiftRight((0,r.int)(4)))),e.assign(e.bitOr(e.shiftRight((0,r.int)(4)))),t.assign(t.bitAnd((0,r.int)(16711935))),e.assign(e.bitAnd((0,r.int)(16711935))),t.assign(t.bitOr(t.shiftRight((0,r.int)(8)))),e.assign(e.bitOr(e.shiftRight((0,r.int)(8)))),t.assign(t.bitAnd((0,r.int)(65535))),e.assign(e.bitAnd((0,r.int)(65535))),(0,r.ivec2)(t,e)}),H=(0,r.Fn)(([s])=>B(M(s)));var J=new o.Vector2,C=new o.Vector3,N=new o.Matrix4,D=new o.Matrix4,K=(s,t,e,n,a)=>{let f=a.getSize(J);s.update(f.x/f.y),t.position.set(s.pos[0]-e,s.pos[1],s.pos[2]-n),C.set(s.eye[0]-e,s.eye[1],s.eye[2]-n),t.lookAt(C),t.updateMatrixWorld(),t.updateProjectionMatrix()},Q=(s,t,e,n)=>{N.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),D.makeTranslation(-e,0,-n),N.multiply(D);for(let a=0;a<16;a++)s.mvp[a]=N.elements[a];s.pos[0]=t.position.x+e,s.pos[1]=t.position.y,s.pos[2]=t.position.z+n},X=()=>new o.Vector3,Z=()=>new o.BoxGeometry,$=(s,t)=>{let e=(0,i.attribute)("pos","vec3"),n=(0,i.attribute)("scl","vec3"),a=(0,i.attribute)("aid","float"),f=(0,i.Fn)(([c,g])=>(0,i.textureLoad)(s,g,(0,i.int)(0)).depth(c.toInt())),d=(0,i.Fn)(([c])=>(0,i.vec3)(-.33,.77,.55).normalize().dot(c).mul(.5).add(.5)),l=(0,i.Fn)(()=>t.element(a.toInt()).add(e.add(i.positionLocal.mul(n)))),v=(0,i.Fn)(()=>e.add(i.positionGeometry.mul(n)).sub(i.normalLocal.sign().mul((0,i.float)(.5))).floor()),T=(0,i.varying)(a,"vAid"),b=(0,i.varying)(d(i.normalLocal),"vDiff"),h=(0,i.varying)(v(),"vCenter"),E=(0,i.Fn)(()=>{let c=(0,i.ivec3)(h),g=H(c).toVar("uv"),R=f(T,g).rgb.mul(b).toVar("rgb");return(0,i.vec4)(R,1)}),p=new o.MeshBasicNodeMaterial({side:o.FrontSide});return p.positionNode=l(),p.colorNode=E(),p},tt=(s=16)=>{let t=new o.DataArrayTexture(null,4096,4096,s);return t.wrapS=o.ClampToEdgeWrapping,t.wrapT=o.ClampToEdgeWrapping,t.magFilter=o.NearestFilter,t.minFilter=o.NearestFilter,t.colorSpace=o.SRGBColorSpace,t.needsUpdate=!0,t.generateMipmaps=!1,t.source.dataReady=!1,t},et=s=>{let t=new o.CanvasTexture(s);return t.magFilter=o.NearestFilter,t.minFilter=o.NearestFilter,t.flipY=!1,t.generateMipmaps=!1,t},st=()=>{let s=document.createElement("canvas");return s.width=4096,s.height=4096,s},m=class extends o.InstancedMesh{constructor(e){let{slot:n=16,controls:a}=e,f=(0,i.uniformArray)(Array.from({length:n},X),"vec3"),d=tt(n);super(Z(),$(d,f),1);u(this,"voxel");u(this,"offsetNode");u(this,"dstTexture");u(this,"_context");u(this,"_texture");u(this,"_isThree");let l=st();this._context=l.getContext("2d"),this._texture=et(l),this.offsetNode=f,this.dstTexture=d,this.frustumCulled=!1,this.voxel=(0,U.default)(e),this._isThree=a!=="voxel",this._setAttribute()}onBeforeRender(e,n,a){let{dstTexture:f,offsetNode:d,voxel:l,_context:v,_isThree:T,_texture:b}=this,{cam:h,center:E,count:p,updated:c,updates:g,overflow:R}=l,[A,y]=E;T?Q(h,a,A,y):K(h,a,A,y,e);let _=d,S=_.array;if(g(({at:w,atlas:I,offset:V})=>{S[w].set(V[0]-A,V[1],V[2]-y),v.drawImage(I,0,0),_.needsUpdate=!0,b.needsUpdate=!0,e.copyTextureToTexture(b,f,null,C.set(0,0,w))}),!c())return;if(R())return this._setAttribute();let O=this.geometry;O.getAttribute("pos").needsUpdate=!0,O.getAttribute("scl").needsUpdate=!0,O.getAttribute("aid").needsUpdate=!0,this.count=p()}_setAttribute(){let{geometry:e,voxel:n}=this,{pos:a,scl:f,aid:d}=n;e.setAttribute("pos",new o.InstancedBufferAttribute(a(),3)),e.setAttribute("scl",new o.InstancedBufferAttribute(f(),3)),e.setAttribute("aid",new o.InstancedBufferAttribute(d(),1))}},rt=m;0&&(module.exports={Voxel,atlas,m2uv,xyz2m});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\nimport { attribute, float, Fn, int, ivec3, normalLocal, positionGeometry, positionLocal, textureLoad, uniformArray, varying, vec3, vec4 } from 'three/tsl'\nimport createVoxel from 'voxelized-js/src'\nimport { atlas } from './utils'\nimport type { Camera, DataArrayTexture, Object3D, Renderer, Scene, Texture, UniformArrayNode, VarNode, Vector3 } from 'three/webgpu'\n\nexport * from './utils'\n\ntype Req = Parameters<typeof createVoxel>[0]\ntype Res = ReturnType<typeof createVoxel>\ntype Cam = Res['cam']\n\ntype BaseRenderer = Parameters<Object3D['onBeforeRender']>[0]\n\nconst _vec2 = new THREE.Vector2()\nconst _vec3 = new THREE.Vector3()\nconst _mat4 = new THREE.Matrix4()\nconst _shift = new THREE.Matrix4()\n\nconst driveFromVoxel = (cam: Cam, camera: Camera, cx: number, cz: number, renderer: Renderer | BaseRenderer) => {\n const size = renderer.getSize(_vec2)\n cam.update(size.x / size.y)\n camera.position.set(cam.pos[0] - cx, cam.pos[1], cam.pos[2] - cz)\n _vec3.set(cam.eye[0] - cx, cam.eye[1], cam.eye[2] - cz)\n camera.lookAt(_vec3)\n camera.updateMatrixWorld()\n // @ts-ignore\n camera.updateProjectionMatrix()\n}\n\nconst driveFromThree = (cam: Cam, camera: Camera, cx: number, cz: number) => {\n _mat4.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n _shift.makeTranslation(-cx, 0, -cz)\n _mat4.multiply(_shift)\n for (let k = 0; k < 16; k++) cam.mvp[k] = _mat4.elements[k]\n cam.pos[0] = camera.position.x + cx\n cam.pos[1] = camera.position.y\n cam.pos[2] = camera.position.z + cz\n}\n\nconst createAtlasTex = (slot = 16) => {\n const t = new THREE.DataArrayTexture(null, 4096, 4096, slot)\n t.minFilter = t.magFilter = THREE.NearestFilter\n t.wrapS = t.wrapT = THREE.ClampToEdgeWrapping\n t.generateMipmaps = false\n t.needsUpdate = true\n t.source.dataReady = false\n t.colorSpace = THREE.SRGBColorSpace\n return t\n}\n\nconst createVec3 = () => new THREE.Vector3()\nconst createGeometry = () => new THREE.BoxGeometry()\nconst createMaterial = (atlasTex: DataArrayTexture, offsetNode: UniformArrayNode<'vec3'>) => {\n const _pos = attribute<'vec3'>('pos', 'vec3')\n const _scl = attribute<'vec3'>('scl', 'vec3')\n const _aid = attribute<'float'>('aid', 'float')\n const pick = Fn(([id, uvPix]: [VarNode<'float'>, VarNode<'ivec2'>]) => {\n return textureLoad(atlasTex, uvPix, int(0)).depth(id.toInt())\n })\n const diffuse = Fn(([n]: [VarNode<'vec3'>]) => {\n return vec3(-0.33, 0.77, 0.55).normalize().dot(n).mul(0.5).add(0.5)\n })\n const position = Fn(() => {\n const off = offsetNode.element(_aid.toInt())\n return off.add(_pos.add(positionLocal.mul(_scl)))\n })\n const center = Fn(() => {\n const local = _pos.add(positionGeometry.mul(_scl))\n return local.sub(normalLocal.sign().mul(float(0.5))).floor()\n })\n const vAid = varying(_aid, 'vAid')\n const vDiff = varying(diffuse(normalLocal), 'vDiff')\n const vCenter = varying(center(), 'vCenter')\n const color = Fn(() => {\n const p = ivec3(vCenter)\n const uv = atlas(p).toVar('uv')\n const rgb = pick(vAid, uv).rgb.mul(vDiff).toVar('rgb')\n return vec4(rgb, 1)\n })\n const mat = new THREE.MeshBasicNodeMaterial({ side: THREE.FrontSide })\n mat.positionNode = position()\n mat.colorNode = color()\n return mat\n}\n\nexport class Voxel extends THREE.InstancedMesh {\n voxel: Res\n offsetNode: UniformArrayNode<'vec3'>\n dstTexture: DataArrayTexture\n private _texture: Texture\n private _isThree: boolean\n constructor(params: Req & { controls?: 'three' | 'voxel' }) {\n const { slot = 16, controls } = params\n const offsetNode = uniformArray<'vec3'>(Array.from({ length: slot }, createVec3), 'vec3')\n const dstTexture = createAtlasTex(slot)\n super(createGeometry(), createMaterial(dstTexture, offsetNode), 1)\n this.offsetNode = offsetNode\n this.dstTexture = dstTexture\n this.frustumCulled = false\n this.voxel = createVoxel(params)\n this._texture = new THREE.Texture()\n this._texture.flipY = this._texture.generateMipmaps = false\n this._isThree = controls !== 'voxel'\n this._setAttribute()\n }\n onBeforeRender(renderer: Renderer | BaseRenderer, _scene: Scene, camera: Camera) {\n const { dstTexture, offsetNode, voxel, _isThree, _texture } = this\n const { center, cam, updates, updated, count, overflow } = voxel\n const [cx, cz] = center\n if (_isThree) driveFromThree(cam, camera, cx, cz)\n else driveFromVoxel(cam, camera, cx, cz, renderer)\n const _node = offsetNode as unknown as { array: Vector3[]; needsUpdate: boolean }\n const array = _node.array\n updates(({ at, atlas, offset }) => {\n array[at].set(offset[0] - cx, offset[1], offset[2] - cz)\n _texture.image = atlas\n _texture.needsUpdate = _node.needsUpdate = true\n renderer.copyTextureToTexture(_texture, dstTexture, null, _vec3.set(0, 0, at))\n })\n if (!updated()) return\n if (overflow()) return this._setAttribute()\n const geometry = this.geometry\n geometry.getAttribute('pos').needsUpdate = true\n geometry.getAttribute('scl').needsUpdate = true\n geometry.getAttribute('aid').needsUpdate = true\n this.count = count()\n }\n private _setAttribute() {\n const { geometry, voxel } = this\n const { pos, scl, aid } = voxel\n geometry.setAttribute('pos', new THREE.InstancedBufferAttribute(pos(), 3))\n geometry.setAttribute('scl', new THREE.InstancedBufferAttribute(scl(), 3))\n geometry.setAttribute('aid', new THREE.InstancedBufferAttribute(aid(), 1))\n }\n}\n\nexport default Voxel\n","import { Fn, int, ivec2 } from 'three/tsl'\nimport type { VarNode } from 'three/webgpu'\n\nexport const xyz2m = Fn(([xyz]: [VarNode<'ivec3'>]) => {\n const x = xyz.x.toVar()\n const y = xyz.y.toVar()\n const z = xyz.z.toVar()\n x.assign(x.bitOr(x.shiftLeft(int(16))))\n y.assign(y.bitOr(y.shiftLeft(int(16))))\n z.assign(z.bitOr(z.shiftLeft(int(16))))\n x.assign(x.bitAnd(int(0xff0000ff | 0)))\n y.assign(y.bitAnd(int(0xff0000ff | 0)))\n z.assign(z.bitAnd(int(0xff0000ff | 0)))\n x.assign(x.bitOr(x.shiftLeft(int(8))))\n y.assign(y.bitOr(y.shiftLeft(int(8))))\n z.assign(z.bitOr(z.shiftLeft(int(8))))\n x.assign(x.bitAnd(int(0x0300f00f)))\n y.assign(y.bitAnd(int(0x0300f00f)))\n z.assign(z.bitAnd(int(0x0300f00f)))\n x.assign(x.bitOr(x.shiftLeft(int(4))))\n y.assign(y.bitOr(y.shiftLeft(int(4))))\n z.assign(z.bitOr(z.shiftLeft(int(4))))\n x.assign(x.bitAnd(int(0x030c30c3)))\n y.assign(y.bitAnd(int(0x030c30c3)))\n z.assign(z.bitAnd(int(0x030c30c3)))\n x.assign(x.bitOr(x.shiftLeft(int(2))))\n y.assign(y.bitOr(y.shiftLeft(int(2))))\n z.assign(z.bitOr(z.shiftLeft(int(2))))\n x.assign(x.bitAnd(int(0x09249249)))\n y.assign(y.bitAnd(int(0x09249249)))\n z.assign(z.bitAnd(int(0x09249249)))\n return x.bitOr(y.shiftLeft(int(1))).bitOr(z.shiftLeft(int(2)))\n})\n\nexport const m2uv = Fn(([morton]: [VarNode<'int'>]) => {\n const px = morton.toVar()\n const py = morton.shiftRight(int(1)).toVar()\n px.assign(px.bitAnd(int(0x55555555)))\n py.assign(py.bitAnd(int(0x55555555)))\n px.assign(px.bitOr(px.shiftRight(int(1))))\n py.assign(py.bitOr(py.shiftRight(int(1))))\n px.assign(px.bitAnd(int(0x33333333)))\n py.assign(py.bitAnd(int(0x33333333)))\n px.assign(px.bitOr(px.shiftRight(int(2))))\n py.assign(py.bitOr(py.shiftRight(int(2))))\n px.assign(px.bitAnd(int(0x0f0f0f0f)))\n py.assign(py.bitAnd(int(0x0f0f0f0f)))\n px.assign(px.bitOr(px.shiftRight(int(4))))\n py.assign(py.bitOr(py.shiftRight(int(4))))\n px.assign(px.bitAnd(int(0x00ff00ff)))\n py.assign(py.bitAnd(int(0x00ff00ff)))\n px.assign(px.bitOr(px.shiftRight(int(8))))\n py.assign(py.bitOr(py.shiftRight(int(8))))\n px.assign(px.bitAnd(int(0x0000ffff)))\n py.assign(py.bitAnd(int(0x0000ffff)))\n return ivec2(px, py)\n})\n\nexport const atlas = Fn(([p]: [VarNode<'ivec3'>]) => {\n return m2uv(xyz2m(p))\n})\n"],"mappings":"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","names":["index_exports","__export","Voxel","atlas","index_default","m2uv","xyz2m","__toCommonJS","THREE","import_tsl","import_src","import_tsl","xyz2m","xyz","x","y","z","m2uv","morton","px","py","atlas","p","_vec2","_vec3","_mat4","_shift","driveFromVoxel","cam","camera","cx","cz","renderer","size","driveFromThree","k","createAtlasTex","slot","createVec3","createGeometry","createMaterial","atlasTex","offsetNode","_pos","_scl","_aid","pick","id","uvPix","diffuse","n","position","center","vAid","vDiff","vCenter","color","p","uv","atlas","rgb","mat","Voxel","params","controls","dstTexture","__publicField","createVoxel","_scene","voxel","_isThree","_texture","updates","updated","count","overflow","_node","array","at","offset","geometry","pos","scl","aid","index_default"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\nimport { attribute, float, Fn, int, ivec3, normalLocal, positionGeometry, positionLocal, textureLoad, uniformArray, varying, vec3, vec4 } from 'three/tsl'\nimport createVoxel from 'voxelized-js/src'\nimport { atlas } from './utils'\nimport type { Camera, CanvasTexture, DataArrayTexture, Object3D, Renderer, Scene, UniformArrayNode, VarNode, Vector3 } from 'three/webgpu'\n\nexport * from './utils'\n\ntype Req = Parameters<typeof createVoxel>[0]\ntype Res = ReturnType<typeof createVoxel>\ntype Cam = Res['cam']\n\ntype BaseRenderer = Parameters<Object3D['onBeforeRender']>[0]\n\nconst _vec2 = new THREE.Vector2()\nconst _vec3 = new THREE.Vector3()\nconst _mat4 = new THREE.Matrix4()\nconst _shift = new THREE.Matrix4()\n\nconst driveFromVoxel = (cam: Cam, camera: Camera, cx: number, cz: number, renderer: Renderer | BaseRenderer) => {\n const size = renderer.getSize(_vec2)\n cam.update(size.x / size.y)\n camera.position.set(cam.pos[0] - cx, cam.pos[1], cam.pos[2] - cz)\n _vec3.set(cam.eye[0] - cx, cam.eye[1], cam.eye[2] - cz)\n camera.lookAt(_vec3)\n camera.updateMatrixWorld()\n // @ts-ignore\n camera.updateProjectionMatrix()\n}\n\nconst driveFromThree = (cam: Cam, camera: Camera, cx: number, cz: number) => {\n _mat4.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n _shift.makeTranslation(-cx, 0, -cz)\n _mat4.multiply(_shift)\n for (let k = 0; k < 16; k++) cam.mvp[k] = _mat4.elements[k]\n cam.pos[0] = camera.position.x + cx\n cam.pos[1] = camera.position.y\n cam.pos[2] = camera.position.z + cz\n}\n\nconst createVec3 = () => new THREE.Vector3()\nconst createGeometry = () => new THREE.BoxGeometry()\nconst createMaterial = (atlasTex: DataArrayTexture, offsetNode: UniformArrayNode<'vec3'>) => {\n const _pos = attribute<'vec3'>('pos', 'vec3')\n const _scl = attribute<'vec3'>('scl', 'vec3')\n const _aid = attribute<'float'>('aid', 'float')\n const pick = Fn(([id, uvPix]: [VarNode<'float'>, VarNode<'ivec2'>]) => {\n return textureLoad(atlasTex, uvPix, int(0)).depth(id.toInt())\n })\n const diffuse = Fn(([n]: [VarNode<'vec3'>]) => {\n return vec3(-0.33, 0.77, 0.55).normalize().dot(n).mul(0.5).add(0.5)\n })\n const position = Fn(() => {\n const off = offsetNode.element(_aid.toInt())\n return off.add(_pos.add(positionLocal.mul(_scl)))\n })\n const center = Fn(() => {\n const local = _pos.add(positionGeometry.mul(_scl))\n return local.sub(normalLocal.sign().mul(float(0.5))).floor()\n })\n const vAid = varying(_aid, 'vAid')\n const vDiff = varying(diffuse(normalLocal), 'vDiff')\n const vCenter = varying(center(), 'vCenter')\n const color = Fn(() => {\n const p = ivec3(vCenter)\n const uv = atlas(p).toVar('uv')\n const rgb = pick(vAid, uv).rgb.mul(vDiff).toVar('rgb')\n return vec4(rgb, 1)\n })\n const mat = new THREE.MeshBasicNodeMaterial({ side: THREE.FrontSide })\n mat.positionNode = position()\n mat.colorNode = color()\n return mat\n}\n\nconst createDstTexture = (slot = 16) => {\n const t = new THREE.DataArrayTexture(null, 4096, 4096, slot)\n t.wrapS = THREE.ClampToEdgeWrapping\n t.wrapT = THREE.ClampToEdgeWrapping\n t.magFilter = THREE.NearestFilter\n t.minFilter = THREE.NearestFilter\n t.colorSpace = THREE.SRGBColorSpace\n t.needsUpdate = true\n t.generateMipmaps = false\n t.source.dataReady = false\n return t\n}\n\nconst createSrcTexture = (el: HTMLCanvasElement) => {\n const t = new THREE.CanvasTexture(el)\n t.magFilter = THREE.NearestFilter\n t.minFilter = THREE.NearestFilter\n t.flipY = false\n t.generateMipmaps = false\n return t\n}\n\nconst createCanvas = () => {\n const el = document.createElement('canvas')\n el.width = 4096\n el.height = 4096\n return el\n}\n\nexport class Voxel extends THREE.InstancedMesh {\n voxel: Res\n offsetNode: UniformArrayNode<'vec3'>\n dstTexture: DataArrayTexture\n private _context: CanvasRenderingContext2D\n private _texture: CanvasTexture\n private _isThree: boolean\n constructor(params: Req & { controls?: 'three' | 'voxel' }) {\n const { slot = 16, controls } = params\n const offsetNode = uniformArray<'vec3'>(Array.from({ length: slot }, createVec3), 'vec3')\n const dstTexture = createDstTexture(slot)\n super(createGeometry(), createMaterial(dstTexture, offsetNode), 1)\n const canvas = createCanvas()\n this._context = canvas.getContext('2d')!\n this._texture = createSrcTexture(canvas)\n this.offsetNode = offsetNode\n this.dstTexture = dstTexture\n this.frustumCulled = false\n this.voxel = createVoxel(params)\n this._isThree = controls !== 'voxel'\n this._setAttribute()\n }\n onBeforeRender(renderer: Renderer | BaseRenderer, _scene: Scene, camera: Camera) {\n const { dstTexture, offsetNode, voxel, _context, _isThree, _texture } = this\n const { cam, center, count, updated, updates, overflow } = voxel\n const [cx, cz] = center\n if (_isThree) driveFromThree(cam, camera, cx, cz)\n else driveFromVoxel(cam, camera, cx, cz, renderer)\n const _node = offsetNode as unknown as { array: Vector3[]; needsUpdate: boolean; srcTex: any }\n const array = _node.array\n updates(({ at, atlas, offset }) => {\n array[at].set(offset[0] - cx, offset[1], offset[2] - cz)\n _context.drawImage(atlas, 0, 0)\n _node.needsUpdate = true\n _texture.needsUpdate = true\n renderer.copyTextureToTexture(_texture, dstTexture, null, _vec3.set(0, 0, at))\n })\n if (!updated()) return\n if (overflow()) return this._setAttribute()\n const geometry = this.geometry\n geometry.getAttribute('pos').needsUpdate = true\n geometry.getAttribute('scl').needsUpdate = true\n geometry.getAttribute('aid').needsUpdate = true\n this.count = count()\n }\n private _setAttribute() {\n const { geometry, voxel } = this\n const { pos, scl, aid } = voxel\n geometry.setAttribute('pos', new THREE.InstancedBufferAttribute(pos(), 3))\n geometry.setAttribute('scl', new THREE.InstancedBufferAttribute(scl(), 3))\n geometry.setAttribute('aid', new THREE.InstancedBufferAttribute(aid(), 1))\n }\n}\n\nexport default Voxel\n","import { Fn, int, ivec2 } from 'three/tsl'\nimport type { VarNode } from 'three/webgpu'\n\nexport const xyz2m = Fn(([xyz]: [VarNode<'ivec3'>]) => {\n const x = xyz.x.toVar()\n const y = xyz.y.toVar()\n const z = xyz.z.toVar()\n x.assign(x.bitOr(x.shiftLeft(int(16))))\n y.assign(y.bitOr(y.shiftLeft(int(16))))\n z.assign(z.bitOr(z.shiftLeft(int(16))))\n x.assign(x.bitAnd(int(0xff0000ff | 0)))\n y.assign(y.bitAnd(int(0xff0000ff | 0)))\n z.assign(z.bitAnd(int(0xff0000ff | 0)))\n x.assign(x.bitOr(x.shiftLeft(int(8))))\n y.assign(y.bitOr(y.shiftLeft(int(8))))\n z.assign(z.bitOr(z.shiftLeft(int(8))))\n x.assign(x.bitAnd(int(0x0300f00f)))\n y.assign(y.bitAnd(int(0x0300f00f)))\n z.assign(z.bitAnd(int(0x0300f00f)))\n x.assign(x.bitOr(x.shiftLeft(int(4))))\n y.assign(y.bitOr(y.shiftLeft(int(4))))\n z.assign(z.bitOr(z.shiftLeft(int(4))))\n x.assign(x.bitAnd(int(0x030c30c3)))\n y.assign(y.bitAnd(int(0x030c30c3)))\n z.assign(z.bitAnd(int(0x030c30c3)))\n x.assign(x.bitOr(x.shiftLeft(int(2))))\n y.assign(y.bitOr(y.shiftLeft(int(2))))\n z.assign(z.bitOr(z.shiftLeft(int(2))))\n x.assign(x.bitAnd(int(0x09249249)))\n y.assign(y.bitAnd(int(0x09249249)))\n z.assign(z.bitAnd(int(0x09249249)))\n return x.bitOr(y.shiftLeft(int(1))).bitOr(z.shiftLeft(int(2)))\n})\n\nexport const m2uv = Fn(([morton]: [VarNode<'int'>]) => {\n const px = morton.toVar()\n const py = morton.shiftRight(int(1)).toVar()\n px.assign(px.bitAnd(int(0x55555555)))\n py.assign(py.bitAnd(int(0x55555555)))\n px.assign(px.bitOr(px.shiftRight(int(1))))\n py.assign(py.bitOr(py.shiftRight(int(1))))\n px.assign(px.bitAnd(int(0x33333333)))\n py.assign(py.bitAnd(int(0x33333333)))\n px.assign(px.bitOr(px.shiftRight(int(2))))\n py.assign(py.bitOr(py.shiftRight(int(2))))\n px.assign(px.bitAnd(int(0x0f0f0f0f)))\n py.assign(py.bitAnd(int(0x0f0f0f0f)))\n px.assign(px.bitOr(px.shiftRight(int(4))))\n py.assign(py.bitOr(py.shiftRight(int(4))))\n px.assign(px.bitAnd(int(0x00ff00ff)))\n py.assign(py.bitAnd(int(0x00ff00ff)))\n px.assign(px.bitOr(px.shiftRight(int(8))))\n py.assign(py.bitOr(py.shiftRight(int(8))))\n px.assign(px.bitAnd(int(0x0000ffff)))\n py.assign(py.bitAnd(int(0x0000ffff)))\n return ivec2(px, py)\n})\n\nexport const atlas = Fn(([p]: [VarNode<'ivec3'>]) => {\n return m2uv(xyz2m(p))\n})\n"],"mappings":"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","names":["index_exports","__export","Voxel","atlas","index_default","m2uv","xyz2m","__toCommonJS","THREE","import_tsl","import_src","import_tsl","xyz2m","xyz","x","y","z","m2uv","morton","px","py","atlas","p","_vec2","_vec3","_mat4","_shift","driveFromVoxel","cam","camera","cx","cz","renderer","size","driveFromThree","k","createVec3","createGeometry","createMaterial","atlasTex","offsetNode","_pos","_scl","_aid","pick","id","uvPix","diffuse","n","position","center","vAid","vDiff","vCenter","color","p","uv","atlas","rgb","mat","createDstTexture","slot","createSrcTexture","el","createCanvas","Voxel","params","controls","dstTexture","__publicField","canvas","createVoxel","_scene","voxel","_context","_isThree","_texture","count","updated","updates","overflow","_node","array","at","offset","geometry","pos","scl","aid","index_default"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- var F=Object.defineProperty;var S=(i,t,e)=>t in i?F(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var d=(i,t,e)=>S(i,typeof t!="symbol"?t+"":t,e);import*as n from"three/webgpu";import{attribute as O,float as z,Fn as b,int as G,ivec3 as P,normalLocal as M,positionGeometry as W,positionLocal as q,textureLoad as Y,uniformArray as J,varying as V,vec3 as K,vec4 as Q}from"three/tsl";import X from"voxelized-js/src";import{Fn as E,int as s,ivec2 as I}from"three/tsl";var k=E(([i])=>{let t=i.x.toVar(),e=i.y.toVar(),r=i.z.toVar();return t.assign(t.bitOr(t.shiftLeft(s(16)))),e.assign(e.bitOr(e.shiftLeft(s(16)))),r.assign(r.bitOr(r.shiftLeft(s(16)))),t.assign(t.bitAnd(s(-16776961))),e.assign(e.bitAnd(s(-16776961))),r.assign(r.bitAnd(s(-16776961))),t.assign(t.bitOr(t.shiftLeft(s(8)))),e.assign(e.bitOr(e.shiftLeft(s(8)))),r.assign(r.bitOr(r.shiftLeft(s(8)))),t.assign(t.bitAnd(s(50393103))),e.assign(e.bitAnd(s(50393103))),r.assign(r.bitAnd(s(50393103))),t.assign(t.bitOr(t.shiftLeft(s(4)))),e.assign(e.bitOr(e.shiftLeft(s(4)))),r.assign(r.bitOr(r.shiftLeft(s(4)))),t.assign(t.bitAnd(s(51130563))),e.assign(e.bitAnd(s(51130563))),r.assign(r.bitAnd(s(51130563))),t.assign(t.bitOr(t.shiftLeft(s(2)))),e.assign(e.bitOr(e.shiftLeft(s(2)))),r.assign(r.bitOr(r.shiftLeft(s(2)))),t.assign(t.bitAnd(s(153391689))),e.assign(e.bitAnd(s(153391689))),r.assign(r.bitAnd(s(153391689))),t.bitOr(e.shiftLeft(s(1))).bitOr(r.shiftLeft(s(2)))}),j=E(([i])=>{let t=i.toVar(),e=i.shiftRight(s(1)).toVar();return t.assign(t.bitAnd(s(1431655765))),e.assign(e.bitAnd(s(1431655765))),t.assign(t.bitOr(t.shiftRight(s(1)))),e.assign(e.bitOr(e.shiftRight(s(1)))),t.assign(t.bitAnd(s(858993459))),e.assign(e.bitAnd(s(858993459))),t.assign(t.bitOr(t.shiftRight(s(2)))),e.assign(e.bitOr(e.shiftRight(s(2)))),t.assign(t.bitAnd(s(252645135))),e.assign(e.bitAnd(s(252645135))),t.assign(t.bitOr(t.shiftRight(s(4)))),e.assign(e.bitOr(e.shiftRight(s(4)))),t.assign(t.bitAnd(s(16711935))),e.assign(e.bitAnd(s(16711935))),t.assign(t.bitOr(t.shiftRight(s(8)))),e.assign(e.bitOr(e.shiftRight(s(8)))),t.assign(t.bitAnd(s(65535))),e.assign(e.bitAnd(s(65535))),I(t,e)}),C=E(([i])=>j(k(i)));var Z=new n.Vector2,N=new n.Vector3,_=new n.Matrix4,B=new n.Matrix4,$=(i,t,e,r,o)=>{let a=o.getSize(Z);i.update(a.x/a.y),t.position.set(i.pos[0]-e,i.pos[1],i.pos[2]-r),N.set(i.eye[0]-e,i.eye[1],i.eye[2]-r),t.lookAt(N),t.updateMatrixWorld(),t.updateProjectionMatrix()},tt=(i,t,e,r)=>{_.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),B.makeTranslation(-e,0,-r),_.multiply(B);for(let o=0;o<16;o++)i.mvp[o]=_.elements[o];i.pos[0]=t.position.x+e,i.pos[1]=t.position.y,i.pos[2]=t.position.z+r},et=(i=16)=>{let t=new n.DataArrayTexture(null,4096,4096,i);return t.minFilter=t.magFilter=n.NearestFilter,t.wrapS=t.wrapT=n.ClampToEdgeWrapping,t.generateMipmaps=!1,t.needsUpdate=!0,t.source.dataReady=!1,t.colorSpace=n.SRGBColorSpace,t},st=()=>new n.Vector3,rt=()=>new n.BoxGeometry,it=(i,t)=>{let e=O("pos","vec3"),r=O("scl","vec3"),o=O("aid","float"),a=b(([f,l])=>Y(i,l,G(0)).depth(f.toInt())),c=b(([f])=>K(-.33,.77,.55).normalize().dot(f).mul(.5).add(.5)),h=b(()=>t.element(o.toInt()).add(e.add(q.mul(r)))),m=b(()=>e.add(W.mul(r)).sub(M.sign().mul(z(.5))).floor()),u=V(o,"vAid"),A=V(c(M),"vDiff"),x=V(m(),"vCenter"),R=b(()=>{let f=P(x),l=C(f).toVar("uv"),g=a(u,l).rgb.mul(A).toVar("rgb");return Q(g,1)}),p=new n.MeshBasicNodeMaterial({side:n.FrontSide});return p.positionNode=h(),p.colorNode=R(),p},w=class extends n.InstancedMesh{constructor(e){let{slot:r=16,controls:o}=e,a=J(Array.from({length:r},st),"vec3"),c=et(r);super(rt(),it(c,a),1);d(this,"voxel");d(this,"offsetNode");d(this,"dstTexture");d(this,"_texture");d(this,"_isThree");this.offsetNode=a,this.dstTexture=c,this.frustumCulled=!1,this.voxel=X(e),this._texture=new n.Texture,this._texture.flipY=this._texture.generateMipmaps=!1,this._isThree=o!=="voxel",this._setAttribute()}onBeforeRender(e,r,o){let{dstTexture:a,offsetNode:c,voxel:h,_isThree:m,_texture:u}=this,{center:A,cam:x,updates:R,updated:p,count:f,overflow:l}=h,[g,v]=A;m?tt(x,o,g,v):$(x,o,g,v,e);let H=c,U=H.array;if(R(({at:L,atlas:D,offset:y})=>{U[L].set(y[0]-g,y[1],y[2]-v),u.image=D,u.needsUpdate=H.needsUpdate=!0,e.copyTextureToTexture(u,a,null,N.set(0,0,L))}),!p())return;if(l())return this._setAttribute();let T=this.geometry;T.getAttribute("pos").needsUpdate=!0,T.getAttribute("scl").needsUpdate=!0,T.getAttribute("aid").needsUpdate=!0,this.count=f()}_setAttribute(){let{geometry:e,voxel:r}=this,{pos:o,scl:a,aid:c}=r;e.setAttribute("pos",new n.InstancedBufferAttribute(o(),3)),e.setAttribute("scl",new n.InstancedBufferAttribute(a(),3)),e.setAttribute("aid",new n.InstancedBufferAttribute(c(),1))}},ut=w;export{w as Voxel,C as atlas,ut as default,j as m2uv,k as xyz2m};
1
+ var S=Object.defineProperty;var I=(r,t,e)=>t in r?S(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var d=(r,t,e)=>I(r,typeof t!="symbol"?t+"":t,e);import*as i from"three/webgpu";import{attribute as V,float as G,Fn as g,int as W,ivec3 as P,normalLocal as M,positionGeometry as q,positionLocal as Y,textureLoad as J,uniformArray as K,varying as H,vec3 as Q,vec4 as X}from"three/tsl";import Z from"voxelized-js/src";import{Fn as O,int as s,ivec2 as k}from"three/tsl";var j=O(([r])=>{let t=r.x.toVar(),e=r.y.toVar(),n=r.z.toVar();return t.assign(t.bitOr(t.shiftLeft(s(16)))),e.assign(e.bitOr(e.shiftLeft(s(16)))),n.assign(n.bitOr(n.shiftLeft(s(16)))),t.assign(t.bitAnd(s(-16776961))),e.assign(e.bitAnd(s(-16776961))),n.assign(n.bitAnd(s(-16776961))),t.assign(t.bitOr(t.shiftLeft(s(8)))),e.assign(e.bitOr(e.shiftLeft(s(8)))),n.assign(n.bitOr(n.shiftLeft(s(8)))),t.assign(t.bitAnd(s(50393103))),e.assign(e.bitAnd(s(50393103))),n.assign(n.bitAnd(s(50393103))),t.assign(t.bitOr(t.shiftLeft(s(4)))),e.assign(e.bitOr(e.shiftLeft(s(4)))),n.assign(n.bitOr(n.shiftLeft(s(4)))),t.assign(t.bitAnd(s(51130563))),e.assign(e.bitAnd(s(51130563))),n.assign(n.bitAnd(s(51130563))),t.assign(t.bitOr(t.shiftLeft(s(2)))),e.assign(e.bitOr(e.shiftLeft(s(2)))),n.assign(n.bitOr(n.shiftLeft(s(2)))),t.assign(t.bitAnd(s(153391689))),e.assign(e.bitAnd(s(153391689))),n.assign(n.bitAnd(s(153391689))),t.bitOr(e.shiftLeft(s(1))).bitOr(n.shiftLeft(s(2)))}),z=O(([r])=>{let t=r.toVar(),e=r.shiftRight(s(1)).toVar();return t.assign(t.bitAnd(s(1431655765))),e.assign(e.bitAnd(s(1431655765))),t.assign(t.bitOr(t.shiftRight(s(1)))),e.assign(e.bitOr(e.shiftRight(s(1)))),t.assign(t.bitAnd(s(858993459))),e.assign(e.bitAnd(s(858993459))),t.assign(t.bitOr(t.shiftRight(s(2)))),e.assign(e.bitOr(e.shiftRight(s(2)))),t.assign(t.bitAnd(s(252645135))),e.assign(e.bitAnd(s(252645135))),t.assign(t.bitOr(t.shiftRight(s(4)))),e.assign(e.bitOr(e.shiftRight(s(4)))),t.assign(t.bitAnd(s(16711935))),e.assign(e.bitAnd(s(16711935))),t.assign(t.bitOr(t.shiftRight(s(8)))),e.assign(e.bitOr(e.shiftRight(s(8)))),t.assign(t.bitAnd(s(65535))),e.assign(e.bitAnd(s(65535))),k(t,e)}),F=O(([r])=>z(j(r)));var $=new i.Vector2,C=new i.Vector3,N=new i.Matrix4,B=new i.Matrix4,tt=(r,t,e,n,o)=>{let a=o.getSize($);r.update(a.x/a.y),t.position.set(r.pos[0]-e,r.pos[1],r.pos[2]-n),C.set(r.eye[0]-e,r.eye[1],r.eye[2]-n),t.lookAt(C),t.updateMatrixWorld(),t.updateProjectionMatrix()},et=(r,t,e,n)=>{N.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),B.makeTranslation(-e,0,-n),N.multiply(B);for(let o=0;o<16;o++)r.mvp[o]=N.elements[o];r.pos[0]=t.position.x+e,r.pos[1]=t.position.y,r.pos[2]=t.position.z+n},st=()=>new i.Vector3,rt=()=>new i.BoxGeometry,nt=(r,t)=>{let e=V("pos","vec3"),n=V("scl","vec3"),o=V("aid","float"),a=g(([f,p])=>J(r,p,W(0)).depth(f.toInt())),c=g(([f])=>Q(-.33,.77,.55).normalize().dot(f).mul(.5).add(.5)),u=g(()=>t.element(o.toInt()).add(e.add(Y.mul(n)))),h=g(()=>e.add(q.mul(n)).sub(M.sign().mul(G(.5))).floor()),m=H(o,"vAid"),x=H(c(M),"vDiff"),b=H(h(),"vCenter"),v=g(()=>{let f=P(b),p=F(f).toVar("uv"),T=a(m,p).rgb.mul(x).toVar("rgb");return X(T,1)}),l=new i.MeshBasicNodeMaterial({side:i.FrontSide});return l.positionNode=u(),l.colorNode=v(),l},it=(r=16)=>{let t=new i.DataArrayTexture(null,4096,4096,r);return t.wrapS=i.ClampToEdgeWrapping,t.wrapT=i.ClampToEdgeWrapping,t.magFilter=i.NearestFilter,t.minFilter=i.NearestFilter,t.colorSpace=i.SRGBColorSpace,t.needsUpdate=!0,t.generateMipmaps=!1,t.source.dataReady=!1,t},ot=r=>{let t=new i.CanvasTexture(r);return t.magFilter=i.NearestFilter,t.minFilter=i.NearestFilter,t.flipY=!1,t.generateMipmaps=!1,t},at=()=>{let r=document.createElement("canvas");return r.width=4096,r.height=4096,r},_=class extends i.InstancedMesh{constructor(e){let{slot:n=16,controls:o}=e,a=K(Array.from({length:n},st),"vec3"),c=it(n);super(rt(),nt(c,a),1);d(this,"voxel");d(this,"offsetNode");d(this,"dstTexture");d(this,"_context");d(this,"_texture");d(this,"_isThree");let u=at();this._context=u.getContext("2d"),this._texture=ot(u),this.offsetNode=a,this.dstTexture=c,this.frustumCulled=!1,this.voxel=Z(e),this._isThree=o!=="voxel",this._setAttribute()}onBeforeRender(e,n,o){let{dstTexture:a,offsetNode:c,voxel:u,_context:h,_isThree:m,_texture:x}=this,{cam:b,center:v,count:l,updated:f,updates:p,overflow:T}=u,[E,R]=v;m?et(b,o,E,R):tt(b,o,E,R,e);let w=c,D=w.array;if(p(({at:L,atlas:U,offset:y})=>{D[L].set(y[0]-E,y[1],y[2]-R),h.drawImage(U,0,0),w.needsUpdate=!0,x.needsUpdate=!0,e.copyTextureToTexture(x,a,null,C.set(0,0,L))}),!f())return;if(T())return this._setAttribute();let A=this.geometry;A.getAttribute("pos").needsUpdate=!0,A.getAttribute("scl").needsUpdate=!0,A.getAttribute("aid").needsUpdate=!0,this.count=l()}_setAttribute(){let{geometry:e,voxel:n}=this,{pos:o,scl:a,aid:c}=n;e.setAttribute("pos",new i.InstancedBufferAttribute(o(),3)),e.setAttribute("scl",new i.InstancedBufferAttribute(a(),3)),e.setAttribute("aid",new i.InstancedBufferAttribute(c(),1))}},gt=_;export{_ as Voxel,F as atlas,gt as default,z as m2uv,j as xyz2m};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\nimport { attribute, float, Fn, int, ivec3, normalLocal, positionGeometry, positionLocal, textureLoad, uniformArray, varying, vec3, vec4 } from 'three/tsl'\nimport createVoxel from 'voxelized-js/src'\nimport { atlas } from './utils'\nimport type { Camera, DataArrayTexture, Object3D, Renderer, Scene, Texture, UniformArrayNode, VarNode, Vector3 } from 'three/webgpu'\n\nexport * from './utils'\n\ntype Req = Parameters<typeof createVoxel>[0]\ntype Res = ReturnType<typeof createVoxel>\ntype Cam = Res['cam']\n\ntype BaseRenderer = Parameters<Object3D['onBeforeRender']>[0]\n\nconst _vec2 = new THREE.Vector2()\nconst _vec3 = new THREE.Vector3()\nconst _mat4 = new THREE.Matrix4()\nconst _shift = new THREE.Matrix4()\n\nconst driveFromVoxel = (cam: Cam, camera: Camera, cx: number, cz: number, renderer: Renderer | BaseRenderer) => {\n const size = renderer.getSize(_vec2)\n cam.update(size.x / size.y)\n camera.position.set(cam.pos[0] - cx, cam.pos[1], cam.pos[2] - cz)\n _vec3.set(cam.eye[0] - cx, cam.eye[1], cam.eye[2] - cz)\n camera.lookAt(_vec3)\n camera.updateMatrixWorld()\n // @ts-ignore\n camera.updateProjectionMatrix()\n}\n\nconst driveFromThree = (cam: Cam, camera: Camera, cx: number, cz: number) => {\n _mat4.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n _shift.makeTranslation(-cx, 0, -cz)\n _mat4.multiply(_shift)\n for (let k = 0; k < 16; k++) cam.mvp[k] = _mat4.elements[k]\n cam.pos[0] = camera.position.x + cx\n cam.pos[1] = camera.position.y\n cam.pos[2] = camera.position.z + cz\n}\n\nconst createAtlasTex = (slot = 16) => {\n const t = new THREE.DataArrayTexture(null, 4096, 4096, slot)\n t.minFilter = t.magFilter = THREE.NearestFilter\n t.wrapS = t.wrapT = THREE.ClampToEdgeWrapping\n t.generateMipmaps = false\n t.needsUpdate = true\n t.source.dataReady = false\n t.colorSpace = THREE.SRGBColorSpace\n return t\n}\n\nconst createVec3 = () => new THREE.Vector3()\nconst createGeometry = () => new THREE.BoxGeometry()\nconst createMaterial = (atlasTex: DataArrayTexture, offsetNode: UniformArrayNode<'vec3'>) => {\n const _pos = attribute<'vec3'>('pos', 'vec3')\n const _scl = attribute<'vec3'>('scl', 'vec3')\n const _aid = attribute<'float'>('aid', 'float')\n const pick = Fn(([id, uvPix]: [VarNode<'float'>, VarNode<'ivec2'>]) => {\n return textureLoad(atlasTex, uvPix, int(0)).depth(id.toInt())\n })\n const diffuse = Fn(([n]: [VarNode<'vec3'>]) => {\n return vec3(-0.33, 0.77, 0.55).normalize().dot(n).mul(0.5).add(0.5)\n })\n const position = Fn(() => {\n const off = offsetNode.element(_aid.toInt())\n return off.add(_pos.add(positionLocal.mul(_scl)))\n })\n const center = Fn(() => {\n const local = _pos.add(positionGeometry.mul(_scl))\n return local.sub(normalLocal.sign().mul(float(0.5))).floor()\n })\n const vAid = varying(_aid, 'vAid')\n const vDiff = varying(diffuse(normalLocal), 'vDiff')\n const vCenter = varying(center(), 'vCenter')\n const color = Fn(() => {\n const p = ivec3(vCenter)\n const uv = atlas(p).toVar('uv')\n const rgb = pick(vAid, uv).rgb.mul(vDiff).toVar('rgb')\n return vec4(rgb, 1)\n })\n const mat = new THREE.MeshBasicNodeMaterial({ side: THREE.FrontSide })\n mat.positionNode = position()\n mat.colorNode = color()\n return mat\n}\n\nexport class Voxel extends THREE.InstancedMesh {\n voxel: Res\n offsetNode: UniformArrayNode<'vec3'>\n dstTexture: DataArrayTexture\n private _texture: Texture\n private _isThree: boolean\n constructor(params: Req & { controls?: 'three' | 'voxel' }) {\n const { slot = 16, controls } = params\n const offsetNode = uniformArray<'vec3'>(Array.from({ length: slot }, createVec3), 'vec3')\n const dstTexture = createAtlasTex(slot)\n super(createGeometry(), createMaterial(dstTexture, offsetNode), 1)\n this.offsetNode = offsetNode\n this.dstTexture = dstTexture\n this.frustumCulled = false\n this.voxel = createVoxel(params)\n this._texture = new THREE.Texture()\n this._texture.flipY = this._texture.generateMipmaps = false\n this._isThree = controls !== 'voxel'\n this._setAttribute()\n }\n onBeforeRender(renderer: Renderer | BaseRenderer, _scene: Scene, camera: Camera) {\n const { dstTexture, offsetNode, voxel, _isThree, _texture } = this\n const { center, cam, updates, updated, count, overflow } = voxel\n const [cx, cz] = center\n if (_isThree) driveFromThree(cam, camera, cx, cz)\n else driveFromVoxel(cam, camera, cx, cz, renderer)\n const _node = offsetNode as unknown as { array: Vector3[]; needsUpdate: boolean }\n const array = _node.array\n updates(({ at, atlas, offset }) => {\n array[at].set(offset[0] - cx, offset[1], offset[2] - cz)\n _texture.image = atlas\n _texture.needsUpdate = _node.needsUpdate = true\n renderer.copyTextureToTexture(_texture, dstTexture, null, _vec3.set(0, 0, at))\n })\n if (!updated()) return\n if (overflow()) return this._setAttribute()\n const geometry = this.geometry\n geometry.getAttribute('pos').needsUpdate = true\n geometry.getAttribute('scl').needsUpdate = true\n geometry.getAttribute('aid').needsUpdate = true\n this.count = count()\n }\n private _setAttribute() {\n const { geometry, voxel } = this\n const { pos, scl, aid } = voxel\n geometry.setAttribute('pos', new THREE.InstancedBufferAttribute(pos(), 3))\n geometry.setAttribute('scl', new THREE.InstancedBufferAttribute(scl(), 3))\n geometry.setAttribute('aid', new THREE.InstancedBufferAttribute(aid(), 1))\n }\n}\n\nexport default Voxel\n","import { Fn, int, ivec2 } from 'three/tsl'\nimport type { VarNode } from 'three/webgpu'\n\nexport const xyz2m = Fn(([xyz]: [VarNode<'ivec3'>]) => {\n const x = xyz.x.toVar()\n const y = xyz.y.toVar()\n const z = xyz.z.toVar()\n x.assign(x.bitOr(x.shiftLeft(int(16))))\n y.assign(y.bitOr(y.shiftLeft(int(16))))\n z.assign(z.bitOr(z.shiftLeft(int(16))))\n x.assign(x.bitAnd(int(0xff0000ff | 0)))\n y.assign(y.bitAnd(int(0xff0000ff | 0)))\n z.assign(z.bitAnd(int(0xff0000ff | 0)))\n x.assign(x.bitOr(x.shiftLeft(int(8))))\n y.assign(y.bitOr(y.shiftLeft(int(8))))\n z.assign(z.bitOr(z.shiftLeft(int(8))))\n x.assign(x.bitAnd(int(0x0300f00f)))\n y.assign(y.bitAnd(int(0x0300f00f)))\n z.assign(z.bitAnd(int(0x0300f00f)))\n x.assign(x.bitOr(x.shiftLeft(int(4))))\n y.assign(y.bitOr(y.shiftLeft(int(4))))\n z.assign(z.bitOr(z.shiftLeft(int(4))))\n x.assign(x.bitAnd(int(0x030c30c3)))\n y.assign(y.bitAnd(int(0x030c30c3)))\n z.assign(z.bitAnd(int(0x030c30c3)))\n x.assign(x.bitOr(x.shiftLeft(int(2))))\n y.assign(y.bitOr(y.shiftLeft(int(2))))\n z.assign(z.bitOr(z.shiftLeft(int(2))))\n x.assign(x.bitAnd(int(0x09249249)))\n y.assign(y.bitAnd(int(0x09249249)))\n z.assign(z.bitAnd(int(0x09249249)))\n return x.bitOr(y.shiftLeft(int(1))).bitOr(z.shiftLeft(int(2)))\n})\n\nexport const m2uv = Fn(([morton]: [VarNode<'int'>]) => {\n const px = morton.toVar()\n const py = morton.shiftRight(int(1)).toVar()\n px.assign(px.bitAnd(int(0x55555555)))\n py.assign(py.bitAnd(int(0x55555555)))\n px.assign(px.bitOr(px.shiftRight(int(1))))\n py.assign(py.bitOr(py.shiftRight(int(1))))\n px.assign(px.bitAnd(int(0x33333333)))\n py.assign(py.bitAnd(int(0x33333333)))\n px.assign(px.bitOr(px.shiftRight(int(2))))\n py.assign(py.bitOr(py.shiftRight(int(2))))\n px.assign(px.bitAnd(int(0x0f0f0f0f)))\n py.assign(py.bitAnd(int(0x0f0f0f0f)))\n px.assign(px.bitOr(px.shiftRight(int(4))))\n py.assign(py.bitOr(py.shiftRight(int(4))))\n px.assign(px.bitAnd(int(0x00ff00ff)))\n py.assign(py.bitAnd(int(0x00ff00ff)))\n px.assign(px.bitOr(px.shiftRight(int(8))))\n py.assign(py.bitOr(py.shiftRight(int(8))))\n px.assign(px.bitAnd(int(0x0000ffff)))\n py.assign(py.bitAnd(int(0x0000ffff)))\n return ivec2(px, py)\n})\n\nexport const atlas = Fn(([p]: [VarNode<'ivec3'>]) => {\n return m2uv(xyz2m(p))\n})\n"],"mappings":"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","names":["THREE","attribute","float","Fn","int","ivec3","normalLocal","positionGeometry","positionLocal","textureLoad","uniformArray","varying","vec3","vec4","createVoxel","Fn","int","ivec2","xyz2m","xyz","x","y","z","m2uv","morton","px","py","atlas","p","_vec2","_vec3","_mat4","_shift","driveFromVoxel","cam","camera","cx","cz","renderer","size","driveFromThree","k","createAtlasTex","slot","createVec3","createGeometry","createMaterial","atlasTex","offsetNode","_pos","attribute","_scl","_aid","pick","Fn","id","uvPix","textureLoad","int","diffuse","n","vec3","position","positionLocal","center","positionGeometry","normalLocal","float","vAid","varying","vDiff","vCenter","color","p","ivec3","uv","atlas","rgb","vec4","mat","Voxel","params","controls","uniformArray","dstTexture","__publicField","createVoxel","_scene","voxel","_isThree","_texture","updates","updated","count","overflow","_node","array","at","offset","geometry","pos","scl","aid","index_default"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\nimport { attribute, float, Fn, int, ivec3, normalLocal, positionGeometry, positionLocal, textureLoad, uniformArray, varying, vec3, vec4 } from 'three/tsl'\nimport createVoxel from 'voxelized-js/src'\nimport { atlas } from './utils'\nimport type { Camera, CanvasTexture, DataArrayTexture, Object3D, Renderer, Scene, UniformArrayNode, VarNode, Vector3 } from 'three/webgpu'\n\nexport * from './utils'\n\ntype Req = Parameters<typeof createVoxel>[0]\ntype Res = ReturnType<typeof createVoxel>\ntype Cam = Res['cam']\n\ntype BaseRenderer = Parameters<Object3D['onBeforeRender']>[0]\n\nconst _vec2 = new THREE.Vector2()\nconst _vec3 = new THREE.Vector3()\nconst _mat4 = new THREE.Matrix4()\nconst _shift = new THREE.Matrix4()\n\nconst driveFromVoxel = (cam: Cam, camera: Camera, cx: number, cz: number, renderer: Renderer | BaseRenderer) => {\n const size = renderer.getSize(_vec2)\n cam.update(size.x / size.y)\n camera.position.set(cam.pos[0] - cx, cam.pos[1], cam.pos[2] - cz)\n _vec3.set(cam.eye[0] - cx, cam.eye[1], cam.eye[2] - cz)\n camera.lookAt(_vec3)\n camera.updateMatrixWorld()\n // @ts-ignore\n camera.updateProjectionMatrix()\n}\n\nconst driveFromThree = (cam: Cam, camera: Camera, cx: number, cz: number) => {\n _mat4.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n _shift.makeTranslation(-cx, 0, -cz)\n _mat4.multiply(_shift)\n for (let k = 0; k < 16; k++) cam.mvp[k] = _mat4.elements[k]\n cam.pos[0] = camera.position.x + cx\n cam.pos[1] = camera.position.y\n cam.pos[2] = camera.position.z + cz\n}\n\nconst createVec3 = () => new THREE.Vector3()\nconst createGeometry = () => new THREE.BoxGeometry()\nconst createMaterial = (atlasTex: DataArrayTexture, offsetNode: UniformArrayNode<'vec3'>) => {\n const _pos = attribute<'vec3'>('pos', 'vec3')\n const _scl = attribute<'vec3'>('scl', 'vec3')\n const _aid = attribute<'float'>('aid', 'float')\n const pick = Fn(([id, uvPix]: [VarNode<'float'>, VarNode<'ivec2'>]) => {\n return textureLoad(atlasTex, uvPix, int(0)).depth(id.toInt())\n })\n const diffuse = Fn(([n]: [VarNode<'vec3'>]) => {\n return vec3(-0.33, 0.77, 0.55).normalize().dot(n).mul(0.5).add(0.5)\n })\n const position = Fn(() => {\n const off = offsetNode.element(_aid.toInt())\n return off.add(_pos.add(positionLocal.mul(_scl)))\n })\n const center = Fn(() => {\n const local = _pos.add(positionGeometry.mul(_scl))\n return local.sub(normalLocal.sign().mul(float(0.5))).floor()\n })\n const vAid = varying(_aid, 'vAid')\n const vDiff = varying(diffuse(normalLocal), 'vDiff')\n const vCenter = varying(center(), 'vCenter')\n const color = Fn(() => {\n const p = ivec3(vCenter)\n const uv = atlas(p).toVar('uv')\n const rgb = pick(vAid, uv).rgb.mul(vDiff).toVar('rgb')\n return vec4(rgb, 1)\n })\n const mat = new THREE.MeshBasicNodeMaterial({ side: THREE.FrontSide })\n mat.positionNode = position()\n mat.colorNode = color()\n return mat\n}\n\nconst createDstTexture = (slot = 16) => {\n const t = new THREE.DataArrayTexture(null, 4096, 4096, slot)\n t.wrapS = THREE.ClampToEdgeWrapping\n t.wrapT = THREE.ClampToEdgeWrapping\n t.magFilter = THREE.NearestFilter\n t.minFilter = THREE.NearestFilter\n t.colorSpace = THREE.SRGBColorSpace\n t.needsUpdate = true\n t.generateMipmaps = false\n t.source.dataReady = false\n return t\n}\n\nconst createSrcTexture = (el: HTMLCanvasElement) => {\n const t = new THREE.CanvasTexture(el)\n t.magFilter = THREE.NearestFilter\n t.minFilter = THREE.NearestFilter\n t.flipY = false\n t.generateMipmaps = false\n return t\n}\n\nconst createCanvas = () => {\n const el = document.createElement('canvas')\n el.width = 4096\n el.height = 4096\n return el\n}\n\nexport class Voxel extends THREE.InstancedMesh {\n voxel: Res\n offsetNode: UniformArrayNode<'vec3'>\n dstTexture: DataArrayTexture\n private _context: CanvasRenderingContext2D\n private _texture: CanvasTexture\n private _isThree: boolean\n constructor(params: Req & { controls?: 'three' | 'voxel' }) {\n const { slot = 16, controls } = params\n const offsetNode = uniformArray<'vec3'>(Array.from({ length: slot }, createVec3), 'vec3')\n const dstTexture = createDstTexture(slot)\n super(createGeometry(), createMaterial(dstTexture, offsetNode), 1)\n const canvas = createCanvas()\n this._context = canvas.getContext('2d')!\n this._texture = createSrcTexture(canvas)\n this.offsetNode = offsetNode\n this.dstTexture = dstTexture\n this.frustumCulled = false\n this.voxel = createVoxel(params)\n this._isThree = controls !== 'voxel'\n this._setAttribute()\n }\n onBeforeRender(renderer: Renderer | BaseRenderer, _scene: Scene, camera: Camera) {\n const { dstTexture, offsetNode, voxel, _context, _isThree, _texture } = this\n const { cam, center, count, updated, updates, overflow } = voxel\n const [cx, cz] = center\n if (_isThree) driveFromThree(cam, camera, cx, cz)\n else driveFromVoxel(cam, camera, cx, cz, renderer)\n const _node = offsetNode as unknown as { array: Vector3[]; needsUpdate: boolean; srcTex: any }\n const array = _node.array\n updates(({ at, atlas, offset }) => {\n array[at].set(offset[0] - cx, offset[1], offset[2] - cz)\n _context.drawImage(atlas, 0, 0)\n _node.needsUpdate = true\n _texture.needsUpdate = true\n renderer.copyTextureToTexture(_texture, dstTexture, null, _vec3.set(0, 0, at))\n })\n if (!updated()) return\n if (overflow()) return this._setAttribute()\n const geometry = this.geometry\n geometry.getAttribute('pos').needsUpdate = true\n geometry.getAttribute('scl').needsUpdate = true\n geometry.getAttribute('aid').needsUpdate = true\n this.count = count()\n }\n private _setAttribute() {\n const { geometry, voxel } = this\n const { pos, scl, aid } = voxel\n geometry.setAttribute('pos', new THREE.InstancedBufferAttribute(pos(), 3))\n geometry.setAttribute('scl', new THREE.InstancedBufferAttribute(scl(), 3))\n geometry.setAttribute('aid', new THREE.InstancedBufferAttribute(aid(), 1))\n }\n}\n\nexport default Voxel\n","import { Fn, int, ivec2 } from 'three/tsl'\nimport type { VarNode } from 'three/webgpu'\n\nexport const xyz2m = Fn(([xyz]: [VarNode<'ivec3'>]) => {\n const x = xyz.x.toVar()\n const y = xyz.y.toVar()\n const z = xyz.z.toVar()\n x.assign(x.bitOr(x.shiftLeft(int(16))))\n y.assign(y.bitOr(y.shiftLeft(int(16))))\n z.assign(z.bitOr(z.shiftLeft(int(16))))\n x.assign(x.bitAnd(int(0xff0000ff | 0)))\n y.assign(y.bitAnd(int(0xff0000ff | 0)))\n z.assign(z.bitAnd(int(0xff0000ff | 0)))\n x.assign(x.bitOr(x.shiftLeft(int(8))))\n y.assign(y.bitOr(y.shiftLeft(int(8))))\n z.assign(z.bitOr(z.shiftLeft(int(8))))\n x.assign(x.bitAnd(int(0x0300f00f)))\n y.assign(y.bitAnd(int(0x0300f00f)))\n z.assign(z.bitAnd(int(0x0300f00f)))\n x.assign(x.bitOr(x.shiftLeft(int(4))))\n y.assign(y.bitOr(y.shiftLeft(int(4))))\n z.assign(z.bitOr(z.shiftLeft(int(4))))\n x.assign(x.bitAnd(int(0x030c30c3)))\n y.assign(y.bitAnd(int(0x030c30c3)))\n z.assign(z.bitAnd(int(0x030c30c3)))\n x.assign(x.bitOr(x.shiftLeft(int(2))))\n y.assign(y.bitOr(y.shiftLeft(int(2))))\n z.assign(z.bitOr(z.shiftLeft(int(2))))\n x.assign(x.bitAnd(int(0x09249249)))\n y.assign(y.bitAnd(int(0x09249249)))\n z.assign(z.bitAnd(int(0x09249249)))\n return x.bitOr(y.shiftLeft(int(1))).bitOr(z.shiftLeft(int(2)))\n})\n\nexport const m2uv = Fn(([morton]: [VarNode<'int'>]) => {\n const px = morton.toVar()\n const py = morton.shiftRight(int(1)).toVar()\n px.assign(px.bitAnd(int(0x55555555)))\n py.assign(py.bitAnd(int(0x55555555)))\n px.assign(px.bitOr(px.shiftRight(int(1))))\n py.assign(py.bitOr(py.shiftRight(int(1))))\n px.assign(px.bitAnd(int(0x33333333)))\n py.assign(py.bitAnd(int(0x33333333)))\n px.assign(px.bitOr(px.shiftRight(int(2))))\n py.assign(py.bitOr(py.shiftRight(int(2))))\n px.assign(px.bitAnd(int(0x0f0f0f0f)))\n py.assign(py.bitAnd(int(0x0f0f0f0f)))\n px.assign(px.bitOr(px.shiftRight(int(4))))\n py.assign(py.bitOr(py.shiftRight(int(4))))\n px.assign(px.bitAnd(int(0x00ff00ff)))\n py.assign(py.bitAnd(int(0x00ff00ff)))\n px.assign(px.bitOr(px.shiftRight(int(8))))\n py.assign(py.bitOr(py.shiftRight(int(8))))\n px.assign(px.bitAnd(int(0x0000ffff)))\n py.assign(py.bitAnd(int(0x0000ffff)))\n return ivec2(px, py)\n})\n\nexport const atlas = Fn(([p]: [VarNode<'ivec3'>]) => {\n return m2uv(xyz2m(p))\n})\n"],"mappings":"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","names":["THREE","attribute","float","Fn","int","ivec3","normalLocal","positionGeometry","positionLocal","textureLoad","uniformArray","varying","vec3","vec4","createVoxel","Fn","int","ivec2","xyz2m","xyz","x","y","z","m2uv","morton","px","py","atlas","p","_vec2","_vec3","_mat4","_shift","driveFromVoxel","cam","camera","cx","cz","renderer","size","driveFromThree","k","createVec3","createGeometry","createMaterial","atlasTex","offsetNode","_pos","attribute","_scl","_aid","pick","Fn","id","uvPix","textureLoad","int","diffuse","n","vec3","position","positionLocal","center","positionGeometry","normalLocal","float","vAid","varying","vDiff","vCenter","color","p","ivec3","uv","atlas","rgb","vec4","mat","createDstTexture","slot","createSrcTexture","el","createCanvas","Voxel","params","controls","uniformArray","dstTexture","__publicField","canvas","createVoxel","_scene","voxel","_context","_isThree","_texture","count","updated","updates","overflow","_node","array","at","offset","geometry","pos","scl","aid","index_default"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voxel-three",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "author": "tseijp",
5
5
  "license": "MIT",
6
6
  "private": false,
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@ import * as THREE from 'three/webgpu'
2
2
  import { attribute, float, Fn, int, ivec3, normalLocal, positionGeometry, positionLocal, textureLoad, uniformArray, varying, vec3, vec4 } from 'three/tsl'
3
3
  import createVoxel from 'voxelized-js/src'
4
4
  import { atlas } from './utils'
5
- import type { Camera, DataArrayTexture, Object3D, Renderer, Scene, Texture, UniformArrayNode, VarNode, Vector3 } from 'three/webgpu'
5
+ import type { Camera, CanvasTexture, DataArrayTexture, Object3D, Renderer, Scene, UniformArrayNode, VarNode, Vector3 } from 'three/webgpu'
6
6
 
7
7
  export * from './utils'
8
8
 
@@ -38,17 +38,6 @@ const driveFromThree = (cam: Cam, camera: Camera, cx: number, cz: number) => {
38
38
  cam.pos[2] = camera.position.z + cz
39
39
  }
40
40
 
41
- const createAtlasTex = (slot = 16) => {
42
- const t = new THREE.DataArrayTexture(null, 4096, 4096, slot)
43
- t.minFilter = t.magFilter = THREE.NearestFilter
44
- t.wrapS = t.wrapT = THREE.ClampToEdgeWrapping
45
- t.generateMipmaps = false
46
- t.needsUpdate = true
47
- t.source.dataReady = false
48
- t.colorSpace = THREE.SRGBColorSpace
49
- return t
50
- }
51
-
52
41
  const createVec3 = () => new THREE.Vector3()
53
42
  const createGeometry = () => new THREE.BoxGeometry()
54
43
  const createMaterial = (atlasTex: DataArrayTexture, offsetNode: UniformArrayNode<'vec3'>) => {
@@ -84,38 +73,70 @@ const createMaterial = (atlasTex: DataArrayTexture, offsetNode: UniformArrayNode
84
73
  return mat
85
74
  }
86
75
 
76
+ const createDstTexture = (slot = 16) => {
77
+ const t = new THREE.DataArrayTexture(null, 4096, 4096, slot)
78
+ t.wrapS = THREE.ClampToEdgeWrapping
79
+ t.wrapT = THREE.ClampToEdgeWrapping
80
+ t.magFilter = THREE.NearestFilter
81
+ t.minFilter = THREE.NearestFilter
82
+ t.colorSpace = THREE.SRGBColorSpace
83
+ t.needsUpdate = true
84
+ t.generateMipmaps = false
85
+ t.source.dataReady = false
86
+ return t
87
+ }
88
+
89
+ const createSrcTexture = (el: HTMLCanvasElement) => {
90
+ const t = new THREE.CanvasTexture(el)
91
+ t.magFilter = THREE.NearestFilter
92
+ t.minFilter = THREE.NearestFilter
93
+ t.flipY = false
94
+ t.generateMipmaps = false
95
+ return t
96
+ }
97
+
98
+ const createCanvas = () => {
99
+ const el = document.createElement('canvas')
100
+ el.width = 4096
101
+ el.height = 4096
102
+ return el
103
+ }
104
+
87
105
  export class Voxel extends THREE.InstancedMesh {
88
106
  voxel: Res
89
107
  offsetNode: UniformArrayNode<'vec3'>
90
108
  dstTexture: DataArrayTexture
91
- private _texture: Texture
109
+ private _context: CanvasRenderingContext2D
110
+ private _texture: CanvasTexture
92
111
  private _isThree: boolean
93
112
  constructor(params: Req & { controls?: 'three' | 'voxel' }) {
94
113
  const { slot = 16, controls } = params
95
114
  const offsetNode = uniformArray<'vec3'>(Array.from({ length: slot }, createVec3), 'vec3')
96
- const dstTexture = createAtlasTex(slot)
115
+ const dstTexture = createDstTexture(slot)
97
116
  super(createGeometry(), createMaterial(dstTexture, offsetNode), 1)
117
+ const canvas = createCanvas()
118
+ this._context = canvas.getContext('2d')!
119
+ this._texture = createSrcTexture(canvas)
98
120
  this.offsetNode = offsetNode
99
121
  this.dstTexture = dstTexture
100
122
  this.frustumCulled = false
101
123
  this.voxel = createVoxel(params)
102
- this._texture = new THREE.Texture()
103
- this._texture.flipY = this._texture.generateMipmaps = false
104
124
  this._isThree = controls !== 'voxel'
105
125
  this._setAttribute()
106
126
  }
107
127
  onBeforeRender(renderer: Renderer | BaseRenderer, _scene: Scene, camera: Camera) {
108
- const { dstTexture, offsetNode, voxel, _isThree, _texture } = this
109
- const { center, cam, updates, updated, count, overflow } = voxel
128
+ const { dstTexture, offsetNode, voxel, _context, _isThree, _texture } = this
129
+ const { cam, center, count, updated, updates, overflow } = voxel
110
130
  const [cx, cz] = center
111
131
  if (_isThree) driveFromThree(cam, camera, cx, cz)
112
132
  else driveFromVoxel(cam, camera, cx, cz, renderer)
113
- const _node = offsetNode as unknown as { array: Vector3[]; needsUpdate: boolean }
133
+ const _node = offsetNode as unknown as { array: Vector3[]; needsUpdate: boolean; srcTex: any }
114
134
  const array = _node.array
115
135
  updates(({ at, atlas, offset }) => {
116
136
  array[at].set(offset[0] - cx, offset[1], offset[2] - cz)
117
- _texture.image = atlas
118
- _texture.needsUpdate = _node.needsUpdate = true
137
+ _context.drawImage(atlas, 0, 0)
138
+ _node.needsUpdate = true
139
+ _texture.needsUpdate = true
119
140
  renderer.copyTextureToTexture(_texture, dstTexture, null, _vec3.set(0, 0, at))
120
141
  })
121
142
  if (!updated()) return