I’m working on a simple glow/outline shader. I’m using the subVector between my camera and my object to calculate a viewVector uniform, or the angle at which we are viewing the object, and using this to calculate pixel ‘intensity’.
It works nicely, unless I rotate my object, in which case the effect breaks. How can I allow for object rotation in my code?
Here is my vertex shader:
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main()
{
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
I suspect that the problem is that your view vector is in “world” space when your calculation treats it as being in object space.
Why do you need a view vector? Why not just use vec3(0,0,-1)?
For an accurate silhouette, use the normalised eye-space position, i.e.
vec3 vNormel = normalize((modelViewMatrix * vec4( position, 1.0 )).xyz);
But a fixed vector may suffice if the field of view is narrow.
Thanks, but the effect I’m after is more of a 3d halo glow, like the one seen here:
https://stemkoski.github.io/Three.js/Shader-Glow.html
You can change the parameters c and p to achieve a glass-like effect too.
All transforms work with the current code. Its just rotations that seem to break it
Yes. I know.
Have you actually tried using a fixed vector, or the eye-space vertex position?
Ah sorry, I’d misunderstood what you were driving at.
If I use a fixed vector, then it looks right if everything is static, but now if I rotate/move objects or the camera then the effect breaks
vec3 viewVector = vec3(0,0,1);
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
[QUOTE=benkyma;1266661]Ah sorry, I’d misunderstood what you were driving at.
If I use a fixed vector, then it looks right if everything is static, but now if I rotate/move objects or the camera then the effect breaks
vec3 viewVector = vec3(0,0,1);
vec3 vNormel = normalize( normalMatrix * viewVector );
[/QUOTE]
That’s not fixed. Fixed means:
vec3 vNormel = vec3(0,0,1);
intensity = pow( c - dot(vNormal, vNormel), p );
This assumes that normalMatrix is transforming into eye space, i.e. it’s based upon modelViewMatrix.
Ah got it. That pretty much works. It looks a little wrong towards the edge of the screen but it might be good enough. Thanks a lot for explaining.
If I use the following, all my objects go white though:
vec3 vNormel = normalize((modelViewMatrix * vec4( position, 1.0 )).xyz);