0

太陽の反射が強い金属表面が、光の中で仮想的に白くなるような効果が欲しいです。2 パス レンダリングと、1 番目のパス (メタリック) の上に 2 番目のパス (ほぼ白いテクスチャと最高のスペキュラー ライト) を加算ブレンドすると、かなりうまく機能しました。

ただし、パフォーマンスのために、マルチテクスチャリングに切り替えたいのですが、そこには加算ブレンディングのようなものはありません。

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);

これらはいずれも添加ブレンドとして機能しません。:-(

私の 2 番目の質問: 同じ三角形で、2 番目のテクスチャを最初のテクスチャよりも光沢のあるものにする可能性はありますか? glMaterial を使用すると、他のテクスチャのマテリアルがオーバーライドされるようです。

解決策はおそらく良い glTexEnvi - 強い光沢のあるテクスチャの効果をシミュレートするハックでしょうか?

4

1 に答える 1

1

みんな、私はついにその目的のためにシェーダーを書いてそれを作りました! 奇妙なことに、私は最終的に加算ブレンディングを使用しませんでした (それを真剣に達成するためにシェーダーの 1 行を変更するだけです) が、2 番目のテクスチャがスペキュラー マップになるようにアイデアを拡張しました。光が当たる!

ほとんどの効果は、私自身のシェーダーが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

1 つの疑問が残ります。一体なぜ gl_TexCoord(1) を使用できないのでしょうか。マルチテクスチャリングはシェーダーなしで正常に機能しますが、結果はテクスチャではなくピクセル レンダリング アーティファクトになります。どんな助けでも感謝します。

于 2013-02-11T00:06:36.520 に答える