Вопрос
Я пытаюсь нарисовать много кругов на сфере с помощью шейдеров.Основной алогрит выглядит следующим образом:
- вычислите расстояние от фрагмента (используя его текстурные координаты) до местоположения центра окружности (центр окружности также указан в текстурных координатах).
- вычислите угол от фрагмента до центра окружности.
- в зависимости от угла, получите доступ к текстуре (в которой 360 пикселей, а красный канал указывает расстояние по радиусу) и извлеките радиус для данного угла
- если расстояние от фрагмента до центра окружности меньше полученного радиуса, то цвет фрагмента - красный, в противном случае - синий.
Я бы хотел рисовать ...допустим, 60 красных кругов на синей сфере.У меня есть y шейдеров для работы на один круг, но как сделать 60?Вот что я уже пробовал....
Я передал текстуру данных, которая задает радиус для заданного угла, но я замечаю, что появляются артефакты.Я полагаю, что это связано с линейной интерполяцией, когда я пытаюсь извлечь информацию из текстуры данных, используя:
float returnV = texture2D(angles, vec2(x, y)).r;
где angles - текстура данных (sampler2D), которая содержит радиус для данного угла, и x = angle / 360.0 (угол от 0 до 360) и y = 0-60 (y - номер окружности)
Я попытался передать равномерные радиусы с плавающей запятой [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);