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

6
我正在尝试创建一个着色器,在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)的点积作为度量描述当前片段距离边缘有多近。

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

1个回答

6

问题解决了!

在我上面的代码中,vNormal 是顶点法线。为了获得视图向量,需要在着色器中添加一个uniform,并将其值设置为网格位置与相机位置之间的差异。(理论上,该值应该是每个顶点的位置与相机位置之间的差异,但对于我的目的来说,这足够接近了。)

要查看实现,请访问:http://stemkoski.github.io/Three.js/Shader-Glow.html


2
您好,我有一个关于你们的着色器-光晕效果例子的问题。我有两个问题想要问一下。首先,我想说当我按照你们的例子使用代码时,它效果很棒。但是当我旋转应用了该着色器的物体时,透明度会停止工作,那种不错的发光效果也不再总是面向摄像机。有什么办法可以解决这个问题吗? - Kahless
1
我也遇到了这个旋转问题。你解决了吗? - Ben Gannaway

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接