Threejs - 在着色器材质上应用简单纹理

时间:2014-08-03 10:00:22

标签: three.js glsl

将Threejs(67)与Webgl渲染器一起使用时,我似乎无法使用着色器材质来佩戴其纹理。无论我做什么,材料都会保持黑色。

目前我的代码看起来很基本:

var grassT = new Three.Texture(grass); // grass is an already loaded image.
grassT.wrapS = grassT.wrapT = Three.ClampToEdgeWrapping;
grassT.flipY = false;
grassT.minFilter = Three.NearestFilter;
grassT.magFilter = Three.NearestFilter;
grassT.needsUpdate = true;

var terrainUniforms = {
  grassTexture : { type: "t", value: grassT},
}

然后我在vertexShader中有这个重要的部分:

vUv = uv;

在fragmentShader方面:

gl_FragColor = texture2D(grassTexture, vUv);

这导致:

  • 黑色材料。
  • 控制台没有错误。
  • gl_FragColor值始终为(0.0,0.0,0.0,1.0)。

我尝试/检查的内容:

  • 如果我只使用自定义纯色,一切正常。
  • 如果我也使用普通颜色的vertexColors,那么一切都很好。
  • 我的纹理宽度/高度确实是2的幂。
  • 图像与代码位于同一服务器上。
  • 测试了其他具有相同结果的图像。
  • 图像实际上是在浏览器调试器中加载的。
  • 网格的UVS已更正。
  • 使用wrapT,wrapS,minFilter,magFilter
  • 调整网格大小,使纹理的比例为1:1。
  • 使用requirejs图像插件预加载图像并从THREE.Texture()创建纹理,而不是使用THREE.ImageUtils();
  • 玩needUpdate:true;
  • 尝试在材料实例化过程中添加定义[' USE_MAP']。
  • 尝试添加material.dynamic = true。
  • 我有一个正确的渲染循环(与地形的交互工作)。

我仍然想知道:

  • 这是一个使用express + socket.io的自定义端口的多人游戏。我是否遇到过任何Webgl安全策略?
  • 此刻我没有灯光逻辑,这是一个问题吗?
  • 也许着色器材料需要其他"定义"在instanciation?

我想我忽略了一些简单的事情,这就是我要问的原因...... 感谢。

2 个答案:

答案 0 :(得分:2)

我在同一个着色器上应用各种效果。我有一个自定义API,只需使用Three.UniformsUtils.merge()即可合并所有不同的效果制服。但是,此函数在纹理上调用clone()方法,这导致将needsUpdate重置为{{1}在纹理到达渲染器之前。

在达到材料级别时,您应该将纹理 false 属性设置为true。在纹理级别上,如果您设置的统一被合并,因此克隆,稍后在此过程中,它将失去其needsUpdate属性。

此问题也在此处详细说明:https://github.com/mrdoob/three.js/issues/3393

在我的情况下,以下不是正在工作(needsUpdate是我的纹理):

grassT

虽然以后在代码中完美运行:

grassT.needsUpdate = true

答案 1 :(得分:1)

图像加载是异步的。最有可能的是,您在加载纹理图像之前渲染场景。

在图像加载后,您必须将texture.needsUpdate标记设置为true 。 three.js有一个实用程序可以帮助你:

var texture = THREE.ImageUtils.loadTexture( "texture.jpg" );

呈现后,渲染器会将texture.needsUpdate标记设置回false

three.js r.68