PDA

View Full Version : Rotation in Glow Shader



benkyma
05-27-2015, 03:12 AM
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 );
}

GClements
05-27-2015, 03:41 AM
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.

benkyma
05-27-2015, 04:00 AM
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

GClements
05-27-2015, 04:35 AM
Thanks, but the effect I'm after is more of a 3d halo glow, like the one seen here
Yes. I know.

Have you actually tried using a fixed vector, or the eye-space vertex position?

benkyma
05-27-2015, 05:00 AM
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 );

GClements
05-27-2015, 08:11 AM
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 );


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.

benkyma
05-27-2015, 09:14 AM
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);