@tinypoly/cpu-rendererv0.3.0MIT

Renderizador de CPU para Three.js

Pacote de código aberto que renderiza um THREE.Scene na CPU, dividindo o trabalho entre um conjunto de workers. Roda no navegador e no Node, e nunca cria um contexto WebGL. É o renderizador do modo render do Tinypoly.

npm install @tinypoly/cpu-renderer three
Carregando o renderizador

Imagem renderizada neste navegador quando a página abriu.

Recursos

Recursos que o renderizador suporta hoje, dos materiais e geometrias até os efeitos de câmera.

Materiais

Standard e Physical, com clearcoat, sheen, transmissão e anisotropia. Também Lambert, Phong, Toon e Basic.

Shaders GLSL

ShaderMaterial é executado por um interpretador próprio, que compila o GLSL para closures. Não usa eval.

Sombras

Sombras traçadas por raio contra uma BVH, com penumbra, e oclusão de ambiente.

Iluminação Global

Luz difusa indireta com cache de irradiância, filtro de ruído no estilo SVGF e amostragem por importância do ambiente.

Câmera e Pós-Processamento

Ambiente HDR ou em gradiente, profundidade de campo, neblina, vinheta, grão e tone mapping ACES, AgX ou Neutral.

Saída Progressiva

Os pixels chegam conforme cada bloco termina, prontos para serem pintados em um canvas. O quadro pode ser pausado e retomado.

Navegador e Node

Sem dependência do DOM: recebe um tamanho e devolve os pixels. No Node os workers rodam em worker_threads e compartilham memória sem cabeçalho nenhum; no navegador isso exige isolamento de origem.

Linhas, Sprites e Pontos

Line, LineSegments, LineLoop, linhas tracejadas, sprites e PointsMaterial, com câmera em perspectiva ou ortográfica.

Como funciona

A thread principal só coordena. O cálculo é feito nos workers.

  1. 01

    Serialização

    Geometrias, materiais, texturas, luzes e câmera são copiados para um formato próprio, em segundo plano.

  2. 02

    Preparação

    O primeiro worker executa os vertex shaders e monta os triângulos e a BVH. Os demais reaproveitam esse resultado pela memória compartilhada.

  3. 03

    Blocos

    Com iluminação global, o cache de luz indireta é calculado primeiro. Depois a imagem é dividida em blocos, e cada worker pega o próximo livre.

  4. 04

    Finalização

    Cada bloco é entregue assim que termina, e o adaptador o pinta no canvas. No fim, o filtro de ruído é aplicado à luz indireta.

Uso

Passe o tamanho, os objetos e a câmera, e chame render(). Ele devolve os pixels prontos, e o attachCanvas pinta cada bloco em um canvas conforme 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();

No Tinypoly

Este é o renderizador usado no modo de renderização do Tinypoly.

Abrir o editor