置换贴图UV贴图?

时间:2012-10-03 18:58:34

标签: webgl three.js textures uv-mapping heightmap

摘要

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

模型和UV地图

以下是我的六边形网格的参考图像及其在Blender中的相应UV地图。

Hexagonal Model and UV Map

漫反射和位移纹理

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

Hexagonal Diffuse and Displacement Textures

呈现

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

Hexagonal Plane Renders -- With & Without Displacement Map

代码

这是相关的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-only的过程中的关键步骤。
  4. 当然,秘密选项#4不属于上述情况,我只是真的不知道我在做什么。或上述任何混合物。

    实例

    您可以查看实时示例here

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

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

2 个答案:

答案 0 :(得分:4)

在地形资料中,设置wireframe = true,您就能看到正在发生的事情。

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

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

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

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

vertex normals

答案 1 :(得分: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;",

这取代了法线向量的位置。

所以要解决你更新法线或着色器。