1
0
Fork 0

Add the ability to record depth in color buffer. This should solve depth buffer resolution problem for older NVidia cards.

This commit is contained in:
Frederic Bouvier 2012-05-01 08:47:38 +02:00
parent 4b1d51a801
commit 6be18a5c99
14 changed files with 88 additions and 44 deletions

View file

@ -67,6 +67,7 @@
<program> <program>
<vertex-shader>Shaders/deferred-tree.vert</vertex-shader> <vertex-shader>Shaders/deferred-tree.vert</vertex-shader>
<fragment-shader>Shaders/deferred-tree.frag</fragment-shader> <fragment-shader>Shaders/deferred-tree.frag</fragment-shader>
<fragment-shader>Shaders/gbuffer-functions.frag</fragment-shader>
</program> </program>
<uniform> <uniform>
<name>texture</name> <name>texture</name>

View file

@ -1,15 +1,15 @@
#extension GL_EXT_gpu_shader4 : enable #extension GL_EXT_gpu_shader4 : enable
// -*- mode: C; -*-
// Licence: GPL v2
// Author: Frederic Bouvier.
// //
// attachment 0: normal.x | normal.x | normal.y | normal.y
// attachment 1: diffuse.r | diffuse.g | diffuse.b | material Id
// attachment 2: specular.l | shininess | emission.l | unused
//
varying vec3 ecNormal; varying vec3 ecNormal;
varying float alpha; varying float alpha;
uniform int materialID; uniform int materialID;
uniform sampler2D texture; uniform sampler2D texture;
vec2 normal_encode(vec3 n); void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);
void main() { void main() {
vec4 texel = texture2D(texture, gl_TexCoord[0].st); vec4 texel = texture2D(texture, gl_TexCoord[0].st);
@ -19,8 +19,6 @@ void main() {
float shininess = gl_FrontMaterial.shininess; float shininess = gl_FrontMaterial.shininess;
float emission = dot( gl_FrontLightModelProduct.sceneColor.rgb, vec3( 0.3, 0.59, 0.11 ) ); float emission = dot( gl_FrontLightModelProduct.sceneColor.rgb, vec3( 0.3, 0.59, 0.11 ) );
vec3 normal2 = normalize( (2.0 * gl_Color.a - 1.0) * ecNormal ); vec3 normal2 = normalize( (2.0 * gl_Color.a - 1.0) * ecNormal );
gl_FragData[0] = vec4( normal_encode(normal2), 0.0, 1.0 ); encode_gbuffer(normal2, gl_Color.rgb * texel.rgb, materialID, specular, shininess, emission, gl_FragCoord.z);
gl_FragData[1] = vec4( gl_Color.rgb * texel.rgb, float( materialID ) / 255.0 );
gl_FragData[2] = vec4( specular, shininess / 128.0, emission, 1.0 );
} }

View file

@ -1,8 +1,8 @@
// -*- mode: C; -*-
// Licence: GPL v2
// Author: Frederic Bouvier.
// //
// attachment 0: normal.x | normal.x | normal.y | normal.y
// attachment 1: diffuse.r | diffuse.g | diffuse.b | material Id
// attachment 2: specular.l | shininess | emission.l | unused
//
varying vec3 ecNormal; varying vec3 ecNormal;
varying float alpha; varying float alpha;
void main() { void main() {

View file

@ -6,6 +6,7 @@
// //
uniform int materialID; uniform int materialID;
uniform sampler2D texture; uniform sampler2D texture;
void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);
void main() { void main() {
vec4 texel = texture2D(texture, gl_TexCoord[0].st); vec4 texel = texture2D(texture, gl_TexCoord[0].st);
if (texel.a < 0.1) if (texel.a < 0.1)
@ -14,9 +15,6 @@ void main() {
float shininess = 0.1; float shininess = 0.1;
float emission = 0.0; float emission = 0.0;
// Normal is straight towards the viewer. // Normal is straight towards the viewer. (FB: Are they really billboards ? )
vec3 normal2 = vec3(0.0, 0.0, 0.0); encode_gbuffer(vec3(0.5, 0.5, 0.0), gl_Color.rgb * texel.rgb, materialID, specular, shininess, emission, gl_FragCoord.z);
gl_FragData[0] = vec4( 0.5, 0.5, 0.0, 1.0 );
gl_FragData[1] = vec4( gl_Color.rgb * texel.rgb, float( materialID ) / 255.0 );
gl_FragData[2] = vec4( specular, shininess / 255.0, emission, 1.0 );
} }

View file

@ -7,7 +7,7 @@ uniform float fg_FogDensity;
uniform vec3 fg_Planes; uniform vec3 fg_Planes;
varying vec3 ray; varying vec3 ray;
vec3 position( vec3 viewdir, float depth ); vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex );
void main() { void main() {
vec2 coords = gl_TexCoord[0].xy; vec2 coords = gl_TexCoord[0].xy;
@ -15,11 +15,7 @@ void main() {
if ( initialized < 0.1 ) if ( initialized < 0.1 )
discard; discard;
vec3 normal; vec3 normal;
normal.xy = texture2D( normal_tex, coords ).rg * 2.0 - vec2(1.0,1.0); vec3 pos = position( normalize(ray), coords, depth_tex );
normal.z = sqrt( 1.0 - dot( normal.xy, normal.xy ) );
float len = length(normal);
normal /= len;
vec3 pos = position( normalize(ray), texture2D( depth_tex, coords ).r );
float fogFactor = 0.0; float fogFactor = 0.0;
const float LOG2 = 1.442695; const float LOG2 = 1.442695;

View file

@ -1,4 +1,9 @@
// -*- mode: C; -*-
// Licence: GPL v2
// Author: Frederic Bouvier.
uniform vec3 fg_Planes; uniform vec3 fg_Planes;
uniform bool fg_DepthInColor;
// normal compression functions from // normal compression functions from
// http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap // http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap
@ -19,10 +24,60 @@ vec3 normal_decode(vec2 enc)
return n; 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 position( vec3 viewDir, float depth )
{ {
vec3 pos; vec3 pos;
pos.z = - fg_Planes.y / (fg_Planes.x + depth * fg_Planes.z); pos.z = - fg_Planes.y / (fg_Planes.x + depth * fg_Planes.z);
pos.xy = viewDir.xy / viewDir.z * pos.z; pos.xy = viewDir.xy / viewDir.z * pos.z;
return pos; 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);
} }

View file

@ -15,7 +15,7 @@ uniform float Far;
varying vec4 ecPosition; varying vec4 ecPosition;
vec3 position( vec3 viewdir, float depth ); vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex );
vec3 normal_decode(vec2 enc); vec3 normal_decode(vec2 enc);
void main() { void main() {
@ -27,7 +27,7 @@ void main() {
vec3 normal = normal_decode(texture2D( normal_tex, coords ).rg); vec3 normal = normal_decode(texture2D( normal_tex, coords ).rg);
vec4 spec_emis = texture2D( spec_emis_tex, coords ); vec4 spec_emis = texture2D( spec_emis_tex, coords );
vec3 pos = position(viewDir, texture2D( depth_tex, coords ).r); vec3 pos = position(viewDir, coords, depth_tex);
if ( pos.z < ecPos3.z ) // Negative direction in z if ( pos.z < ecPos3.z ) // Negative direction in z
discard; // Don't light surface outside the light volume discard; // Don't light surface outside the light volume

View file

@ -19,7 +19,7 @@ uniform float Far;
varying vec4 ecPosition; varying vec4 ecPosition;
vec3 position( vec3 viewdir, float depth ); vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex );
vec3 normal_decode(vec2 enc); vec3 normal_decode(vec2 enc);
void main() { void main() {
@ -31,7 +31,7 @@ void main() {
vec3 normal = normal_decode(texture2D( normal_tex, coords ).rg); vec3 normal = normal_decode(texture2D( normal_tex, coords ).rg);
vec4 spec_emis = texture2D( spec_emis_tex, coords ); vec4 spec_emis = texture2D( spec_emis_tex, coords );
vec3 pos = position(viewDir, texture2D( depth_tex, coords ).r); vec3 pos = position(viewDir, coords, depth_tex);
if ( pos.z < ecPos3.z ) // Negative direction in z if ( pos.z < ecPos3.z ) // Negative direction in z
discard; // Don't light surface outside the light volume discard; // Don't light surface outside the light volume

View file

@ -12,7 +12,7 @@ uniform int fg_ShadowNumber;
uniform vec4 fg_ShadowDistances; uniform vec4 fg_ShadowDistances;
varying vec3 ray; varying vec3 ray;
vec3 position( vec3 viewdir, float depth ); vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex );
vec3 normal_decode(vec2 enc); vec3 normal_decode(vec2 enc);
vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint ) vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint )
@ -57,7 +57,7 @@ void main() {
float len = length(normal); float len = length(normal);
normal /= len; normal /= len;
vec3 viewDir = normalize(ray); vec3 viewDir = normalize(ray);
vec3 pos = position( viewDir, texture2D( depth_tex, coords ).r ); vec3 pos = position( viewDir, coords, depth_tex );
vec4 tint; vec4 tint;
float shadow = shadow2DProj( shadow_tex, DynamicShadow( vec4( pos, 1.0 ), tint ) ).r; float shadow = shadow2DProj( shadow_tex, DynamicShadow( vec4( pos, 1.0 ), tint ) ).r;

View file

@ -17,7 +17,7 @@ varying vec4 eyePlaneT;
varying vec4 eyePlaneR; varying vec4 eyePlaneR;
varying vec4 eyePlaneQ; varying vec4 eyePlaneQ;
vec3 position( vec3 viewdir, float depth ); vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex );
vec3 normal_decode(vec2 enc); vec3 normal_decode(vec2 enc);
vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint ) vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint )
@ -43,7 +43,7 @@ void main() {
float len = length(normal); float len = length(normal);
normal /= len; normal /= len;
vec3 viewDir = normalize(ray); vec3 viewDir = normalize(ray);
vec3 pos = position( viewDir, texture2D( depth_tex, coords ).r ); vec3 pos = position( viewDir, coords, depth_tex );
vec4 tint; vec4 tint;
float shadow; float shadow;

View file

@ -14,7 +14,7 @@ uniform vec4 fg_ShadowDistances;
uniform int filtering; uniform int filtering;
varying vec3 ray; varying vec3 ray;
vec3 position( vec3 viewdir, float depth ); vec3 position( vec3 viewDir, vec2 coords, sampler2D depth_tex );
vec3 normal_decode(vec2 enc); vec3 normal_decode(vec2 enc);
vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint ) vec4 DynamicShadow( in vec4 ecPosition, out vec4 tint )
@ -59,7 +59,7 @@ void main() {
float len = length(normal); float len = length(normal);
normal /= len; normal /= len;
vec3 viewDir = normalize(ray); vec3 viewDir = normalize(ray);
vec3 pos = position( viewDir, texture2D( depth_tex, coords ).r ); vec3 pos = position( viewDir, coords, depth_tex );
vec4 tint; vec4 tint;
float shadow = 0.0; float shadow = 0.0;

View file

@ -56,7 +56,7 @@ uniform vec3 dirt_g_color;
uniform vec3 dirt_b_color; uniform vec3 dirt_b_color;
//uniform vec4 fg_SunAmbientColor; //uniform vec4 fg_SunAmbientColor;
vec2 normal_encode(vec3 n); void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);
///fog include////////////////////// ///fog include//////////////////////
uniform int fogType; uniform int fogType;
@ -180,7 +180,5 @@ void main (void)
// END lightmap // END lightmap
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
gl_FragData[0]=vec4(normal_encode(N), 0.0, 1.0); encode_gbuffer(N, fragColor.rgb, 1, specular, gl_FrontMaterial.shininess, emission, gl_FragCoord.z);
gl_FragData[1]=vec4(fragColor.rgb,1.0/255.0);
gl_FragData[2]=vec4(specular, gl_FrontMaterial.shininess/128.0, emission, 1.0);
} }

View file

@ -37,7 +37,7 @@ int linear_search_steps = 10;
int GlobalIterationCount = 0; int GlobalIterationCount = 0;
int gIterationCap = 64; int gIterationCap = 64;
vec2 normal_encode(vec3 n); void encode_gbuffer(vec3 normal, vec3 color, int mId, float specular, float shininess, float emission, float depth);
void QDM(inout vec3 p, inout vec3 v) void QDM(inout vec3 p, inout vec3 v)
{ {
@ -190,7 +190,6 @@ void main (void)
N.z = sqrt(1.0 - min(1.0,dot(N.xy, N.xy))); N.z = sqrt(1.0 - min(1.0,dot(N.xy, N.xy)));
float Nz = N.z; float Nz = N.z;
N = normalize(N.x * tangent + N.y * binormal + N.z * normal); N = normalize(N.x * tangent + N.y * binormal + N.z * normal);
gl_FragData[0] = vec4( normal_encode(N), 0.0, 1.0 );
vec4 ambient_light = constantColor + vec4(gl_Color.rgb, 1.0); vec4 ambient_light = constantColor + vec4(gl_Color.rgb, 1.0);
@ -216,9 +215,6 @@ void main (void)
vec4 p = vec4( ecPos3 + tile_size * V * (d-1.0) * depth_factor / s.z, 1.0 ); vec4 p = vec4( ecPos3 + tile_size * V * (d-1.0) * depth_factor / s.z, 1.0 );
gl_FragData[1] = vec4( finalColor.rgb, 1.0 / 255.0 );
gl_FragData[2] = vec4( dot(specular.xyz,vec3(0.3, 0.59, 0.11 )), specular.w/128.0, 0.0, 1.0 );
if (dot(normal,-V) > 0.1) { if (dot(normal,-V) > 0.1) {
vec4 iproj = gl_ProjectionMatrix * p; vec4 iproj = gl_ProjectionMatrix * p;
iproj /= iproj.w; iproj /= iproj.w;
@ -226,4 +222,5 @@ void main (void)
} else { } else {
gl_FragDepth = gl_FragCoord.z; gl_FragDepth = gl_FragCoord.z;
} }
encode_gbuffer(N, finalColor.rgb, 1, dot(specular.xyz,vec3(0.3, 0.59, 0.11 )), specular.w, 0.0, gl_FragDepth);
} }

View file

@ -68,6 +68,7 @@ Started September 2000 by David Megginson, david@megginson.com
<show-buffers type="bool" userarchive="y">true</show-buffers> <show-buffers type="bool" userarchive="y">true</show-buffers>
<ambient-occlusion type="bool" userarchive="y">false</ambient-occlusion> <ambient-occlusion type="bool" userarchive="y">false</ambient-occlusion>
<exposure type="float" userarchive="y">1.0</exposure> <exposure type="float" userarchive="y">1.0</exposure>
<use-color-for-depth type="bool">false</use-color-for-depth>
<debug type="bool">false</debug> <debug type="bool">false</debug>
<realism type="int">5</realism> <realism type="int">5</realism>
<filtering type="int">8</filtering> <filtering type="int">8</filtering>