繁体   English   中英

opengl中的多纹理添加剂混合

[英]multitexture additive blending in 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-可以模拟具有强烈光泽的纹理效果的技巧?

伙计们,我终于为此目的编写了一个着色器来实现了! 奇怪的是,我最终没有使用加法混合(只需更改着色器中的一条线即可实现这一目标),而是扩展了此想法,使第二个纹理成为镜面贴图-这样,只有当镜面贴图时才可以看到其纹理。轻击中!

大多数效果可以通过以下事实实现:我自己的着色器可以简单地处理镜面反射率的值远高于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)-结果是没有纹理,但像素渲染伪影,尽管没有着色器的多重纹理效果很好。 任何帮助表示赞赏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM