// -*- 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); }