Three.js で光るハロー効果を生成するシェーダーを作成しようとしています。私の現在の試みはここにあります: http://stemkoski.github.io/Three.js/Shader-Halo.html
現在のシェーダー コードは次のとおりです。
<script id="vertexShader" type="x-shader/x-vertex">
varying vec3 vNormal;
void main()
{
vNormal = normalize( normalMatrix * normal );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-vertex">
varying vec3 vNormal;
void main()
{
float intensity = pow( 0.7 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) ), 4.0 );
gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;
}
</script>
オブジェクトがシーンの中心にある限り、これは問題なく機能します。ズームまたはパンの後、ハロー効果は強度が変化したり、偏って見えたりします。
これがなぜなのか、数学的に理解できたと思います。このコードでは、グロー効果の強度は、メッシュに対する法線ベクトルの z 座標によって決定されます。これは、ビューアーに面しているベクトルであるためです。強度を計算する前に、同様の変換を (0,0,1) に適用します。
こうしてたどり着いた
<script id="vertexShader" type="x-shader/x-vertex">
varying vec3 vNormal;
varying vec4 vector;
void main()
{
vNormal = normalize( normalMatrix * normal );
vector = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 1.0, 0.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-vertex">
varying vec3 vNormal;
varying vec4 vector;
void main()
{
vec4 v = vec4( vNormal, 0.0 );
float intensity = pow( 0.7 - dot( v, vector ), 4.0 );
gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;
}
</script>
原点にあるときでも元のシェーダーとはまったく異なって見え、シーンをズームおよびパンすると外観が変化し続けます。
私は途方に暮れています。シーンをズーム/パンするときにこのシェーダーによって生成される外観が変わらないように、法線ベクトルを正しく変換する方法 (または他の変更を行う必要がある) を知っている人はいますか?
[アップデート]
http://john-chapman-graphics.blogspot.com/2013/01/good-enough-volumetrics-for-spotlights.htmlに有望なリードがあるようです
特に、
エッジは...どうにかして柔らかくする必要があり、そこで頂点法線の出番です。ビュー スペース法線 (cnorm) とビュー ベクトル (正規化されたフラグメント位置、cpos) の内積を、説明するメトリックとして使用できます。どのくらいエッジに近いか...現在のフラグメントは.
ビュー空間法線とビュー ベクトルを計算するためのコードを知っている人はいますか?