Смешивание нескольких текстур в GLSL
это долго, но я обещаю, что это интересно. :)
Я пытаюсь имитировать внешний вид текстурирования другого приложения с помощью jMonkeyEngine. У меня есть список вершин и граней (треугольников), составляющих "ландшафтную сетку", которая должна быть текстурирована примерно с 7-15 различными текстурами (в зависимости от рельефа "ландшафта"). Каждый треугольник имеет связанный с ним текстурный код, означающий, из какой текстуры должен состоять данный треугольник. И конечно, текстуры должны плавно смешиваться между каждой гранью.
поэтому я пытаюсь разработать стратегию, которая позволяет это (которая не использует готовые файлы png Альфа-карты, текстурные Альфы должны быть сделаны во время выполнения). Прямо сейчас я полагаю, что если я вычислю "силу" каждой текстуры в каждой вершине (в шейдере вершин) - путем факторинга типов местности всех соседних граней (пока не знаю, как это сделать) - я должен иметь возможность установить Альфа-значения на основе того, как далеко пиксель от точки вершина. Сгенерированная "Альфа-карта" будет использоваться шейдером фраг для смешивания каждой текстуры на пиксель.
это даже возможно, или я должен смотреть на совершенно другую стратегию? У меня есть код шейдера для приложения, которое я пытаюсь имитировать (но они HLSL, и я использую GLSL), но похоже, что они делают этот шаг смешивания в другом месте:
sampler MeshTextureSampler = sampler_state { Texture = diffuse_texture; AddressU = WRAP; AddressV = WRAP; MinFilter = LINEAR; MagFilter = LINEAR; };
Я не уверен, что это HLSL "MeshTextureSampler", но похоже, что это приложение может быть предварительно смешано все текстуры по мере необходимости и создали единую текстуру для всей сетки на основе данных кода лица / рельефа. В шейдере пикселей / фрагментов все, что они действительно делают, это:
float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);
после этого это просто тени, освещение и т. д.-никакого смешивания текстур вообще, насколько я могу судить, что заставляет меня верить, что эта работа по смешиванию текстур выполняется на CPU заранее, я полагаю. Любые предложения приветствуются.
1 ответов
Если я правильно вас понимаю, вот какой будет мой первый выстрел:
ваша проблема заключается в том, более или менее, как распределить ваше значение на лицо по вершинам. Это фактически похоже на нормальную генерацию на сетке: сначала вы генерируете Нормаль для каждого треугольника, а затем вычисляете их на вершину. Гугл "нормальное поколение", и вы получите там, но вот суть. Для каждого соседнего треугольника найдите коэффициент взвешивания (часто угол угла, который использует вершина, или площадь поверхности треугольника, или комбинация), а затем суммировать значение (будь то нормальное или ваши "сильные стороны"), умноженное на коэффициент взвешивания, до общего результата. Нормализуйся и все.
Итак, у вас есть "сильные стороны" текстуры,которые вы можете отправить в свой шейдер вершин. Современным решением было бы использовать символы и образец массива текстур в пиксельном шейдере после того, как вы немного изменили значения наложения, чтобы дать вам более приятные передачи.
Итак, если я получу ваша проблема правильно:
предварительная обработка:
forearch vertex in mesh
vertexvalue = 0
normalization = 0
foreach adjacent triangle of vertex
angle = calculateAngleBetween3Vertices(vertex,triangle.someothervertex,triangle.theotherothervertex)
vertexvalue += triangle.value * angle
normalization += angle
vertexvalue/=normalization
время подготовки:
передайте значение(ы) каждой вершины в fragmentshader и сделайте это в шейдере фрагментов:
basecolour = 0;
foreach value
basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value)
//this is simple, but we could do better once we have this working
или, альтернативно, вы можете хорошо взглянуть на свою геометрию. Если у вас есть комбинация больших треугольников и крошечных, у вас будет неравный разброс данных, и так как ваши данные на вершину, у вас будет больше деталей, где это больше геометрии. В таком случае вы, вероятно, захотите сделать то, что делают все остальные, и отделить текстурирование от геометрии с помощью карт смешивания. Они могут иметь низкое разрешение и не должны увеличивать потребление памяти или время выполнения шейдеров.