我正在尝试创建一个着色器以在 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)的点积作为描述离边缘有多近……当前片段有多近。
有人知道计算视图空间法线和视图向量的代码吗?