To create good shield effect, we need to combine 2 effects.
We will use a sphere for the shield but it should be applicable on other shapes too.
Active Effect
This effect should emulate the solidity of the shield.We will need a normal vector (vector up from face) and vector from the point to camera. Angle between those two vectors is our transparency.
The angle ranges from 0° to 90°. 0° is full transparency (no color, middle of the sphere), 90° is no transparency (full color, edges of the sphere).
The angle is calculated using Dot product (
dot()
in shader).//FIXME rotate normals
//TODO compare to Shield on Unity3D wiki
Color
//THINK calculateangleToCamera
in fragment shader?
#version 330 core
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 MV;
uniform mat4 VP;
uniform mat4 MVP;
uniform vec3 Camera_world;
out float angleToCamera;
void main()
{
gl_Position = MVP * vPosition;
vec3 cameraNormal = Camera_world - (M * vec4(vPosition)).xyz;
angleToCamera = dot(cameraNormal, vNormal);
}
#version 330 core
in float angleToCamera;
uniform vec3 OverallColor;
out vec4 color;
void main()
{
color = vec4(OverallColor, angleToCamera);
}
Texture
#version 330 core
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 MV;
uniform mat4 VP;
uniform mat4 MVP;
uniform vec3 Camera_world;
out float angleToCamera;
out vec2 uv;
void main()
{
gl_Position = MVP * vPosition;
vec3 cameraNormal = Camera_world - (M * vec4(vPosition)).xyz;
angleToCamera = dot(cameraNormal, vNormal);
}
#version 330 core
in float angleToCamera;
in vec22 uv;
uniform sampler2D MainTexture;
out vec4 color;
void main()
{
color = vec4(texture(MainTexture, uv).xyz, angleToCamera);
}
Hit Effect
This effect is rendered for every hit (for few ticks with different transparency).The effect may have problems with overlapping too many effects. To limit the problem, I recommend you to order the effects by its remaining duration (earliest hit to be rendered first).