Смешивание нескольких текстур в 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

или, альтернативно, вы можете хорошо взглянуть на свою геометрию. Если у вас есть комбинация больших треугольников и крошечных, у вас будет неравный разброс данных, и так как ваши данные на вершину, у вас будет больше деталей, где это больше геометрии. В таком случае вы, вероятно, захотите сделать то, что делают все остальные, и отделить текстурирование от геометрии с помощью карт смешивания. Они могут иметь низкое разрешение и не должны увеличивать потребление памяти или время выполнения шейдеров.