距離によって強さが変わるライトの実装に成功した。
ある地点における光の強さは、光源までの距離を d 、一定減衰率を kc 、1時減衰率を k1 、2時減衰率を k2 とすると以下の式で表すことができます。
減衰率kc, k1, k2はそれぞれGL側(ホストプログラム)からシェーダ側に送ることができる。
以下はホスト側のプログラム
5 | glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, kc); |
6 | glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, k1); |
7 | glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, k2); |
んで、フラグメントシェーダ側の記述は以下のとおり
07 | vec3 L = gl_LightSource[0].position.xyz - P; |
16 | float attenuation = 1.0 / (gl_LightSource[0].constantAttenuation |
17 | + gl_LightSource[0].linearAttenuation * d |
18 | + gl_LightSource[0].quadraticAttenuation * d * d); |
20 | vec3 N = normalize(N); |
23 | vec4 ambient = gl_FrontLightProduct[0].ambient; |
24 | float dotNL = dot(N, L); |
27 | vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL); |
29 | vec3 V = normalize(-P); |
30 | vec3 H = normalize(L + V); |
31 | float powNH = pow (max(dot(N, H), 0.0), gl_FrontMaterial.shininess); |
38 | vec4 specular = gl_FrontLightProduct[0].specular * powNH; |
41 | gl_FragColor = ambient + diffuse + specular; |
44 | gl_FragColor *= attenuation; |
まあほとんど教本のまんまなんですが・・・。
gl_LightSource[0].constantAttenuation
gl_LightSource[0].linearAttenuation
gl_LightSource[0].quadraticAttenuation
がそれぞれホスト側で設定した減衰係数です。
画像の式に当たるのがコメントで減衰係数と書いてあるところ。んで、最後にカラー値を統合したgl_FragColorに減衰係数をかけて明るさを確定してるわけですね。このあたりはレイトレースでやったことがかなり活きてるかんじ。
0 件のコメント:
コメントを投稿