1
0
Fork 0

Restore QDM urban shader technique for quality level >= 4

This commit is contained in:
Frederic Bouvier 2010-11-02 22:31:39 +01:00
parent a653f4bcdb
commit 7c608c2003
2 changed files with 250 additions and 5 deletions

View file

@ -13,6 +13,149 @@
<tangent type="int">6</tangent>
<binormal type="int">7</binormal>
</generate>
<technique n="8">
<predicate>
<and>
<property>/sim/rendering/urban-shader</property>
<property>/sim/rendering/shader-effects</property>
<less-equal>
<value type="float">4.0</value>
<float-property>/sim/rendering/quality-level</float-property>
</less-equal>
<or>
<less-equal>
<value type="float">2.0</value>
<glversion/>
</less-equal>
<and>
<extension-supported>GL_ARB_shader_objects</extension-supported>
<extension-supported>GL_ARB_shading_language_100</extension-supported>
<extension-supported>GL_ARB_vertex_shader</extension-supported>
<extension-supported>GL_ARB_fragment_shader</extension-supported>
</and>
</or>
</and>
</predicate>
<pass>
<lighting>true</lighting>
<material>
<ambient><use>material/ambient</use></ambient>
<diffuse><use>material/diffuse</use></diffuse>
<specular><use>material/specular</use></specular>
<color-mode>ambient-and-diffuse</color-mode>
</material>
<blend><use>transparent</use></blend>
<alpha-test><use>transparent</use></alpha-test>
<shade-model>smooth</shade-model>
<cull-face>back</cull-face>
<render-bin>
<bin-number><use>render-bin/bin-number</use></bin-number>
<bin-name><use>render-bin/bin-name</use></bin-name>
</render-bin>
<texture-unit>
<unit>0</unit>
<image><use>texture[0]/image</use></image>
<filter><use>texture[0]/filter</use></filter>
<wrap-s><use>texture[0]/wrap-s</use></wrap-s>
<wrap-t><use>texture[0]/wrap-t</use></wrap-t>
<internal-format>
<use>texture[0]/internal-format</use>
</internal-format>
</texture-unit>
<texture-unit>
<unit>1</unit>
<image><use>texture[2]/image</use></image>
<filter><use>texture[2]/filter</use></filter>
<wrap-s><use>texture[2]/wrap-s</use></wrap-s>
<wrap-t><use>texture[2]/wrap-t</use></wrap-t>
<internal-format><use>texture[2]/internal-format</use></internal-format>
</texture-unit>
<texture-unit>
<unit>2</unit>
<image><use>texture[2]/image</use></image>
<filter>nearest-mipmap-nearest</filter>
<wrap-s><use>texture[2]/wrap-s</use></wrap-s>
<wrap-t><use>texture[2]/wrap-t</use></wrap-t>
<internal-format><use>texture[2]/internal-format</use></internal-format>
<mipmap-control>
<function-r>average</function-r>
<function-g>average</function-g>
<function-b>average</function-b>
<function-a>min</function-a>
</mipmap-control>
</texture-unit>
<texture-unit>
<unit>3</unit>
<type>noise</type>
</texture-unit>
<program>
<vertex-shader>Shaders/urban.vert</vertex-shader>
<fragment-shader>Shaders/urban.frag</fragment-shader>
<attribute>
<name>tangent</name>
<index>6</index>
</attribute>
<attribute>
<name>binormal</name>
<index>7</index>
</attribute>
<attribute>
<name>normal</name>
<index>15</index>
</attribute>
</program>
<uniform>
<name>BaseTex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>NormalTex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>QDMTex</name>
<type>sampler-2d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>NoiseTex</name>
<type>sampler-3d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>depth_factor</name>
<type>float</type>
<value><use>depth-factor</use></value>
</uniform>
<uniform>
<name>tile_size</name>
<type>float</type>
<value><use>xsize</use></value>
</uniform>
<uniform>
<name>night_color</name>
<type>float-vec3</type>
<value><use>night-color</use></value>
</uniform>
<uniform>
<name>quality_level</name>
<type>float</type>
<value><use>quality-level</use></value>
</uniform>
<uniform>
<name>snowlevel</name>
<type>float</type>
<value><use>snow-level</use></value>
</uniform>
<uniform>
<name>max_lod_level</name>
<type>float</type>
<value><use>max-lod-level</use></value>
</uniform>
</pass>
</technique>
<technique n="9">
<predicate>
<and>

View file

@ -5,6 +5,11 @@
#version 120
#define TEXTURE_MIP_LEVELS 10
#define TEXTURE_PIX_COUNT 1024 //pow(2,TEXTURE_MIP_LEVELS)
#define BINARY_SEARCH_COUNT 10
#define BILINEAR_SMOOTH_FACTOR 2.0
varying vec4 rawpos;
varying vec4 ecPosition;
varying vec3 VNormal;
@ -16,6 +21,7 @@ varying vec4 constantColor;
uniform sampler3D NoiseTex;
uniform sampler2D BaseTex;
uniform sampler2D NormalTex;
uniform sampler2D QDMTex;
uniform float depth_factor;
uniform float tile_size;
uniform float quality_level; // From /sim/rendering/quality-level
@ -24,8 +30,96 @@ uniform vec3 night_color;
const float scale = 1.0;
int linear_search_steps = 10;
int GlobalIterationCount = 0;
int gIterationCap = 64;
float ray_intersect(sampler2D reliefMap, vec2 dp, vec2 ds)
void QDM(inout vec3 p, inout vec3 v)
{
const int MAX_LEVEL = TEXTURE_MIP_LEVELS;
const float NODE_COUNT = TEXTURE_PIX_COUNT;
const float TEXEL_SPAN_HALF = 1.0 / NODE_COUNT / 2.0;
float fDeltaNC = TEXEL_SPAN_HALF * depth_factor;
vec3 p2 = p;
float level = MAX_LEVEL;
vec2 dirSign = (sign(v.xy) + 1.0) * 0.5;
GlobalIterationCount = 0;
float d = 0.0;
while (level >= 0.0 && GlobalIterationCount < gIterationCap)
{
vec4 uv = vec4(p2.xyz, level);
d = texture2DLod(QDMTex, uv.xy, uv.w).w;
if (d > p2.z)
{
//predictive point of ray traversal
vec3 tmpP2 = p + v * d;
//current node count
float nodeCount = pow(2.0, (MAX_LEVEL - level));
//current and predictive node ID
vec4 nodeID = floor(vec4(p2.xy, tmpP2.xy)*nodeCount);
//check if we are crossing the current cell
if (nodeID.x != nodeID.z || nodeID.y != nodeID.w)
{
//calculate distance to nearest bound
vec2 a = p2.xy - p.xy;
vec2 p3 = (nodeID.xy + dirSign) / nodeCount;
vec2 b = p3.xy - p.xy;
vec2 dNC = (b.xy * p2.z) / a.xy;
//take the nearest cell
d = min(d,min(dNC.x, dNC.y))+fDeltaNC;
level++;
//use additional convergence speed-up
#ifdef USE_QDM_ASCEND_INTERVAL
if(frac(level*0.5) > EPSILON)
level++;
#elseif USE_QDM_ASCEND_CONST
level++;
#endif
}
p2 = p + v * d;
}
level--;
GlobalIterationCount++;
}
//
// Manual Bilinear filtering
//
float rayLength = length(p2.xy - p.xy) + fDeltaNC;
float dA = p2.z * (rayLength - BILINEAR_SMOOTH_FACTOR * TEXEL_SPAN_HALF) / rayLength;
float dB = p2.z * (rayLength + BILINEAR_SMOOTH_FACTOR * TEXEL_SPAN_HALF) / rayLength;
vec4 p2a = vec4(p + v * dA, 0.0);
vec4 p2b = vec4(p + v * dB, 0.0);
dA = texture2DLod(NormalTex, p2a.xy, p2a.w).w;
dB = texture2DLod(NormalTex, p2b.xy, p2b.w).w;
dA = abs(p2a.z - dA);
dB = abs(p2b.z - dB);
p2 = mix(p2a.xyz, p2b.xyz, dA / (dA + dB));
p = p2;
}
float ray_intersect_QDM(vec2 dp, vec2 ds)
{
vec3 p = vec3( dp, 0.0 );
vec3 v = vec3( ds, 1.0 );
QDM( p, v );
return p.z;
}
float ray_intersect_relief(vec2 dp, vec2 ds)
{
float size = 1.0 / float(linear_search_steps);
float depth = 0.0;
@ -34,7 +128,7 @@ float ray_intersect(sampler2D reliefMap, vec2 dp, vec2 ds)
for(int i = 0; i < linear_search_steps - 1; ++i)
{
depth += size;
float t = step(0.95, texture2D(reliefMap, dp + ds * depth).a);
float t = step(0.95, texture2D(NormalTex, dp + ds * depth).a);
if(best_depth > 0.996)
if(depth >= t)
best_depth = depth;
@ -46,7 +140,7 @@ float ray_intersect(sampler2D reliefMap, vec2 dp, vec2 ds)
for(int i = 0; i < binary_search_steps; ++i)
{
size *= 0.5;
float t = step(0.95, texture2D(reliefMap, dp + ds * depth).a);
float t = step(0.95, texture2D(NormalTex, dp + ds * depth).a);
if(depth >= t)
{
best_depth = depth;
@ -58,6 +152,14 @@ float ray_intersect(sampler2D reliefMap, vec2 dp, vec2 ds)
return(best_depth);
}
float ray_intersect(vec2 dp, vec2 ds)
{
if ( quality_level >= 4.0 )
return ray_intersect_QDM( dp, ds );
else
return ray_intersect_relief( dp, ds );
}
void main (void)
{
if ( quality_level >= 3.5 ) {
@ -68,7 +170,7 @@ void main (void)
vec3 s = vec3(dot(V, VTangent), dot(V, VBinormal), dot(VNormal, -V));
vec2 ds = s.xy * depth_factor / s.z;
vec2 dp = gl_TexCoord[0].st - ds;
float d = ray_intersect(NormalTex, dp, ds);
float d = ray_intersect(dp, ds);
vec2 uv = dp + ds * d;
vec3 N = texture2D(NormalTex, uv).xyz * 2.0 - 1.0;
@ -89,7 +191,7 @@ void main (void)
vec3 sl = normalize( vec3( dot( l, VTangent ), dot( l, VBinormal ), dot( -l, VNormal ) ) );
ds = sl.xy * depth_factor / sl.z;
dp -= ds * d;
float dl = ray_intersect(NormalTex, dp, ds);
float dl = ray_intersect(dp, ds);
if ( dl < d - 0.05 )
shadow_factor = dot( constantColor.xyz, vec3( 1.0, 1.0, 1.0 ) ) * 0.25;
}