2013-02-09 50 views
0

我想要一个效果,即具有强烈的太阳反射的金属表面在光线中几乎变成白色。它在第一遍(金属)上进行两遍渲染和叠加混合第二遍(具有接近白色的纹理和最高镜面光)时效果很好。opengl中的多纹理添加剂混合

但是,出于性能,我想切换到多重纹理,但目前还没有这样的东西作为添加剂调合而成,原来只有

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

目前尚不清楚你想在这里实现什么。你试图做的数学是什么? – 2013-02-09 23:37:23

+0

数学是color = tex1 + tex2,或者甚至color = tex1 + tex2 * 2 – Kenobi 2013-02-09 23:50:39

+1

您是否考虑过使用可编程流水线(着色器)?像你这样的问题是它首先在@Kenobi创建的原因。如果你只想添加颜色,'GL_ADD'应该是可用的操作。 – 2013-02-09 23:54:58

回答

1

家伙,我终于写一个着色器用于该目的奇怪的是,我终于没有用添加剂勾兑成功了! (只需更改着色器中的一条线就可以实现这一点),但是扩展了这个想法,以便第二个纹理将成为高光贴图 - 这样纹理将只在镜面光芒击中它!

大多数的效果可以通过事实证明我自己的着色器可以简单地处理一个值镜面反射的远高于可实现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上升镜面性值被strenghtened:

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

渲染用夸张的4倍光泽。现在,您可以看到泥土质感的光芒:

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

还有一个问题 - 为什么地球上我不能使用gl_TexCoord(1) - 结果是没有质感,但像素渲染文物虽然多纹理不工作正常着色器。任何帮助赞赏。