ребята, я, наконец, сделал это, написав шейдер для этой цели! Как ни странно, я, наконец, не использовал аддитивное смешение (просто измените одну строку в шейдере, чтобы добиться этого серьезно), но расширила идею, чтобы вторая текстура была зеркальной картой - так, чтобы ее текстура была видна только тогда, когда зеркальный свет попадает в него!
Большая часть эффекта может быть достигнуто за счет того, что мой собственный шейдер может просто обработать значение для зеркальности намного выше 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
"}") ;
И Fragment Shader:
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);"
"}");
Это совсем не оптимизировано и на данный момент просто доказательство концепции без художественного мастерства, но вот результат:
Render без каких-либо шейдеров, но мультитектура на модуляции. Вы можете увидеть немного грязи на судне, но бедный зеркальная свет:
Вынесено с шейдерами - грязь есть, хотя и не ясно видно на этом снимке. Тяжелая зеркальная свет, который может быть даже укрепился рост зеркальности-значения в glMaterialfv:
Вынесена с преувеличенной 4x блеском. Вы можете увидеть грязь текстуру теперь свечение:
Остается один вопрос - почему на земле я не могу использовать gl_TexCoord (1) - результат не текстуры, но пиксель рендеринг артефактов, хотя мультитекстурирование отлично работает без шейдер. Любая помощь оценивается.
Непонятно, чего вы пытаетесь достичь здесь. Какую математику вы пытаетесь сделать? –
математика цвет = tex1 + tex2 или даже цвет = tex1 + tex2 * 2 – Kenobi
Рассматривали ли вы использование программируемого конвейера (шейдеров)? Проблемы, подобные вашим, были причиной, по которой он был создан в первую очередь @Kenobi. Если вы хотите просто добавить цвета, то «GL_ADD» должен быть доступной операцией. –