【问题标题】:three.js gradient with canvas rendererthree.js 渐变与画布渲染器
【发布时间】:2013-11-21 20:45:24
【问题描述】:

我知道使用 webgl 渲染器可以在材质上使用 vertexColors 来创建线性渐变。根据文档,这不适用于画布渲染器。我怎样才能回到画布渲染器并且仍然有渐变?我希望它受到环境光照的影响,所以我不能依赖图像纹理。

【问题讨论】:

  • 你的意思是你写的——只有环境?如果是这样,您可以使用Mesh.BasicMaterial,用纹理表示渐变,并在环境光变暗时即时使纹理变暗。
  • 为了澄清,我有一个用于改变亮度的场景的环境光。使用 webgl 渲染器,图像纹理会受到该亮度的影响。当它回到cavas渲染器时,它们不是。我认为这是某种画布渲染器限制。除了使用环境光之外,我怎样才能在飞行中将其变暗?当您说纹理时,我假设的是图像-我是 Three.Js 的新手基本上我想要一种具有线性渐变的材质,该材质会受到两个渲染器的照明的影响。
  • 另外,只要我能与环境光(补间)保持同步,我也可以手动操作。

标签: three.js


【解决方案1】:

是的,CanvasRenderer 不支持 MeshLambertMaterial 和漫反射纹理的组合。

如果您只关心环境光,那么您可以将MeshBasicMaterial 与纹理一起使用,并即时使纹理变暗以模拟环境阴影。 (实际上,您可以通过这种方式模拟任何光照。)

注意,这确实是一个 hack。

创建一个函数来根据环境光照修改纹理。 (image 在您的情况下是无阴影的渐变。)

function applyAmbient( mesh, image, ambientFactor ) { // 1.0 = lightest; 0.0 = darkest

    var canvas = mesh.material.map.image;

    var size = canvas.width;
    var size = canvas.height;

    // get context
    var context = canvas.getContext( '2d' );

    // copy image
    context.drawImage( image, 0, 0 );

    // apply ambient factor
    context.fillStyle = "rgba( 0, 0, 0, " + ( 1 - ambientFactor ) + " )";
    context.fillRect( 0, 0, size, size );

    return canvas;

}

然后,在渲染循环中,更新纹理

applyAmbient( mesh, textureImage, ambientFactor );
mesh.material.map.needsUpdate = true; // important!

jsfiddle:http://jsfiddle.net/mkP7q/

three.js r.62

【讨论】:

  • 这看起来像我想要的,但它会在 getContext 上产生错误。 “TypeError: Object # has no method 'getContext'” 另外,我假设图像参数是图像 src 的字符串?通过查看这个,我假设我可以传递材质而不是网格,还可以从 material.map.image.src 中获取 src。我有很多地方使用这种材料。
  • 我的评论有点模棱两可。我收到传递网格、imageSrc、环境的错误。之后的部分是关于在我让它工作后改变功能。
  • 我添加了一个小提琴来展示一种方法。我会让你弄清楚你的实现细节:-)
  • 谢谢。这非常有帮助。
  • 我刚刚注意到 generateTexture 方法适用于画布,但对于 webgl,使用 addColorStop(1, 'rgba(0,0,0,0)') 时的 alpha 都搞砸了。有没有办法改变这一点,以便 alpha 在使用 webgl 时按预期工作?我尝试将 getContext 更改为 webgl,但它没有适当的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 2012-09-21
  • 1970-01-01
  • 2016-06-19
  • 2013-12-10
  • 2012-09-10
相关资源
最近更新 更多