@KumuPaul
So it’s true that QUADS and QUAD_STRIP don’t work with the WEBGL renderer, and already on 22 Mar 2020 the issue was reported, but not solved until today.
I am trying to translate another sketch now with a more defined closed shape. A nut. And it’s actually not that difficult to transform a QUAD_STRIP shape into a simple vertex() shape by repeating the ‘end’ vectors and inverting them. But still the sketch is far from running as smooth as in P5.java. Also the pointLight()'s work very differently. What can I do to improve this?
P5.js
const NUTS = 25;
const MIN_HEIGHT = 2;
const MAX_HEIGHT = 6;
const MIN_RADIUS = 15;
const MAX_RADIUS = 20;
const MAX_ROT = 0.01;
var nuts = [];
let l0, l1, l2;
let rx = 0,
ry = 0;
let dx = 0,
dy = 0;
let rotX = 0,
rotY = 0;
function setup() {
createCanvas(800, 700, WEBGL);
for (let i = 0; i < NUTS; i++) {
nuts[i] = new Nut();
}
l0 = createVector(-100, -100, -100);
l1 = createVector(-100, -100, -100);
l2 = createVector(-100, -100, -100);
rx = random(0, TWO_PI);
dx = random(-MAX_ROT, MAX_ROT);
ry = random(0, TWO_PI);
dy = random(-MAX_ROT, MAX_ROT);
}
function draw() {
background(0);
scale(5);
rotateX(rotX);
rotateY(-rotY);
rotateX(1.5);
lights();
pointLight(64, 64, 64, l0.x, l0.y, l0.z);
pointLight(64, 64, 64, l1.x, l1.y, l1.z);
pointLight(64, 64, 64, l2.x, l2.y, l2.z);
rx += dx;
ry += dy;
rotateX(rx);
rotateY(ry);
for (let i = 0; i < NUTS; i++) {
nuts[i].draw();
}
}
class Nut {
constructor() {
this.x = random(0);
this.y = random(0);
this.z = random(-20, 20);
this.h = random(MIN_HEIGHT, MAX_HEIGHT);
this.r0 = random(0, MIN_RADIUS);
this.r1 = this.r0 + random(MIN_RADIUS);
this.rx = 0;
this.ry = 0;
this.rz = random(0, TWO_PI);
this.dx = 0;
this.dy = 0;
this.dz = random(-MAX_ROT, MAX_ROT);
this.r = int(random(64, 256));
this.g = int(random(64, 256));
this.b = int(random(64, 256));
}
draw() {
fill(this.r, this.g, this.b);
noStroke();
this.rx += this.dx;
this.ry += this.dy;
this.rz += this.dz;
this.z = 30 * cos(this.rz);
rotateX(this.rx);
rotateY(this.ry);
rotateZ(this.rz);
this.tube(this.r0);
this.tube(this.r1);
this.side(this.z + this.h);
this.side(this.z - this.h);
}
tube(radius) {
let a = 0;
let angle = TWO_PI / 6;
for (let i = 0; i < 6; i++) {
beginShape();
vertex(radius * cos(a), radius * sin(a), this.z - this.h);
vertex(radius * cos(a), radius * sin(a), this.z + this.h);
a += angle;
vertex(radius * cos(a), radius * sin(a), this.z + this.h);
vertex(radius * cos(a), radius * sin(a), this.z - this.h);
endShape();
}
}
side(ht) {
let a = 0;
let angle = TWO_PI / 6;
for (let i = 0; i < 6; i++) {
beginShape();
vertex(this.r0 * cos(a), this.r0 * sin(a), ht);
vertex(this.r1 * cos(a), this.r1 * sin(a), ht);
a += angle;
vertex(this.r1 * cos(a), this.r1 * sin(a), ht);
vertex(this.r0 * cos(a), this.r0 * sin(a), ht);
endShape();
}
}
}
function mouseDragged() {
if (mouseY < height - 20) {
rotY -= (mouseX - pmouseX) * 0.01;
rotX -= (mouseY - pmouseY) * 0.01;
}
}
P5.java
float rotX, rotY;
int NUTS = 25;
float MIN_HEIGHT = 2;
float MAX_HEIGHT = 6;
float MIN_RADIUS = 15;
float MAX_RADIUS = 20;
float MAX_ROT = .01;
TheNut[] nuts = new TheNut[NUTS];
PVector l0, l1, l2;
float rx, ry;
float dx, dy;
void setup() {
size(1000, 750, P3D);
for (int i = 0; i < NUTS; i++) {
nuts[i] = new TheNut();
}
l0 = new PVector(random(-200, 200), random(-200, 200), random(-200, 200));
l1 = new PVector(random(-200, 200), random(-200, 200), random(-200, 200));
l2 = new PVector(random(-200, 200), random(-200, 200), random(-200, 200));
rx = random(0, TWO_PI);
dx = random(-MAX_ROT, MAX_ROT);
ry = random(0, TWO_PI);
dy = random(-MAX_ROT, MAX_ROT);
}
void draw() {
background(0);
translate(width/2, height/2);
scale(5);
rotateX(rotX);
rotateY(-rotY);
lights();
pointLight(64, 64, 64, l0.x, l0.y, l0.z);
pointLight(64, 64, 64, l1.x, l1.y, l1.z);
pointLight(64, 64, 64, l2.x, l2.y, l2.z);
rx += dx;
ry += dy;
rotateX(rx);
rotateY(ry);
for (int i = 0; i < NUTS; i++) {
nuts[i].draw();
}
}
class TheNut {
float x, y, z, h;
float r0, r1; // radii
float rx, ry, rz; // rotations
float dx, dy, dz; // deltas
int r, g, b;
TheNut() {
x = random(0);
y = random(0);
z = random(-20, 20);
h = random(MIN_HEIGHT, MAX_HEIGHT);
r0 = random(0, MIN_RADIUS);
r1 = r0 + random(MIN_RADIUS);
rx = 0;
ry = 0;
rz = random(0, TWO_PI);
dx = 0;
dy = 0;
dz = random(-MAX_ROT, MAX_ROT);
r = int(random(64, 256));
g = int(random(64, 256));
b = int(random(64, 256));
}
void draw() {
fill(r, g, b);
noStroke();
rx += dx;
ry += dy;
rz += dz;
z = 30 * cos(rz);
rotateX(rx);
rotateY(ry);
rotateZ(rz);
float angle = TWO_PI / 5;
// inner
tube(r0);
// outer
tube(r1);
// top
side(z + h);
// bottom
side(z - h);
}
void tube(float radius) {
float angle = TWO_PI / 6;
beginShape(QUAD_STRIP);
float a = 0;
for (int i = 0; i < 8; i++) {
vertex(radius * cos(a), radius * sin(a), z - h);
vertex(radius * cos(a), radius * sin(a), z + h);
a += angle;
}
endShape();
}
void side(float ht) {
float angle = TWO_PI / 6;
beginShape(QUAD_STRIP);
float a = 0;
for (int i = 0; i < 8; i++) {
vertex(r0 * cos(a), r0 * sin(a), ht);
vertex(r1 * cos(a), r1 * sin(a), ht);
a += angle;
}
endShape();
}
}
void mouseDragged() {
if (mouseY < height - 20) {
rotY -= (mouseX - pmouseX) * 0.01;
rotX -= (mouseY - pmouseY) * 0.01;
}
}