4

概括

我正在尝试将置换贴图(高度贴图)应用于一个相当简单的对象(六边形平面),但我得到了一些意想不到的结果。我正在使用灰度,因此,我的印象是我的高度图应该只影响我的网格的 Z 值。但是,我创建的置换贴图在 X 和 Y 平面上拉伸了网格。此外,它似乎没有使用我创建的所有其他纹理都成功应用到的 UV 映射。

模型和 UV 贴图

这是我的六边形网格及其在 Blender 中对应的 UV 贴图的参考图像。

六边形模型和 UV 贴图

漫反射和置换纹理

这些是我通过 Three.JS 应用到我的网格的漫反射和置换贴图纹理。

六边形漫反射和置换纹理

渲染

当我在没有置换贴图的情况下渲染平面时,您可以看到六边形平面保持在线条内。但是,当我添加置换贴图时,它显然会影响顶点的 X 和 Y 位置,而不是仅影响 Z,从而将平面很好地扩展到线条上。

六边形平面渲染——带和不带置换贴图

代码

这是相关的 Three.js 代码:

    // Textures
    var diffuseTexture = THREE.ImageUtils.loadTexture('diffuse.png', null, loaded);
    var displacementTexture = THREE.ImageUtils.loadTexture('displacement.png', null, loaded);
    
    // Terrain Uniform
    var terrainShader = THREE.ShaderTerrain["terrain"];
    var uniformsTerrain = THREE.UniformsUtils.clone(terrainShader.uniforms);
    
  //uniformsTerrain["tNormal"].value = null;
  //uniformsTerrain["uNormalScale"].value = 1;
    
    uniformsTerrain["tDisplacement"].value = displacementTexture;
    uniformsTerrain["uDisplacementScale"].value = 1;
    
    uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture;
  //uniformsTerrain[ "tDetail" ].value = null;
    uniformsTerrain[ "enableDiffuse1" ].value = true;
  //uniformsTerrain[ "enableDiffuse2" ].value = true;
  //uniformsTerrain[ "enableSpecular" ].value = true;

  //uniformsTerrain[ "uDiffuseColor" ].value.setHex(0xcccccc);
  //uniformsTerrain[ "uSpecularColor" ].value.setHex(0xff0000);
  //uniformsTerrain[ "uAmbientColor" ].value.setHex(0x0000cc);

  //uniformsTerrain[ "uShininess" ].value = 3;
  //uniformsTerrain[ "uRepeatOverlay" ].value.set(6, 6);
    
    // Terrain Material
    var material = new THREE.ShaderMaterial({
        uniforms:uniformsTerrain,
        vertexShader:terrainShader.vertexShader,
        fragmentShader:terrainShader.fragmentShader,
        lights:true,
        fog:true
    });
    
    // Load Tile
    var loader = new THREE.JSONLoader();
    loader.load('models/hextile.js', function(g) {
      //g.computeFaceNormals();
      //g.computeVertexNormals();
        g.computeTangents();
        g.materials[0] = material;
        
        tile = new THREE.Mesh(g, new THREE.MeshFaceMaterial());
        scene.add(tile);
    });

假设

我目前正在考虑为什么这可能会出错的三种可能性:

  1. UV 贴图不适用于我的置换贴图。
  2. 我错误地制作了置换贴图。
  3. 我错过了将位移锁定为仅 Z 的过程中的关键步骤。

当然,秘密选项#4 以上都不是,我真的不知道我在做什么。或上述的任何混合物。

现场示例

您可以在此处查看实时示例。

如果有对此主题有更多了解的人可以指导我,我将不胜感激!

编辑 1:根据建议,我已经注释掉computeFaceNormals()computeVertexNormals(). 虽然它确实略有改进,但网格仍在变形。

4

2 回答 2

4

在您的地形材质中,设置wireframe = true,您将能够看到正在发生的事情。

你的代码和纹理基本上没问题。当您在加载程序回调函数中计算顶点法线时会出现问题。

几何图形外环的计算顶点法线稍微向外点。这很可能是因为computeVertexNormals()它们是通过平均每个相邻面的面法线来计算的,并且模型“边”(黑色部分)的面法线被平均到构成这些顶点的顶点法线计算中“帽”的外圈。

结果,“帽”的外环在位移图下方向外扩展。

编辑:果然,直接从你的模型,外环的顶点法线指向外面。内环的顶点法线都是平行的。也许 Blender 正在使用相同的逻辑来生成顶点法线computeVertexNormals()

顶点法线

于 2012-10-03T20:27:38.153 回答
1

问题是如何构造对象,因为位移沿法线向量发生。

代码在这里。

https://github.com/mrdoob/three.js/blob/master/examples/js/ShaderTerrain.js#L348-350

"vec3 dv = texture2D( tDisplacement, uvBase ).xyz;",

这需要置换纹理的 rgb 向量。

"float df = uDisplacementScale * dv.x + uDisplacementBias;",

这仅需要矢量的红色值,因为 uDisplacementScale 通常为 1.0,而 uDisplacementBias 为 0.0。

"vec3 displacedPosition = normal * df + position;",

这会沿着法线向量移动位置。

所以要解决您更新法线或着色器的问题。

于 2012-10-03T19:32:15.897 回答