Карта смещения UV-карта?

Резюме

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

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

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

Гексагональная модель и 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(). Несмотря на небольшое улучшение, сетка все еще деформируется.


person rrowland    schedule 03.10.2012    source источник


Ответы (2)


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

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

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

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

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

нормали вершин

person WestLangley    schedule 03.10.2012
comment
Я установил каркас, который был полезен для устранения неполадок. На самом деле я закомментировал computeFaceNormals и computeVertexNormals, но деформация, похоже, все еще происходит. Вы можете подтвердить это по по той же ссылке ( Он обновлен). Возможно, эти вычисления происходят в другом месте по умолчанию? - person rrowland; 04.10.2012
comment
Это был довольно подробный ответ на ваш первоначальный вопрос. Теперь вы изменили код, и вопрос... В вашей модели уже есть нормали, так что, скорее всего, она использует их, поскольку вы закомментировали расчет нормалей. Просто научитесь устанавливать нормали вершин так, как вы хотите. Остальная часть вашего кода выглядит хорошо для меня. :-) - person WestLangley; 04.10.2012
comment
Это был довольно подробный ответ, и я ценю его. Единственные изменения, которые я внес, были предложенными вами, и я сделал их, чтобы показать, что они на самом деле не решают проблему. У меня идеально плоская плоскость в Blender, и если нормали генерируются неправильно, я понятия не имею, как и почему. Если бы вы могли помочь мне найти решение (отображение смещения, как предполагалось), возможно, обновив свой ответ, включив в него ресурсы, относящиеся к правильному созданию нормалей вершин, я был бы очень признателен и мог бы считать это полным ответом. - person rrowland; 04.10.2012
comment
rowland просто найдите каждую вершину с zindex 0,538017 в вашей модели и задайте им vertexnormals 0,0,1 - person Gero3; 04.10.2012
comment
@Gero3 Gero3 Спасибо, что откликнулись. Я вам должен. - person WestLangley; 04.10.2012
comment
@rrowland Вы задаете хорошие вопросы - вот почему я приложил усилия, чтобы исследовать это для вас. Но, при всем уважении, добавлять новые вопросы постфактум некорректно. Пожалуйста, создайте новый пост, если вам нужна дополнительная помощь. (Я не использовал Blender, поэтому не могу вам с этим помочь.) - person WestLangley; 04.10.2012
comment
Спасибо за дальнейшее разъяснение с вашим ответом. Я просмотрел несколько руководств по Blender и нашел вариант отображения нормалей, который иллюстрировал те же самые неправильно направленные нормали, что и ваша красивая визуализация. Я смог решить эту проблему, создав чрезвычайно тонкий слой вокруг внешнего слоя плоскостей, используя подразделение и исключив его из UV-карты, выровняв нормали. Спасибо за помощь, надеюсь, я вас не обидел! Я бы не смог решить эту проблему без вашего подробного ответа. - person rrowland; 04.10.2012

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

код здесь.

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

Это смещает позицию вдоль нормального вектора.

поэтому, чтобы решить, вы либо обновляете нормали, либо шейдер.

person Gero3    schedule 03.10.2012
comment
Я хотел бы придерживаться стандартов и использовать предоставленный шейдер, а не настраивать свой собственный, если это возможно. Не могли бы вы порекомендовать метод предоставления моих собственных нормалей или исправления сгенерированных? - person rrowland; 04.10.2012