Open blitzgenerative opened 3 years ago
Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.
Hi! Thanks for the issue. The behavior with immediate mode shapes and lighting is very unpredictable because of how the normals are (or are not) calculated in shapes drawn with beginShape
.
That said, could you offer the simplest possible sketch that reproduces the problem you are experiencing?
We could consider automatically generating normals from the faces in immediate mode (for each face, something like v2.copy().sub(v1).cross(v3.copy().sub(v1)).normalize().
) We would probably also need to add a flag to indicate when a normal has been manually specified so we can avoid doing this calculation in that case. We would probably also need to test this for performance, as it would mean doing extra CPU-side calculations per face each frame (maybe we can specify an easy way to disable it? I suppose normal(0, 0, 1)
would do it.)
In any case, for now this could be solved by manually specifying normal()
.
Most appropriate sub-area of p5.js?
Details about the bug:
Run the code below. Comment out:
beginShape(TRIANGLES); for (let face_points of faces){ for (let p of face_points) { vertex(...vectors[p]); } } endShape();
or
box(100)
When it is the box, the directional light is consistent. When it is the beginShape() the lighting is very bright then very dark as if the light itself is rotating in its own way? And not working properly as a result.
`const PHI = (1 + Math.sqrt(5)) / 2; let vectors = [ [-1, PHI, 0], [ 1, PHI, 0], [-1, -PHI, 0], [ 1, -PHI, 0], [0, -1, PHI], [0, 1, PHI], [0, -1, -PHI], [0, 1, -PHI], [ PHI, 0, -1], [ PHI, 0, 1], [-PHI, 0, -1], [-PHI, 0, 1] ]; let faces = [ [0, 11, 5], [0, 5, 1], [0, 1, 7], [0, 7, 10], [0, 10, 11], [1, 5, 9], [5, 11, 4], [11, 10, 2], [10, 7, 6], [7, 1, 8], [3, 9, 4], [3, 4, 2], [3, 2, 6], [3, 6, 8], [3, 8, 9], [4, 9, 5], [2, 4, 11], [6, 2, 10], [8, 6, 7], [9, 8, 1], ];
const canvasWidth = 500; const canvasHeight = 500; const fps=30; const rad=50; function norm_v(v) { const ln2 = Math.sqrt(v[0]2+v[1]2+v[2]*2) return v.map(c=> crad/ln2); }
let middle_point_cache = {}; function middle_point(point_1, point_2) { smaller_index = min(point_1, point_2); greater_index = max(point_1, point_2); let key = smaller_index.toString()+'-'+greater_index.toString(); if (key in middle_point_cache) { return middle_point_cache[key];} let middle = vectors[point_1].map((c, i)=>(c+vectors[point_2][i])/2 ); vectors.push( norm_v(middle) ); index = vectors.length - 1; middle_point_cache[key] = index; return index; }
function divide(faces) { let faces_subdiv = []; for (let tri of faces){ v1 = middle_point(tri[0], tri[1]); v2 = middle_point(tri[1], tri[2]); v3 = middle_point(tri[2], tri[0]); faces_subdiv.push([tri[0], v1, v3]); faces_subdiv.push([tri[1], v2, v1]); faces_subdiv.push([tri[2], v3, v2]); faces_subdiv.push([v1, v2, v3]); } return faces_subdiv; }
let all_cs = [];
function setup(){ const random_seed = parseInt(random(100)); randomSeed(random_seed);
}
function draw() {
console.log(frameRate()) translate(0,0,200); background(all_cs[0],all_cs[1],all_cs[2]); ambientLight(128, 128, 128); directionalLight(128, 128, 128, 0, 0, -1); rotateY(0.01frameCount); rotateZ(0.01frameCount);
} `
Thank you for any help that can be provided.