GLSL шейдеры текстуры альфа-брызги

Я пытаюсь сделать шейдер, используемый для загрузки четырех плиток с деталями текстур на местности, объединяя их в пятое изображение, где r, g, b и компоненты используются, чтобы определить, сколько каждой текстуры следует смешать вместе.
Смешивание работает нормально, но когда я пытаюсь добавить свое изображение «mixmap», оно терпит неудачу из-за проблемы с координатами текстуры.

Во-первых, вот шейдеры:
Вершинный шейдер

void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

Фрагмент шейдера

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;

varying vec3 pos;

void main()
{

vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
vec4 mixmapTexel = texture2D(Mixmap, gl_TexCoord[0].st).rgba;

texel0 *= mixmapTexel.r;
texel1 = mix(texel0,  texel1, mixmapTexel.g);
texel2 = mix(texel1, texel2, mixmapTexel.b);
gl_FragColor = mix(texel2, texel3, mixmapTexel.a);
}

Как я уже сказал, смешивание отлично работает.
Проблема заключается в том, что значения, считанные из моей карты смешивания, не являются правильными.

Вот еще несколько объяснений того, что я делаю.
Я строю пейджинговую систему местности, загружающую местность с карт высот.
Затем я хочу использовать свое изображение микш-карты для представления с помощью компонентов rgba, сколько каждой текстуры следует смешивать в соответствии с высотой.

  • это вода

  • г песок

  • б трава

  • это рок

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

Смешивание между ящиком и текстом

Вот пример смешивания между ящиком и текстом, чтобы вы могли четко видеть, как применяется текстура.

Теперь, если я использую простое смешанное изображение (наполовину красное, наполовину зеленое), которое должно дать мне ящики с левой стороны ландшафта, а текст справа, я получу
с альфа-сплаттингом argb
пример изображения RGBA

Вот часть процесса генерации ландшафта: он перебирает массив вершин и создает треугольники местности

void TerrainPage::generateDisplayList()
{
// create one display list
mDisplayListIndex = glGenLists(1);

// compile the display list, store a triangle in it
glNewList(mDisplayListIndex, GL_COMPILE);
glFrontFace( GL_CW  ); //   Vertex are added clockwise. Used to calculate normals
std::vector<Vertex>::iterator it;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
texShader.enable();
texShader.bindTexture(mTexture0, "Texture0", 0);
texShader.bindTexture(mTexture1, "Texture1", 1);
texShader.bindTexture(mTexture2, "Texture2", 2);
texShader.bindTexture(mTexture3, "Texture3", 3);
texShader.bindTexture(mMixmapTexture, "Mixmap", 4);
Vertex v;
int j=0;
glEnable(GL_TEXTURE_2D);
//mTexture.bind();
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i<mVertices.size(); i++) {
if(i%(2*mWidth) == 0) glEnd(); glBegin(GL_TRIANGLE_STRIP);
v = mVertices[i];
glTexCoord2f(v.texcoords[0], v.texcoords[1]);
glVertex3f(v.position[0], v.position[1], v.position[2]);
}
glEnd();
glDisable(GL_TEXTURE_2D);
texShader.disable();
glEndList();
}

При необходимости я могу предоставить больше скриншотов, а также часть своего кода.

В качестве дополнения к предоставленному ответу я попытался сделать это, рассчитав УФ в шейдере.

Во-первых, вот новый шейдер

Вершинный шейдер

varying vec4 VertexPosition;

void main() {

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
}

Фрагмент шейдера

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;

varying vec4 VertexPosition;
float side = 500.;

void main()
{

vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
vec4 mixmapTexel = texture2D(Mixmap, VertexPosition.xz/(2.*side)).rgba;

texel0 *= mixmapTexel.r;
texel1 = mix(texel0,  texel1, mixmapTexel.g);
//texel2 = mix(texel1, texel2, mixmapTexel.b);
//vec4 tx  = mix(texel2, texel3, mixmapTexel.a);
//vec4 tx = mixmapTexel; //vec4(1, 1, 1, 1.);
gl_FragColor = texel1;

//if(test > 250. )
//    gl_FragColor = vec4(1.,1.,1.,1.);
}

И вот результаты

введите описание изображения здесь

Но если я перемещу камеру:

введите описание изображения здесь

Как вы можете видеть, ящик и текст на этот раз бок о бок. Но похоже, что я вычисляю в экранных координатах вместо мировых координат. Должно быть, я снова запутался с системой координат.
Я постараюсь найти правильный! Я просто хочу убедиться, что я в правильном направлении.
Я также поищу координаты мультитекстуры, возможно, будет удобнее, когда я пойму, как это работает;)

6

Решение

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

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

Если вы не понимаете, о чем я говорю, каждая клетка местности получает ультрафиолетовое излучение:
(0,0), (1,0), (0,1) или (1,1).
Это хорошо для ящика и текстурной текстуры, но микскарта должна быть гораздо более дробной и разнообразной.

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

Я думаю, я понял, что не так. Сохраните положение вершины явно. Не умножайте это на modelviewmatrix, то есть:

varying vec4 VertexPosition;

void main() {

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
//VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
VertexPosition = gl_Vertex;
}

Это будет исправлено, извините, я бросил ваш фиксированный шейдер в rendermonkey, и он больше не двигается вместе с камерой. Надеюсь это поможет. Я получил панорамирование, но теперь это выглядит так:

Исправлен рендер

8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]