Three.js-光晕效果的着色器代码,法线需要变换



我正试图在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)的点积作为描述距离边缘有多近的度量。。。当前片段是.

有人知道计算视图空间法线和视图向量的代码吗?

想明白了!

在我上面的代码中,vNormal是顶点法线。若要获得视图向量,请向着色器添加一个统一,其值为网格位置和摄影机位置之间的差。(理论上,这个值应该是每个顶点的位置和相机的位置之间的差,但这对我来说已经足够接近了。)

有关实现,请查看:http://stemkoski.github.io/Three.js/Shader-Glow.html

最新更新