Я пытаюсь перепрофилировать пример шейдера высотной карты, найденный here, в том, что будет работать с 32-битной точностью вместо 8. Код незавершенного выполнения находится на github: https://github.com/bgourlie/three_heightmapРеализация 32-битного шейдера вершинной вершины вершин в трехjs
Карта высот создается в .NET. Высоты находятся в пределах 0f ... 200F и преобразуется в значение 32-битного цвета (Color struct Unity в) с использованием следующего метода:
private static Color DepthToColor(float height)
{
var depthBytes = BitConverter.GetBytes(height);
int enc = BitConverter.ToInt32(depthBytes, 0);
return new Color((enc >> 24 & 255)/255f, (enc >> 16 & 255)/255f, (enc >> 8 & 255)/255f,
(enc & 255)/255f);
}
Цветовые данные кодируются как PNG, с результатом глядя, как это:
вершинный шейдер принимает эти данные изображения и coverting значения RBGA обратно к исходному значению высоты (с использованием техники ответил на мой вопрос here):
uniform sampler2D bumpTexture; // defined in heightmap.js
varying float vAmount;
varying vec2 vUV;
void main()
{
vUV = uv;
vec4 bumpData = texture2D(bumpTexture, uv);
vAmount = dot(bumpData, vec4(1.0, 255.0, 65025.0, 16581375.0));
// Uncomment to see a "flatter" version
//vAmount = dot(bumpData, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/160581375.0));
// move the position along the normal
vec3 newPosition = position + normal * vAmount;
gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
}
Результат, безусловно, перепутались:
я могу сделать это льстить, изменив эту строку:
vAmount = dot(bumpData, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
Это даст мне гораздо более плоский образ, который по крайней мере показывает хороший контур сгенерированной местности, но с почти полностью плоской плоскостью (имеется небольшое, хотя и незаметное изменение):
Я предполагаю, что я делаю несколько вещей неправильно, я просто не знаю, что. Я не уверен, правильно ли кодирую исходный флоат. Я не уверен, правильно ли я его декодирую в вершинном шейдере (значение, которое я получаю, конечно, находится за пределами диапазона 0 ... 200). Я также не очень опытен в 3D-графике в целом. Поэтому любые рекомендации относительно того, что я делаю неправильно, или вообще, как добиться этого, будут очень признательны.
Опять же, самодостаточная работа в прогрессе код можно найти здесь: https://github.com/bgourlie/three_heightmap
Шум в «png» карты высоты определенно выглядит неправильно. Даже при использовании всех каналов для глубины вы должны хотя бы иметь гладкий градиент в пределах одного цвета, и если у вас есть шум, это не должно быть экстремальным. В связи с этим я предлагаю сузить поиск до той части, где вы создаете карту высот. Я бы предположил, что вы где-то попали в неинициализированную память. –
Я предположил, что шум был результатом использования альфа-канала (при этом ожидая некоторый шум). Вот результирующая карта высот без использования альфа-канала: http://i.imgur.com/l3zcpcG.jpg. По общему признанию, градиенты все еще не выглядят правильно, учитывая высоты, которые они должны представлять. –
Извините, я думаю, что у меня было неправильное предположение: белые точки на самом деле прозрачные пиксели? Первоначально у png была прозрачная прозрачность? Вы сохранили его как png-8, чтобы показать его здесь, и альфа-канал был потерян? Это объясняет белые точки. Если вы использовали это экспортированное изображение для шейдера, вам нужно будет проверить создание PNG, если вы можете выбирать между 8 и 24. (Использование png с альфа-каналом может быть проблемой в любом случае, поскольку сжатие может создавать проблемы в областях, где изображение, если оно полностью прозрачно). –