Карта смещения УФ-картирование?
-
13-12-2019 - |
Вопрос
Резюме
Я пытаюсь применить карту смещения (карту высоты) к довольно простому объекту (шестиугольной плоскости), и у меня получаются некоторые неожиданные результаты.Я использую оттенки серого, и поэтому у меня сложилось впечатление, что моя карта высот должна влиять только на значения Z моей сетки.Однако карта смещения, которую я создал, растягивает сетку по плоскостям X и Y.Кроме того, похоже, что он не использует созданное мной UV-отображение, к которому успешно применяются все остальные текстуры.
Модель и УФ-карта
Вот эталонные изображения моей гексагональной сетки и соответствующей ей УФ-карты в Blender.
Диффузные и смещенные текстуры
Это текстуры карты рассеяния и смещения, которые я применяю к своей сетке с помощью 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);
});
Гипотеза
В настоящее время я рассматриваю три возможности относительно того, почему все может пойти не так:
- УФ-карта не применяется к моей карте смещения.
- Я неправильно составил карту смещения.
- Я пропустил важный шаг в процессе, который зафиксировал бы смещение только на Z-значение.
И, конечно, секретный вариант №4, который не является ничем из вышеперечисленного, и я просто действительно понятия не имею, что я делаю.Или любая смесь из вышеперечисленного.
Живой пример
Вы можете просмотреть живой пример здесь.
Если бы кто-нибудь, обладающий большими знаниями в этой области, мог направить меня, я был бы очень благодарен!
Правка 1:Согласно предложению, я прокомментировал computeFaceNormals()
и computeVertexNormals()
.Несмотря на то, что это привело к небольшому улучшению, сетка все еще деформируется.
Решение
В вашем материале terrain установите wireframe = true
, и вы сможете видеть, что происходит.
Ваш код и текстуры в принципе в порядке.Проблема возникает, когда вы вычисляете нормали вершин в функции обратного вызова загрузчика.
Вычисленные нормали вершин для внешнего кольца вашей геометрии указывают несколько наружу.Скорее всего, это связано с тем, что в computeVertexNormals()
они вычисляются путем усреднения нормалей граней каждой соседней грани, а нормали граней "сторон" вашей модели (черная часть) усредняются при вычислении нормалей вершин для тех вершин, которые составляют внешнее кольцо "шапки".
В результате внешнее кольцо "колпачка" расширяется наружу под картой смещения.
РЕДАКТИРОВАТЬ:Конечно же, прямо из вашей модели нормали вершин внешнего кольца указывают наружу.Все нормали вершин для внутренних колец параллельны.Возможно, Blender использует ту же логику для генерации вершинных нормалей, что и computeVertexNormals()
делает.
Другие советы
Проблема в том, как создан ваш объект, потому что смещение происходит вдоль нормального вектора.
код здесь.
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;",
.
Это вытесняет порядок вдоль нормального вектора.
Так, чтобы решить вас либо обновлять нормали или шейдер.