首页 > 解决方案 > 处理:透明 3D 对象中的持久性

问题描述

先前定义的形状(三角形)出现但不存在于 3D 对象(球体)中,但存在于外部。

三角形出现在透明球体中,但在下一次渲染时消失。为了透明度,我使用了启用的 DEPTH_SORT。

// Aim of program: draw a stack of triangles that goes through a transparent 3D sphere
// Problem: stack not visible inside the sphere

float y;
float x;
float r_sphere = 200;
float up_down = -0.5;

void setup() {

  size(1100, 800, P3D);
  background(0);
  hint(ENABLE_DEPTH_SORT); // option that allows transparency
  fill(0, 40); // alpha parameter for transparency

  x = width/2;
  y = height/2+r_sphere+20;
}

void draw() {

  // 1. draw stack of triangles in new referential
  pushMatrix();

  // define new referential for the triangle at each rendering
  translate(x, y);
  y = y+=up_down;
  // draw the triangle that should persist
  stroke(220, 150, 25);
  strokeWeight(2);
  triangle(0, 0, 90, 0, 70, 30);

  popMatrix();

  // 2. draw the transparent sphere in the initial referential

  translate(width/2, height/2);
  strokeWeight(0.1);
  stroke(155, 220, 220);
  sphere(r_sphere);
}

结果

标签: graphicsprocessingp5.js

解决方案


隐藏三角形堆栈的问题是由每次调用 draw 时绘制的球体引起的。尽管透明度设置为 40,但重复的球体加起来会遮盖除最新的三角形之外的所有球体,而最新的三角形是绘制在除最新球体之外的所有球体之上的。

要查看球体的累积效果如何隐藏三角形堆栈,请将 alpha 设置为较低的数字。通过将 alpha 设置为 5 而不是 40,我们可以看到三角形堆栈的一小段轨迹:

fill(0, 5); // alpha parameter for transparency

如果我们将 alpha 更改为 2,我们会得到一条短路径,并且三角形堆栈似乎永远不会完全被遮挡。

Alpha 为 2 的球体和三角形

另一种不覆盖三角形堆栈的绘制方法是只绘制一次球体。

if (frameCount < 2){
  // 2. draw the transparent sphere in the initial referential 
  translate(width/2, height/2);
  strokeWeight(0.1);
  stroke(155, 220, 220);
  sphere(r_sphere);
}

这将使三角形堆栈可见,但可能不会给您正在寻找的视觉效果,因为这两个三角形似乎在球体的前面而不是在球体内部。

第三种方法是从底部到当前 y 位置重新绘制整个三角形堆栈,然后在每次调用 draw 时绘制球体。

我已修改您的代码以采用这种方法:

float y;
float x;
float r_sphere = 200;
float up_down = -0.5;

void setup() {

  size(1100, 800, P3D);
  background(0);
  hint(ENABLE_DEPTH_SORT); // option that allows transparency
  fill(0, 40); // alpha parameter for transparency
  x = width/2;
  y = height/2+r_sphere+20;
}

void draw() {

    if (frameCount > height + r_sphere+20){
      noLoop();
    } else {
     background(0);
    }

  // 1. draw stack of triangles in new referential
  // define new referential for the triangle at each rendering
  y = height/2+r_sphere+20;
  for (int i = 0; i < frameCount; i++){
    pushMatrix();
    translate(x, y, 0);
    y = y+=up_down;
    // draw the triangle that should persist
    stroke(220, 150, 25);
    strokeWeight(2);
    triangle(0, 0, 90, 0, 70, 30);
    popMatrix();
  }
  // 2. draw the transparent sphere in the initial referential
  translate(width/2, height/2);
  strokeWeight(0.1);
  stroke(155, 220, 220);
  sphere(r_sphere);
}

我相信最后一种方法最接近于模拟一个透明的物理球体和一堆完全不透明的三角形的视图。视觉效果不像第一种方法那样令人兴奋,因为我们没有将三角形堆栈视为空心,因此将 alpha 设置为较低的数字。


推荐阅读