シェーダーを使用すると、次の結果が得られます。
1つの問題は、鏡面反射光が一種の変形であり、球の三角形が表示されることです。もう1つは、鏡面反射光が表示されるべきではない場所に表示されることです(2番目の画像)。1つのspehereライトは頂点シェーダーで実行され、もう1つはフラグメントで実行されます。
頂点ライトシェーダーは次のようになります。頂点:
// Material data.
uniform vec3 uAmbient;
uniform vec3 uDiffuse;
uniform vec3 uSpecular;
uniform float uSpecIntensity;
uniform float uTransparency;
uniform mat4 uWVP;
uniform mat3 uN;
uniform vec3 uSunPos;
uniform vec3 uEyePos;
attribute vec4 attrPos;
attribute vec3 attrNorm;
varying vec4 varColor;
void main(void)
{
vec3 N = uN * attrNorm;
vec3 L = normalize(uSunPos);
vec3 H = normalize(L + uEyePos);
float df = max(0.0, dot(N, L));
float sf = max(0.0, dot(N, H));
sf = pow(sf, uSpecIntensity);
vec3 col = uAmbient + uDiffuse * df + uSpecular * sf;
varColor = vec4(col, uTransparency);
gl_Position = uWVP * attrPos;
}
断片:
varying vec4 varColor;
void main(void)
{
//vec4 col = texture2D(texture_0, varTexCoords);
//col.r += uLightDir.x;
//col.rgb = vec3(pow(gl_FragCoord.z, 64));
gl_FragColor = varColor;
}
コードから提供されたデータが間違っている可能性があります。uNはワールドマトリックスです(それを実行しても何も変わらないように見えますが、反転も転置もされません)。UWVP-世界観の投影行列。
問題がどこにあるかについてのアイデアをいただければ幸いです。
[編集]これがフラグメントで行われた私の軽い計算です:Vertexシェーダーファイル:
uniform mat4 uWVP;
uniform mat3 uN;
attribute vec4 attrPos;
attribute vec3 attrNorm;
varying vec3 varEyeNormal;
void main(void)
{
varEyeNormal = uN * attrNorm;
gl_Position = uWVP * attrPos;
}
フラグメントシェーダーファイル:
// Material data.
uniform vec3 uAmbient;
uniform vec3 uDiffuse;
uniform vec3 uSpecular;
uniform float uSpecIntensity;
uniform float uTransparency;
uniform vec3 uSunPos;
uniform vec3 uEyePos;
varying vec3 varEyeNormal;
void main(void)
{
vec3 N = varEyeNormal;
vec3 L = normalize(uSunPos);
vec3 H = normalize(L + uEyePos);
float df = max(0.0, dot(N, L));
float sf = max(0.0, dot(N, H));
sf = pow(sf, uSpecIntensity);
vec3 col = uAmbient + uDiffuse * df + uSpecular * sf;
gl_FragColor = vec4(col, uTransparency);
}
[EDIT2] Joakimが指摘したように、フラグメントシェーダーでvarEyeNormalを正規化していませんでした。それを修正した後、フラグメントシェーダーでの結果ははるかに良くなります。また、uEyePosで正規化関数を使用したので、スペキュラーはダークサイドになりません。すべての助けをありがとう。