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 +6 -10
- package/README.md +5 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +42 -21
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`
|
|
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.
|
|
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
|
-
###
|
|
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.
|
|
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.
|
|
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 がそのまま使える。`
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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. `
|
|
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
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
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
|
|
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
|
package/dist/index.mjs.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":["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
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,
|
|
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
|
|
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 =
|
|
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 {
|
|
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
|
-
|
|
118
|
-
|
|
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
|