Вопрос

Я пытаюсь нарисовать много кругов на сфере с помощью шейдеров.Основной алогрит выглядит следующим образом:

  1. вычислите расстояние от фрагмента (используя его текстурные координаты) до местоположения центра окружности (центр окружности также указан в текстурных координатах).
  2. вычислите угол от фрагмента до центра окружности.
  3. в зависимости от угла, получите доступ к текстуре (в которой 360 пикселей, а красный канал указывает расстояние по радиусу) и извлеките радиус для данного угла
  4. если расстояние от фрагмента до центра окружности меньше полученного радиуса, то цвет фрагмента - красный, в противном случае - синий.

Я бы хотел рисовать ...допустим, 60 красных кругов на синей сфере.У меня есть y шейдеров для работы на один круг, но как сделать 60?Вот что я уже пробовал....

  1. Я передал текстуру данных, которая задает радиус для заданного угла, но я замечаю, что появляются артефакты.Я полагаю, что это связано с линейной интерполяцией, когда я пытаюсь извлечь информацию из текстуры данных, используя:

    float returnV = texture2D(angles, vec2(x, y)).r; 
    

    где angles - текстура данных (sampler2D), которая содержит радиус для данного угла, и x = angle / 360.0 (угол от 0 до 360) и y = 0-60 (y - номер окружности)

  2. Я попытался передать равномерные радиусы с плавающей запятой [360], но я не могу получить доступ к радиусам с динамической индексацией.Я даже попробовал эту кашу ...

    getArrayValue(int index) {
      if (index == 0) {
        return radii[0];
      }
      else if (index == 1) {
        return radii[1];
      }
    

    и так далее ...

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

Спасибо!!!

~Болт

Это было полезно?

Решение

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

это фрагмент программы.это не основная программа, но вы можете добавить ее в свою программу.попробуй это...

на данный момент вы можете задать несколько единообразных параметров в жестком коде.

uniform float showCircle;
uniform float radius;
uniform vec4 mousePosition;

varying vec3 vertexCoord;

void calculateTerrainCircle(inout vec4 pixelColor)
{
 if(showCircle == 1)
 {  
    float xDist = vertexCoord.x - mousePosition.x;
    float yDist = vertexCoord.y - mousePosition.y;

    float dist = xDist * xDist + yDist * yDist;
    float radius2 = radius * radius;

    if (dist < radius2 * 1.44f && dist > radius2 * 0.64f)
    {
        vec4 temp = pixelColor;

        float diff;
        if (dist < radius2)
            diff = (radius2 - dist) / (0.36f * radius2);
        else
            diff = (dist - radius2) / (0.44f * radius2);

        pixelColor = vec4(1, 0, 0, 1.0) * (1 - diff) + pixelColor * diff;   

        pixelColor = mix(pixelColor, temp, diff);
    }               
}   
}

и в вершинном шейдере вы добавляете:

varying vec3 vertexCoord;

void main()
{
    gl_Position = ftransform();

    vec4 v = vec4(gl_ModelViewMatrix * gl_Vertex);
    vertexCoord = vec3(gl_ModelViewMatrixInverse * v);
}

Другие советы

уфукгун, если вы умножаете матрицу на ее обратную, вы получаете тождество.
Ваш;

vec4 v = vec4(gl_ModelViewMatrix * gl_Vertex);
vertexCoord = vec3(gl_ModelViewMatrixInverse * v);

следовательно, эквивалентно

vertexCoord = vec3(gl_Vertex);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top