@tinypoly/cpu-rendererv0.3.0MIT

Renderizador de CPU para Three.js

Paquete de código abierto que renderiza un THREE.Scene en la CPU, repartiendo el trabajo entre un conjunto de workers. Funciona en el navegador y en Node, y nunca crea un contexto WebGL. Es el renderizador del modo render de Tinypoly.

npm install @tinypoly/cpu-renderer three
Cargando el renderizador

Imagen renderizada en este navegador al abrir la página.

Funciones

Funciones que el renderizador soporta hoy, desde los materiales y geometrías hasta los efectos de cámara.

Materiales

Standard y Physical, con clearcoat, sheen, transmisión y anisotropía. También Lambert, Phong, Toon y Basic.

Shaders GLSL

ShaderMaterial se ejecuta en un intérprete propio, que compila el GLSL a closures. No usa eval.

Sombras

Sombras trazadas por rayos contra una BVH, con penumbra, y oclusión ambiental.

Iluminación Global

Luz difusa indirecta con caché de irradiancia, filtro de ruido al estilo SVGF y muestreo por importancia del entorno.

Cámara y Posprocesado

Entorno HDR o en degradado, profundidad de campo, niebla, viñeta, grano y tone mapping ACES, AgX o Neutral.

Salida Progresiva

Los píxeles llegan a medida que cada bloque termina, listos para pintarse en un canvas. El cuadro se puede pausar y reanudar.

Navegador y Node

Sin dependencia del DOM: recibe un tamaño y devuelve los píxeles. En Node los workers corren en worker_threads y comparten memoria sin ninguna cabecera; en el navegador eso exige aislamiento de origen.

Líneas, Sprites y Puntos

Line, LineSegments, LineLoop, líneas discontinuas, sprites y PointsMaterial, con cámara en perspectiva u ortográfica.

Cómo funciona

El hilo principal solo coordina. El cálculo se hace en los workers.

  1. 01

    Serialización

    Geometrías, materiales, texturas, luces y cámara se copian a un formato propio, en segundo plano.

  2. 02

    Preparación

    El primer worker ejecuta los vertex shaders y arma los triángulos y la BVH. Los demás reutilizan ese resultado por la memoria compartida.

  3. 03

    Bloques

    Con iluminación global, primero se calcula la caché de luz indirecta. Después la imagen se divide en bloques, y cada worker toma el siguiente libre.

  4. 04

    Finalización

    Cada bloque se entrega en cuanto termina, y el adaptador lo pinta en el canvas. Al final, el filtro de ruido se aplica a la luz indirecta.

Uso

Pasa el tamaño, los objetos y la cámara, y llama a render(). Devuelve los píxeles terminados, y attachCanvas pinta cada bloque en un canvas a medida que termina.

main.ts
import * as THREE from "three";
import { CpuRenderer, attachCanvas } from "@tinypoly/cpu-renderer";

const scene = new THREE.Scene();
scene.add(new THREE.Mesh(
  new THREE.SphereGeometry(1, 48, 24),
  new THREE.MeshPhysicalMaterial({ color: "tomato" }),
));

const camera = new THREE.PerspectiveCamera(40, 1, 0.1, 100);
camera.position.set(0, 1, 5);
camera.lookAt(0, 0, 0);

const canvas = document.querySelector("canvas")!;
const renderer = new CpuRenderer({
  width: canvas.clientWidth,
  height: canvas.clientHeight,
  pixelRatio: window.devicePixelRatio,
  scene,
  camera,
  environment: { kind: "gradient", topColor: "#9cb8d8", bottomColor: "#2b2a28" },
  settings: { globalIllumination: { enabled: true } },
});

attachCanvas(renderer, canvas);
renderer.on("progress", ({ completed, total }) => {
  console.log(`${completed} / ${total}`);
});

const { width, height, data } = await renderer.render();

En Tinypoly

Este es el renderizador que se usa en el modo de renderizado de Tinypoly.

Abrir el editor