0

鏡面ハイライトを実装してみました。問題は、サーフェスから遠くに移動すると、ハイライトがどんどん強くなり、ハイライトのエッジが非常に粗くなることです。表面に近づきすぎると、ハイライトが完全に消えます。

これは私のフラグメント シェーダーの関連部分です。すべての計算はビュー空間にあります。指向性太陽光を使用しています。

// samplers
vec3  normal    = texture2D(normals,   coord).xyz;
vec3  position  = texture2D(positions, coord).xyz;
float shininess = texture2D(speculars, coord).x;

// normalize directional light source
vec3 source;
if(directional) source = position + normalize(light);
else source = light;

// reflection
float specular = 0;
vec3 lookat = vec3(0, 0, 1);
float reflection = max(0, dot(reflect(position, normal), lookat));
int power = 5;
specular = shininess * pow(reflection, power);

// ...

// output
image = color * attenuation * intensity * (fraction + specular);

これは私の照明バッファのスクリーンショットです。一番前のバレルにはスペキュラー ハイライトがまったくなく、遠くにあるバレルは非常に強く輝いていることがわかります。真ん中のバレルは思い通りに点灯。

遠ハイライトが強すぎて近ハイライトが消える

私は何を間違っていますか?

4

2 に答える 2

2

反転した光の方向 (オブジェクトから光源を指す) を使用する代わりに、オブジェクトの位置から反射ベクトルを計算しています。

この図の L の代わりに V を使用するようなものです。

また、光沢は、鏡面反射の寄与を直線的に乗算するものではなく、表現の指数であるべきだと思います。

于 2014-01-23T22:47:54.593 に答える
1

変数の命名はあなたを混乱させていると思います。私が読んでいるものから(あなたがカメラ空間にいて、利き手の知識がないと仮定して)

vec3 lookat = vec3(0, 0, 1);
float reflection = max(0, dot(reflect(position, normal), lookat));

lookatはディレクショナル ライトでposition、実際のlookatです。

normal(おそらくすでに正規化されている)とposition( )が正規化されていることを確認してくださいlookat

混乱の少ないコードは次のようになります。

vec3 light_direction = vec3(0, 0, 1);
vec3 lookat = normalize(position-vec3(0,0,0));
float reflection = max(0, dot(reflect(light_direction, normal), -lookat));

を正規化しないとpositionreflectionバイアスがかかります。positionカメラから離れているとバイアスが強くなるvec3(0,0,0)

lookatが定数ではないことに注意してください。ポジションごとに変わります。lookat = vec3(0,0,1)は、ビュー スペース内の 1 つの位置を向いています。

于 2014-01-24T19:14:32.490 に答える