摘要

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

模型和UV地图

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

Hexagonal Model and UV Map

漫反射和位移纹理

这些是我通过三个应用到我的网格的漫反射和位移贴图纹理。JS的。

Hexagonal Diffuse and Displacement Textures

渲染器

当我渲染没有位移图的平面时,您可以看到六边形平面停留在线条内。但是,当我添加位移图时,它显然会影响顶点的X和Y位置,而不是仅影响Z,将平面扩展到线条上。

Hexagonal Plane Renders -- With & Without Displacement Map

密码

这是相关的三个。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,这不是上述的,我只是 真的 不知道我在做什么。或前述的任何混合物。

活的例子

您可以查看现场示例 这里.

如果有更多关于这个问题的知识的人可以指导我,我将非常感激!

编辑1:根据建议,我已经评论了 computeFaceNormals()computeVertexNormals().虽然它做了一个轻微的改进,网格仍然是扭曲。

有帮助吗?

解决方案

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

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

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

结果,"帽"的外环在位移图下向外膨胀。

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

vertex normals

其他提示

问题是您的对象的构造方式如何沿着正常矢量发生位移。

代码在这里。

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;",
.

这沿着正常矢量取代了帖子。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top