Смешивание нескольких текстур в GLSL - PullRequest
6 голосов
/ 03 июля 2011

Это долго, но я обещаю, что это интересно.:)

Я пытаюсь имитировать внешний вид текстур другого приложения, используя jMonkeyEngine.У меня есть список вершин и граней (треугольников), составляющих «сетку ландшафта», которая должна быть текстурирована примерно с 7-15 различными текстурами (в зависимости от рельефа местности).С каждым треугольником связан текстурный код, указывающий, из какой текстуры должен в основном состоять данный треугольник.И, конечно, текстуры должны плавно смешиваться между каждой гранью.

Поэтому я пытаюсь разработать стратегию, которая позволяет это (которая НЕ использует предварительно созданные файлы PNG альфа-карты, необходимо сделать альфа текстуры).во время выполнения).Прямо сейчас я вычисляю, рассчитываю ли я «прочность» каждой текстуры в каждой вершине (в вершинном шейдере) - с учетом типов местности всех соседних граней (пока не знаю, как это сделать) - я должен быть в состоянииустановить альфа-значения на основе того, как далеко пиксель от вершины.Сгенерированная «альфа-карта» будет использоваться фрагментным шейдером для смешивания каждой текстуры на пиксель.

Возможно ли это вообще, или мне следует взглянуть на совершенно другую стратегию?У меня есть шейдерный код для приложения, которое я пытаюсь имитировать (но это HLSL, а я использую GLSL), но кажется, что они делают этот шаг смешивания в другом месте:

    sampler MeshTextureSampler = sampler_state { Texture = diffuse_texture; AddressU = WRAP; AddressV = WRAP; MinFilter = LINEAR; MagFilter = LINEAR; }; 

IЯ не уверен, что это за HLSL "MeshTextureSampler", но похоже, что это приложение могло предварительно смешать все текстуры по мере необходимости и создать единую текстуру для всей сетки на основе данных кода лица / ландшафта.В пиксельном / фрагментном шейдере все, что они действительно делают, это:

float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);

После этого это просто тени, освещение и т. Д. - насколько я могу судить, никакого смешения текстур вообще нет,Полагаю, я полагаю, что эта работа по смешиванию текстур выполняется на процессоре заранее.Любые предложения приветствуются.

1 Ответ

3 голосов
/ 04 июля 2011

Если я вас правильно понимаю, вот что мой первый выстрел будет:

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

Итак, у вас есть «сильные стороны» текстур, которые вы можете отправить в ваш вершинный шейдер. Современное решение состоит в том, чтобы использовать символы и сэмплировать массив текстур в пиксельном шейдере, после того как вы немного подстроили значения наложения, чтобы получить более приятные передачи.

Итак, если я правильно понял вашу проблему:

Preprocess:

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

Время рендеринга:

передать значение (я) каждой вершины во фрагментный шейдер и сделать это в фрагментном шейдере:

basecolour = 0;
foreach value    
   basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value)
   //this is simple, but we could do better once we have this working

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

...