canvas

geometry / colors

What this shows

Three flat-shaded icosahedra with hue, saturation and red-to-yellow vertex color gradients and black wireframe overlays float above soft canvas-texture shadows while the camera follows the pointer.

Side by side with the three.js r186 original: webgl_geometry_colors.html

Differences from three.js

  • MeshPhongMaterial with shininess 0 becomes an EASEL LambertMaterial with flat baked lighting, which has no specular term; with shininess 0 the Phong highlight is a faint uniform sheen that the port drops.
  • EASEL's Color.setRGB rejects components outside 0 to 1, so the third icosahedron's green channel is clamped at 0 before it is stored; three.js stores the negative value and clamps at output, which only changes the gradient on the top faces slightly.
  • EASEL lights each vertex in linear space and encodes it to sRGB before interpolating across the face, where three.js interpolates in linear space and encodes per pixel, so the gradients blend slightly darker between vertices.
  • The black wireframe overlay shares the faces' depth, so EASEL's depth test hides short stretches of some edges where three.js draws them unbroken.
  • The upstream page follows the mouse over the whole window; the embedded stage follows the pointer over its canvas, measured from the canvas center.
EASEL (Canvas2D)
This example needs a canvas-capable browser.

Loading scene…

three.js r186 (WebGL)
This example needs a canvas-capable browser.

Loading scene…

Loading scene…

Key API excerpt

import * as EASEL from "@xsyetopz/easel";


const geometry = new EASEL.IcosahedronGeometry(200, 1);
const count = geometry.getAttribute("position").count;
geometry.setAttribute("color", new EASEL.Attribute(new Float32Array(count * 3), 3));

const positions = geometry.getAttribute("position");
const colors = geometry.getAttribute("color");
const color = new EASEL.Color();

for (let i = 0; i < count; i++) {
  color.setHSL((positions.getY(i) / 200 + 1) / 2, 1.0, 0.5, EASEL.SRGBColorSpace);
  colors.setXYZ(i, color.r, color.g, color.b);
}

const material = new EASEL.LambertMaterial({
  color: 0xffffff,
  shading: EASEL.Shading.Flat,
  vertexColors: true,
});
const mesh = new EASEL.Mesh(geometry, material);
mesh.add(new EASEL.Mesh(geometry, new EASEL.BasicMaterial({
  color: 0x000000,
  wireframe: true,
  vertexColors: false,
})));

scene.add(mesh);

renderer.prepare(scene, camera);
renderer.render(scene, camera);