Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

185
Views
3D Object Faces Disappearing in p5.js

I am trying to make a 3D box with a pattern on each side using the following code but when viewed from certain angles, the back faces disappear when looking through the transparent parts of the forward faces. I was also wondering if it is possible to have a different pattern on each face? Many thanks in advance!

let r = 10
let a = 0
let c = 20
let angle = 0
let art

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  art = createGraphics(800, 800)

}

function draw() {
  background(0);
  
  let x = r + c * cos(a)
  let y = r + c * sin(a)

  art.fill(r, a, c)
  art.ellipse(x + 400, y + 400, 10, 10)

  c += 0.2
  a += 1.8

  push()
  texture(art)
  rotateX(angle)
  rotateY(angle)
  rotateZ(angle)
  box(400)

  angle += 0.0003
  pop()

  orbitControl();
}
html, body { margin: 0; overflow: hidden; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

This happens because in in WebGL, once a pixels is drawn, regardless of the level of level of transparency of that pixel, if another triangle would draw to that same pixel, but at a further depth, it is discarded (I think the alpha information from the original pixel(s) may no longer be available). In order for transparency to work properly in WebGL it is necessary to draw all triangles in depth order (furthest from the camera first). And even then if two triangles intersect there will still be problems.

In your case because you have many pixels that are completely transparent and others that are completely opaque there is another solution: a custom fragment shader that discards pixels if the texture alpha is below some threshold.

const vert = `
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

attribute vec3 aPosition;
attribute vec2 aTexCoord;

varying vec2 vTexCoord;

void main() {
  vTexCoord = aTexCoord;

  vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0);
  gl_Position = uProjectionMatrix * viewModelPosition;
}`;

const frag = `
precision mediump float;

// ranges from 0..1
varying vec2 vTexCoord;

uniform sampler2D uSampler;

void main() {
  vec4 tex = texture2D(uSampler, vTexCoord);
  if (tex.a < 0.05) {
    discard;
  }

  gl_FragColor = tex;
}`;

let r = 10
let a = 0
let c = 20
let angle = 0
let art
let discardShader;

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  art = createGraphics(800, 800)
  discardShader = createShader(vert, frag)
  textureMode(NORMAL)
}

function draw() {
  background(0);

  let x = r + c * cos(a)
  let y = r + c * sin(a)

  art.fill(r, a, c)
  art.ellipse(x + 400, y + 400, 10, 10)

  c += 0.2
  a += 1.8

  push()
  noStroke()
  texture(art)
  shader(discardShader)
  rotateX(angle)
  rotateY(angle)
  rotateZ(angle)
  box(400)

  angle += 0.0003
  pop()

  orbitControl();
}
html,
body {
  margin: 0;
  overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>

Note #1: It is important that you use p5.js v1.4.1 for this to work because prior to that there was a bug that prevented user shaders from working with textures.

Note #2: If your texture had partial opacity then this would not work and instead you would want to render each plane of the box separately and in the correct order (farthest from the camera first).

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!