首页 文章

多组分添加剂混合在opengl中

提问于
浏览
0

我想要一种效果,即具有强烈太阳反射的金属表面在光线下几乎变白 . 它通过两次传递渲染和添加混合第二次传递(具有近乎白色的纹理和最高的镜面光)在第一次传递(金属色)上工作得非常好 .

但是,为了性能,我想切换到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 - hack可以模拟具有强烈光泽的纹理效果吗?

1 回答

  • 1

    伙计们,我终于为此目的写了一个着色器!奇怪的是,我终于没有使用加法混合(只需在着色器中更改一行就可以实现这一点)但扩展了这个想法,使第二个纹理成为镜面反射贴图 - 这样它的纹理只有在镜面时才能看到光打它!

    大多数效果都可以通过我自己的着色器可以简单地处理 specularity of much above 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

    呈现夸张的4倍光泽 . 你现在可以在发光中看到污垢纹理:

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

    还有一个问题 - 为什么我不能使用gl_TexCoord(1) - 结果是没有纹理而是像素渲染人工制品虽然多重纹理在没有着色器的情况下工作正常 . 任何帮助赞赏 .

相关问题