【问题标题】:Create animation of transparency, revealing the Mesh in threejs创建透明度动画,在threejs中显示Mesh
【发布时间】:2014-03-21 15:41:40
【问题描述】:

我需要创建线性动画(类似于 2d jquery 对象中的 slideUp),并显示一个非常复杂的网格(构建 3d 模型) - 从底部到顶部。

我一直在寻找不透明通道/不透明贴图或类似的东西,现在我知道这是不可能的。

使用纹理精灵和改变偏移不是最好的主意,因为我的 UV 贴图太复杂了。

有没有办法在 THREE.JS 中创建这种效果?

【问题讨论】:

  • (3d 模型的)背景是什么?如果什么都没有,也许你可以有一个广告牌(带有透明渐变材料),它会改变比例和位置,逐渐将建筑物显示为一个 hacky 解决方案?
  • 在背景中我有天空盒和一些树。我还需要旋转这座建筑
  • 我的 hacky 建议在这种情况下不起作用。我猜想控制 alpha 信息的片段着色器将是朝着这个方向迈出的一步。
  • 这是我的第一个想法,但我不知道如何实现它。我发现了类似的东西 - jsfiddle.net/yfSwK/99 现在我正试图弄清楚它是如何工作的

标签: javascript three.js webgl


【解决方案1】:

将整个场景渲染到第一个帧缓冲区(纹理)中。
仅将网格渲染到第二个帧缓冲区(纹理)中。

渲染一个使用前面提到的两个纹理的全屏矩形,并使用以下代码的某些版本:

uniform sampler2D texScene;
uniform sampler2D texMesh;

uniform vec2 uResolution;
uniform float time;

void main() {
    vec2 uv = gl_FragCoord.xy / uResolution;

    vec3 s = texture2D( texScene, uv ).xyz;
    vec4 m = texture2D( texMesh, uv );

    // slide up effect
    float percent = clamp( time, 0, endAnim ) / endAnim;  // endAnim is the time animation ends (assuming animation starts at time=0)

    vec3 color = s;
    if( uv.y > (1.0 - percent) ) {
        color = s * (1.0 - m.a) + m.xyz * m.a;
    }
    gl_FragColor = vec4( color, 1.0 );
}

应该直观地理解代码是如何工作的。根据经过的时间,它检查动画的百分比,并据此计算它是否应该包含网格的颜色,或者只输出背景颜色。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    或者,您可以使用gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) 将建筑物绘制到屏幕上,并为您的建筑物提供 alpha 渐变(从上到下)。

    绘制到任何输出的方式是,WebGL 评估源信息和目标信息(已经绘制到该输出的内容)并将两者结合起来,但您可以指定它是如何做到的。

    绘制到输出的方程可以大致描述为:

    SOURCE_VALUE * [SOURCE_FACTOR] [BLEND EQUATION] DESTINATION_VALUE * [DESTINATION_FACTOR];

    默认情况下是:

    SOURCE_VALUE * 1 + DESTINATION_VALUE * 0;

    这个等式丢弃缓冲区中的所有现有信息,并用新信息覆盖它。 我们要做的是告诉 WebGL 将现有信息保留在我们没有绘制到缓冲区的位置,并将新信息带到我们将要绘制的位置,因此等式变为:

    SOURCE_VALUE * SRC_ALPHA + DESTINATION_VALUE * ONE_MINUS_SRC_ALPHA;

    如果您的建筑物在一个碎片中是 20% 的透明,那么该碎片将是建筑物的 20% 的颜色,以及建筑物后面任何部分的 80% 的颜色。

    这种绘制半透明对象的方法尊重深度缓冲区。

    【讨论】:

      【解决方案3】:

      我想出了另一个解决方案。

      我为整个建筑使用一种纹理(没有重复的图案)。 我逐渐垂直放置 UVS(从底部到纹理底部的面等),并通过填充透明矩形(画布纹理)为纹理设置动画。

      // x - current step
      // steps - number of steps
      
      var canvas = document.getElementById('canvas-texture'),
          ctx    = canvas.getContext('2d');
      
      ctx.beginPath();
      ctx.drawImage(image, 0, 0);
      ctx.globalCompositeOperation = 'destination-out';
      ctx.fillRect(0, 0, width, height/steps * x);
      ctx.closePath();
      

      我需要它尽快,所以如果我有时间我会在周末尝试你的想法,如果你愿意,我可以用我的解决方案创建一些小提琴。

      无论如何,谢谢你们的帮助。

      【讨论】:

        猜你喜欢
        • 2012-01-17
        • 2012-02-27
        • 2011-09-23
        • 1970-01-01
        • 1970-01-01
        • 2014-06-10
        • 2010-09-25
        • 2014-12-10
        • 1970-01-01
        相关资源
        最近更新 更多