83 lines
2.3 KiB
C
83 lines
2.3 KiB
C
// -*- mode: C; -*-
|
|
// Licence: GPL v2
|
|
// Author: Frederic Bouvier.
|
|
|
|
uniform vec3 fg_Planes;
|
|
uniform bool fg_DepthInColor;
|
|
|
|
// normal compression functions from
|
|
// http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap
|
|
vec2 normal_encode(vec3 n)
|
|
{
|
|
float p = sqrt(n.z * 8.0 + 8.0);
|
|
return n.xy / p + 0.5;
|
|
}
|
|
|
|
vec3 normal_decode(vec2 enc)
|
|
{
|
|
vec2 fenc = enc * 4.0 - 2.0;
|
|
float f = dot(fenc,fenc);
|
|
float g = sqrt(1.0 - f / 4.0);
|
|
vec3 n;
|
|
n.xy = fenc * g;
|
|
n.z = 1.0 - f / 2.0;
|
|
return n;
|
|
}
|
|
|
|
// depth to color encoding and decoding functions from
|
|
// Deferred Shading Tutorial by Fabio Policarpo and Francisco Fonseca
|
|
// (corrected by Frederic Bouvier)
|
|
vec3 float_to_color(in float f)
|
|
{
|
|
vec3 color;
|
|
f *= 255.0;
|
|
color.x = floor(f);
|
|
f = (f-color.x)*255.0;
|
|
color.y = floor(f);
|
|
color.z = f-color.y;
|
|
color.xy /= 255.0;
|
|
return color;
|
|
}
|
|
|
|
float color_to_float(vec3 color)
|
|
{
|
|
const vec3 byte_to_float = vec3(1.0, 1.0/255.0, 1.0/(255.0*255.0));
|
|
return dot(color,byte_to_float);
|
|
}
|
|
|
|
vec3 position( vec3 viewDir, float depth )
|
|
{
|
|
vec3 pos;
|
|
pos.z = - fg_Planes.y / (fg_Planes.x + depth * fg_Planes.z);
|
|
pos.xy = viewDir.xy / viewDir.z * pos.z;
|
|
return pos;
|
|
}
|
|
|
|
vec3 position( vec3 viewDir, vec3 depthColor )
|
|
{
|
|
return position( viewDir, color_to_float(depthColor) );
|
|
}
|
|
|
|
vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex )
|
|
{
|
|
float depth;
|
|
if (fg_DepthInColor)
|
|
depth = color_to_float( texture2D( depth_tex, coords ).rgb );
|
|
else
|
|
depth = texture2D( depth_tex, coords ).r;
|
|
return position( viewDir, depth );
|
|
}
|
|
|
|
// attachment 0: normal.x | normal.y | 0.0 | 1.0
|
|
// attachment 1: diffuse.r | diffuse.g | diffuse.b | material Id
|
|
// attachment 2: specular.l | shininess | emission.l | unused
|
|
// attachment 3: ---------- depth ------------ | unused (optional)
|
|
//
|
|
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth)
|
|
{
|
|
gl_FragData[0] = vec4( normal_encode(normal), 0.0, 1.0 );
|
|
gl_FragData[1] = vec4( color, float( mId ) / 255.0 );
|
|
gl_FragData[2] = vec4( specular, shininess / 128.0, emission, 1.0 );
|
|
if (fg_DepthInColor)
|
|
gl_FragData[3] = vec4(float_to_color(depth), 1.0);
|
|
}
|