poppygl 0.0.1 → 0.0.2
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.md +107 -8
- package/dist/index.js +806 -568
- package/package.json +13 -2
package/README.md
CHANGED
|
@@ -1,16 +1,115 @@
|
|
|
1
1
|
# poppygl
|
|
2
2
|
|
|
3
|
-
Render GLTF files to PNG images in completely native
|
|
3
|
+
Render GLTF files to PNG images in completely native JavaScript without WebGL/OpenGL.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<img width="996" height="732" alt="image" src="https://github.com/user-attachments/assets/5cda4566-2637-440e-8956-dff87aedbc26" />
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import { renderGLTFToPNGBuffer } from "poppygl"
|
|
7
|
+
## Quick start
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
Give poppygl a `.gltf` or `.glb` URL and it will fetch every referenced buffer/texture, rasterize the scene, and hand back a PNG buffer.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
```ts
|
|
12
|
+
import { renderGLTFToPNGBufferFromURL } from "poppygl"
|
|
13
|
+
import { writeFile } from "node:fs/promises"
|
|
14
|
+
|
|
15
|
+
const png = await renderGLTFToPNGBufferFromURL(
|
|
16
|
+
"https://models.babylonjs.com/DamagedHelmet.glb",
|
|
17
|
+
{
|
|
18
|
+
width: 800,
|
|
19
|
+
height: 600,
|
|
20
|
+
ambient: 0.15,
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
await writeFile("DamagedHelmet.png", png)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> The fetch helper relies on the global `fetch` API (present in Node 18+ and modern browsers). Pass a custom `fetchImpl` if you need different transport or caching behaviour.
|
|
28
|
+
|
|
29
|
+
## Render from an in-memory GLB buffer
|
|
30
|
+
|
|
31
|
+
Already have the `.glb` bytes (for example, uploaded by a user or read from disk)? Send the buffer straight to `renderGLTFToPNGBufferFromGLBBuffer` and receive the PNG output.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { readFile } from "node:fs/promises"
|
|
35
|
+
import { renderGLTFToPNGBufferFromGLBBuffer } from "poppygl"
|
|
36
|
+
|
|
37
|
+
const glb = await readFile("DamagedHelmet.glb")
|
|
38
|
+
const png = await renderGLTFToPNGBufferFromGLBBuffer(glb, {
|
|
39
|
+
width: 1024,
|
|
40
|
+
height: 768,
|
|
15
41
|
})
|
|
42
|
+
|
|
43
|
+
// write or return the PNG buffer
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> This helper expects every referenced buffer/image to be embedded in the GLB (the usual single-file package). If the asset links out to external resources, load it with `renderGLTFToPNGBufferFromURL` instead so poppygl can fetch the extras.
|
|
47
|
+
|
|
48
|
+
## Render options
|
|
49
|
+
|
|
50
|
+
`renderGLTFToPNGBufferFromURL` accepts the same render options as the lower-level APIs:
|
|
51
|
+
|
|
52
|
+
- `width`/`height` (default `512`): output resolution in pixels.
|
|
53
|
+
- `fov`: vertical field of view in degrees (defaults to `35`).
|
|
54
|
+
- `camPos` and `lookAt`: override the auto-framed camera position and target.
|
|
55
|
+
- `lightDir`: normalized directional light vector (defaults to a top-right key light).
|
|
56
|
+
- `ambient`: ambient lighting contribution (0–1, defaults to `0.2`).
|
|
57
|
+
- `gamma`: gamma correction applied to the output (defaults to `2.2`).
|
|
58
|
+
- `cull`: back-face culling mode (`"back"`, `"front"`, or `"none"`).
|
|
59
|
+
- `fetchImpl`: optional override for resource loading (must match the `fetch` signature).
|
|
60
|
+
|
|
61
|
+
You can inspect the defaults via `getDefaultRenderOptions()` or reuse the internal merge logic with `resolveRenderOptions()`.
|
|
62
|
+
|
|
63
|
+
## If you already have the GLTF JSON
|
|
64
|
+
|
|
65
|
+
When the GLTF JSON object is already in memory (for example, bundled with your app), skip the network loader and supply resources directly:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import {
|
|
69
|
+
bufferFromDataURI,
|
|
70
|
+
createSceneFromGLTF,
|
|
71
|
+
decodeImageFromBuffer,
|
|
72
|
+
encodePNGToBuffer,
|
|
73
|
+
pureImageFactory,
|
|
74
|
+
renderSceneFromGLTF,
|
|
75
|
+
} from "poppygl"
|
|
76
|
+
import gltfJson from "./CesiumMan.gltf.json" assert { type: "json" }
|
|
77
|
+
import { readFile } from "node:fs/promises"
|
|
78
|
+
|
|
79
|
+
const base = new URL("./CesiumMan/", import.meta.url)
|
|
80
|
+
|
|
81
|
+
const buffers = await Promise.all(
|
|
82
|
+
(gltfJson.buffers ?? []).map(async (entry) => {
|
|
83
|
+
if (!entry.uri) throw new Error("Buffers without URIs need custom handling.")
|
|
84
|
+
return entry.uri.startsWith("data:")
|
|
85
|
+
? bufferFromDataURI(entry.uri)
|
|
86
|
+
: await readFile(new URL(entry.uri, base))
|
|
87
|
+
}),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
const images = await Promise.all(
|
|
91
|
+
(gltfJson.images ?? []).map(async (img) => {
|
|
92
|
+
if (!img.uri) throw new Error("Only URI-backed images are shown in this example.")
|
|
93
|
+
const data = img.uri.startsWith("data:")
|
|
94
|
+
? bufferFromDataURI(img.uri)
|
|
95
|
+
: await readFile(new URL(img.uri, base))
|
|
96
|
+
return decodeImageFromBuffer(data, img.mimeType)
|
|
97
|
+
}),
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
const scene = createSceneFromGLTF(gltfJson, { buffers, images })
|
|
101
|
+
const { bitmap } = renderSceneFromGLTF(scene, { width: 512, height: 512 }, pureImageFactory)
|
|
102
|
+
const png = await encodePNGToBuffer(bitmap)
|
|
16
103
|
```
|
|
104
|
+
|
|
105
|
+
The only contract is that `buffers` is an array of `Uint8Array` instances and `images` is an array of `BitmapLike` textures (PNG and JPEG are supported out of the box via `decodeImageFromBuffer`).
|
|
106
|
+
|
|
107
|
+
## Additional utilities
|
|
108
|
+
|
|
109
|
+
- `loadGLTFWithResourcesFromURL` returns `{ gltf, resources }` if you prefer to inspect or cache the parsed data before rendering.
|
|
110
|
+
- `createSceneFromGLTF` builds draw calls ready for the software rasterizer.
|
|
111
|
+
- `computeSmoothNormals` and `computeWorldAABB` expose useful preprocessing helpers.
|
|
112
|
+
- `pureImageFactory` allocates the `pureimage` bitmap implementation used by the renderer.
|
|
113
|
+
- `encodePNGToBuffer` packs any `BitmapLike` into a PNG buffer that can be written to disk or served over the network.
|
|
114
|
+
|
|
115
|
+
Happy rendering!
|