Я хотел бы знать, как сделать этот эффект выделения объединенного круга. Вот изображения для иллюстрации:
В основном я ищу этот эффект:
Как добиться эффекта слияния кругов? Я не нашел никакого объяснения относительно этого эффекта. Я знаю, что для проецирования этих текстур я могу разработать систему декалей, но я не знаю, как создать эффект слияния.
По возможности я ищу чисто шейдерное решение.
Ответы:
Есть несколько трюков, которые вы можете сделать:
Z-буфер
После того, как вы отрендерили все остальные объекты, для каждого блока визуализируйте прозрачный круг меньшего размера с максимальным значением Z. Затем визуализируем круги выбора надписей на земле. Так как они находятся ниже в Z-порядке, они будут отброшены, когда находятся под юнитами.
Быть полностью прозрачным означает, что круг записывается только в Z-буфер (максимальное значение Z). Теперь, когда вы отрисовываете декали, они проверяются по значениям буфера Z, и если они проходят тест, они визуализируются (что происходит только за пределами кругов)
трафарет
То же, что и в предыдущем подходе, но на этот раз используйте трафаретный буфер. Визуализируйте меньшие круги для юнитов с некоторым значением трафарета, а затем визуализируйте декали выбора. Настройте трафарет, чтобы отменить любые элементы с вашим значением трафарета.
источник
Вы можете, например, проверить в пиксельном шейдере рендеринга декаль, если есть пересечение с любыми другими декалями, и убить пиксель, если так. Это довольно эффективно сделать для этого вида круглых наклеек.
источник
Вы имеете в виду эти синие круги на земле?
Возможно, есть более разумный способ сделать это, но рассмотрим мое решение в качестве примера того, как это можно сделать. Рендеринг ваших кругов в отдельную пустую текстуру размером с экран. На данный момент вы можете смешать их вместе, как вы хотите. В зависимости от ваших потребностей вы можете написать полный цвет или просто информацию о том, что круг присутствует в данном пикселе. Однако вам обязательно понадобится информация о глубине для каждого пикселя, который вы пишете, если вы хотите получить эффект Z-теста.
Когда вы визуализируете ландшафт после предыдущего шага, вы можете отобрать ранее созданную текстуру, используя координаты экрана в пиксельном шейдере, в качестве UV. Теперь вы знаете, что круг должен или не должен проецироваться на заданный пиксель местности. Однако в этом случае он будет работать так, как если бы Z-тест был отключен, поэтому местность не может скрыть ни одного круга. Если вы хотите, чтобы местность скрывала окружности за ней, выполните проверку глубины, прежде чем смешивать окружность с текстурой местности. Вы можете использовать небольшой уклон, чтобы включить рендеринг кругов, которые находятся чуть-чуть под землей, но вы все равно хотели бы, чтобы они отображались.
Редактировать: теперь, чтобы получить эффект объединенных кругов, вам нужно сделать следующее: при рендеринге на отдельную текстуру, вам нужно проверить, есть ли уже отрисованный круг, где вы пытаетесь создать новый. (Проверьте, есть ли у текстуры значение), если это так, сотрите этот пиксель. Это должно дать эффект «контура», когда два или более кругов перекрываются. Чтобы это работало правильно, вам нужно будет выполнить этот тест только для внутренней части круга, а не для границы. Таким образом, при рендеринге кругов записывайте в выходную текстуру какое-то конкретное значение, которое указывает, что внутри находится круг. Тогда вам просто не нужно ничего рендерить на круг внутри, и вы должны быть хорошими.
Edit2: для вашего простого красного / зеленого примера: перед рендерингом какого-либо пикселя проверьте, не является ли этот пиксель уже зеленым. Если это так, не визуализируйте. Это сделает свое дело. Фактически, при записи в текстуру вы можете даже использовать красный / зеленый снаружи / внутри круга, а затем при рендеринге ландшафта читать эти значения и преобразовывать их в желаемый цвет.
Если мой ответ окажется слишком абстрактным, дайте мне знать.
источник
Есть несколько вариантов. Как правило, трафаретные буферы часто очень удобны, когда необходимо замаскировать определенный рисунок, например, контур, где круги перекрываются в вашем примере.
В этом случае, я думаю, это можно сделать так же легко без буфера трафарета. Вы можете использовать буфер глубины, чтобы устранить контур, где круги перекрываются. Идея состоит в том, что вы рисуете внутреннюю часть кругов только в буфере глубины (поскольку мы не хотим видеть внутреннюю часть), а затем рисуете контур. Таким образом, часть контура, которая перекрывается с другим кругом, будет удалена тестом глубины.
Единственное предостережение в том, что вы должны быть осторожны с глубокой борьбой. Вы можете использовать небольшое смещение, чтобы удостовериться, что контуры на самом деле находятся за внутренней частью, и будут устранены с помощью теста глубины. Альтернативой было бы использовать
glPolygonOffset()
.Допустим, у вас есть две окружности, параллельные плоскости xy, с центрами в точках (x1, y1, z) и (x2, y2, z). И у вас есть эти функции рисования:
Последовательность рисования выглядит следующим образом с
delta
небольшим смещением:источник
Вне моей головы, если эти надписи нарисованы как диски, я бы проверял каждый круг на предмет пересечения с каждым другим кругом и помещал точки пересечения в массив. Затем нарисуйте дуги, которые не находятся внутри пересечения. Это не шейдерное решение.
источник
Вы хотите трафарет здесь. Ваш первый проход отображает круги в буфере трафарета. Второй проход визуализирует видимый контур , где бы ни был изменен буфер трафарета . Второй проход должен использовать геометрию, которая больше, чем первый проход, в этом случае достаточно простого линейного скаляра.
Хотя решение, которое я имею для рисования контуров здесь, - это больше, чем нужно (так как этот шейдер превращает каждое ребро сетки в полный квад), он использует следующий подход: рисование исходной модели в буфере трафарета, а затем рендеринг увеличенной версии, где буфер трафарета по-прежнему равен 0.
источник