roc_samples/data/shaders/standard.frag
cecilkorik 12cb7128f7 split everything in roc_samples out of the main roc project
refactored as needed to make roc work as a shared library, without any stupid import hacks
2017-05-08 23:49:09 -07:00

141 lines
No EOL
4 KiB
GLSL
Executable file

varying vec4 ambientGlobal/*,ambientA[8],diffuseA[8]*/;
varying vec4 pixelpos;
uniform sampler2D tex;
varying vec3 normal/*,lightDirA[8],halfVectorA[8]*/;
/*varying float distA[8];*/
vec4 overlay_blend(vec4 base, vec4 blend)
{
vec4 lumCoeff = vec4(0.2125, 0.7154, 0.0721, 1.0);
vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
vec4 result;
float luminance = dot(base, lumCoeff);
if (luminance < 0.45)
result = 2.0 * blend * base;
else if (luminance > 0.55)
result = white - 2.0 * (white - blend) * (white - base);
else
{
vec4 result1 = 2.0 * blend * base;
vec4 result2 = white - 2.0 * (white - blend) * (white - base);
result = mix(result1, result2, (luminance - 0.45) * 10.0);
}
return result;
}
vec4 process_lightsource(gl_LightSourceParameters light, vec4 incolor)
{
vec3 n,halfV,viewV,lightDir,halfVector;
float NdotL,NdotHV,dist;
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
vec4 spec = vec4(0.0, 0.0, 0.0, 1.0);
vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
float att;
/* a fragment shader can't write a varying variable, hence we need
a new variable to store the normalized interpolated normal */
n = normalize(normal);
vec3 aux, ldir;
vec4 d,a;
if (light.position[3] == 1.0)
{
aux = vec3(light.position-pixelpos);
ldir = normalize(aux);
dist = length(aux);
}
else
{
ldir = normalize(vec3(light.position));
dist = 0.0;
}
halfVector = normalize(light.halfVector.xyz);
/* Compute the diffuse, ambient and globalAmbient terms */
d = gl_FrontMaterial.diffuse * light.diffuse;
/* The ambient terms have been separated since one of them */
/* suffers attenuation */
a = gl_FrontMaterial.ambient * light.ambient;
/* compute the dot product between normal and normalized lightdir */
NdotL = dot(n,ldir);
#define SHADOW_FUZZ 0.1
if (NdotL > 0.0) {
NdotL = ((1.0 - SHADOW_FUZZ) * NdotL) + SHADOW_FUZZ;
att = 1.0 / (light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
color = att * (d * NdotL + a);
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
//spec = att * gl_FrontMaterial.specular * light.specular * pow(NdotHV,gl_FrontMaterial.shininess);
spec = att * white * light.specular * pow(NdotHV,10.0);
}
else if (NdotL > (-1.0 * SHADOW_FUZZ)) {
float fraction;
NdotL = (NdotL+SHADOW_FUZZ);
fraction = NdotL / SHADOW_FUZZ;
att = 1.0 / (light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
color = att * fraction * (d * NdotL + a);
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
//spec = att * fraction * gl_FrontMaterial.specular * light.specular * pow(NdotHV,gl_FrontMaterial.shininess);
spec = att * white * light.specular * pow(NdotHV,10.0);
}
// blend mode SCREEN
color = white - ((white - color) * (white - incolor));
// blend mode AVG
//color = (color + incolor) * 0.5;
// blend mode LIGHTEN
//color = max(color, incolor);
// blend mode OVERLAY
//color = overlay_blend(incolor, color);
// blend mode DODGE
//color = incolor / (white - color);
// blend mode MULTIPLY
//color = color * incolor;
color += clamp(spec, 0.0, 1.0);
return clamp(color, 0.0, 1.0);
}
void main()
{
vec4 color = ambientGlobal;
vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
//color = white;
color = process_lightsource(gl_LightSource[0], color);
color = process_lightsource(gl_LightSource[1], color);
color = process_lightsource(gl_LightSource[2], color);
color = process_lightsource(gl_LightSource[3], color);
color = process_lightsource(gl_LightSource[4], color);
color = process_lightsource(gl_LightSource[5], color);
color = process_lightsource(gl_LightSource[6], color);
color = process_lightsource(gl_LightSource[7], color);
vec4 texcolor = texture2D(tex, gl_TexCoord[0].st);
gl_FragColor = clamp(texcolor * color, 0.0, 1.0);
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}