мультитекстурное смешивание присадок в opengl

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

Однако для повышения производительности я хочу перейти на MultiTexturing, но там нет такого понятия, как аддитивное смешивание, только

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,  GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

ни один из них не работает в качестве аддитивной смеси. 🙁

Мой второй вопрос: есть ли возможность сделать вторую текстуру более блестящей, чем первая текстура в том же треугольнике? Кажется, что использование glMaterial переопределяет материал другой текстуры.

может ли решение быть хорошим glTexEnvi — хаком, который симулирует эффект текстуры с сильным блеском?

0

Решение

ребята, я наконец сделал это, написав шейдер для этой цели! Как ни странно, я, наконец, не использовал аддитивное смешивание (просто измените одну строку в шейдере, чтобы добиться этого всерьез), но расширил идею так, чтобы вторая текстура была зеркальной картой — так, чтобы ее текстура была видна только тогда, когда зеркально свет поражает это!

Большая часть эффекта может быть достигнута благодаря тому факту, что мой собственный шейдер может просто обработать значение для зеркальность намного выше 1 — злой OpenGL обрезал бы его до 1, не спрашивая 🙁

GLfloat mat_specular[] ={ 2, 2, 2, 1 }; glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular); //works here :-)

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

   vs = const_cast<char *>(
"varying vec4 diffuse, ambient;""varying vec3 normal, lightDir, halfVector;""uniform float time;""void main(void){""normal = normalize(gl_NormalMatrix * gl_Normal);"  //Transform Normal into Eye Space
"lightDir = normalize(vec3(gl_LightSource[0].position));""halfVector = normalize(gl_LightSource[0].halfVector.xyz);""diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;""ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient + gl_FrontMaterial.ambient * gl_LightModel.ambient;""gl_TexCoord[0]  = gl_MultiTexCoord0;""gl_Position = ftransform();"     //Apply Changes
"}") ;

И фрагментный шейдер:

fs =const_cast<char *>(
"uniform sampler2D tex1;""uniform sampler2D tex2;""varying vec4 diffuse,ambient;""varying vec3 normal, lightDir, halfVector;""void main() {""vec3 n,halfV,colortexel,colorfragment;""vec4 texel,specularmap;""float NdotL,NdotHV,alphatexel,alphafragment;\n""colorfragment = ambient.rgb;"    //initialize color with ambient part
"alphafragment = gl_FrontMaterial.diffuse.a;""n = normalize(normal);"   //copy to write
"NdotL = max(dot(normal, lightDir), -0.1);""specularmap = texture2D(tex2,gl_TexCoord[0].st);"   //MUST Be started first!
"texel = texture2D(tex1,gl_TexCoord[0].st*2.0);"
"if (NdotL>=-0.1) {""colorfragment += diffuse.rgb * NdotL;""halfV = normalize(halfVector);""NdotHV = max (dot(n,halfV),0.0);""colorfragment += gl_FrontMaterial.specular.rgb * specularmap.rgb * gl_LightSource[0].specular.rgb * pow(NdotHV, gl_FrontMaterial.shininess);""}"
"colortexel = texel.rgb; alphatexel = texel.a;""gl_FragColor = vec4(colortexel * colorfragment, alphatexel * alphafragment);""}");

Это совсем не оптимизировано, и на данный момент это просто подтверждение концепции без художественного мастерства, но вот результат:

Рендеринг без каких-либо шейдеров, но мультитекстура на «модулирование». Вы можете увидеть немного грязи на сосуде, но слабое зеркальное освещение:

http://i.stack.imgur.com/8whUC.jpg

Рендеринг с помощью шейдеров — грязь есть, хотя на этом снимке не видно. Сильный зеркальный свет, который можно даже усилить, увеличив значение зеркальности в glMaterialfv:

http://i.stack.imgur.com/IpnTa.jpg

Оказывается с преувеличенной 4x блеск. Теперь вы можете увидеть текстуру грязи в сиянии:

http://i.stack.imgur.com/MPAm3.jpg

Остается один вопрос — почему я не могу использовать gl_TexCoord (1) — в результате получаются не текстуры, а артефакты рендеринга пикселей, хотя мультитекстурирование прекрасно работает без шейдера. Любая помощь приветствуется.

1

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

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