Вопрос

Резюме

Я пытаюсь применить карту смещения (карту высоты) к довольно простому объекту (шестиугольной плоскости), и у меня получаются некоторые неожиданные результаты.Я использую оттенки серого, и поэтому у меня сложилось впечатление, что моя карта высот должна влиять только на значения Z моей сетки.Однако карта смещения, которую я создал, растягивает сетку по плоскостям X и Y.Кроме того, похоже, что он не использует созданное мной UV-отображение, к которому успешно применяются все остальные текстуры.

Модель и УФ-карта

Вот эталонные изображения моей гексагональной сетки и соответствующей ей УФ-карты в Blender.

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. УФ-карта не применяется к моей карте смещения.
  2. Я неправильно составил карту смещения.
  3. Я пропустил важный шаг в процессе, который зафиксировал бы смещение только на Z-значение.

И, конечно, секретный вариант №4, который не является ничем из вышеперечисленного, и я просто действительно понятия не имею, что я делаю.Или любая смесь из вышеперечисленного.

Живой пример

Вы можете просмотреть живой пример здесь.

Если бы кто-нибудь, обладающий большими знаниями в этой области, мог направить меня, я был бы очень благодарен!

Правка 1:Согласно предложению, я прокомментировал computeFaceNormals() и computeVertexNormals().Несмотря на то, что это привело к небольшому улучшению, сетка все еще деформируется.

Это было полезно?

Решение

В вашем материале terrain установите wireframe = true, и вы сможете видеть, что происходит.

Ваш код и текстуры в принципе в порядке.Проблема возникает, когда вы вычисляете нормали вершин в функции обратного вызова загрузчика.

Вычисленные нормали вершин для внешнего кольца вашей геометрии указывают несколько наружу.Скорее всего, это связано с тем, что в computeVertexNormals() они вычисляются путем усреднения нормалей граней каждой соседней грани, а нормали граней "сторон" вашей модели (черная часть) усредняются при вычислении нормалей вершин для тех вершин, которые составляют внешнее кольцо "шапки".

В результате внешнее кольцо "колпачка" расширяется наружу под картой смещения.

РЕДАКТИРОВАТЬ:Конечно же, прямо из вашей модели нормали вершин внешнего кольца указывают наружу.Все нормали вершин для внутренних колец параллельны.Возможно, Blender использует ту же логику для генерации вершинных нормалей, что и computeVertexNormals() делает.

vertex normals

Другие советы

Проблема в том, как создан ваш объект, потому что смещение происходит вдоль нормального вектора.

код здесь.

https:// github.com / mrdoob / trey.js / blob / master / Примеры / js / saderterraina.js # l348-350

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

Это принимает вектор RGB текстуры смещения.

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

Это принимает только красное значение вектора, потому что UdisplaceementsCaleCaleCaleCale обычно составляет 1,0, а UDisplaceBias составляет 0,0.

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

Это вытесняет порядок вдоль нормального вектора.

Так, чтобы решить вас либо обновлять нормали или шейдер.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top