Ignore:
Timestamp:
02/19/09 12:05:56 (16 years ago)
Author:
mattausch
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg

    r3319 r3320  
    156156 
    157157 
    158 /** The ssao shader returning the an intensity value between 0 and 1 
    159         This version of the ssao shader uses the dotproduct between pixel and  
    160         sample normal as weight. 
     158/** The ssao shader returning the an intensity value between 0 and 1. 
     159        This version of the ssao shader uses the dotproduct between  
     160        pixel-to-sample direction and sample normal as weight. 
     161 
     162    The algorithm works like the following: 
     163        1) Check in a circular area around the current position. 
     164        2) Shoot vectors to the positions there, and check the angle to these positions. 
     165        3) Summing up these angles gives an estimation of the occlusion at the current position. 
    161166*/ 
    162167float3 ssao2(fragment IN, 
     
    172177                         float3 tr,  
    173178                         float3 viewDir, 
    174                          sampler2D normalTex, 
    175                          float sampleIntensity 
     179                         float convergence, 
     180                         float sampleIntensity, 
     181                         bool isMovingObject, 
     182                         sampler2D normalTex 
    176183                         ) 
    177184{ 
    178185        float total_ao = .0f; 
     186        float validSamples = .0f; 
    179187        float numSamples = .0f; 
    180         float validSamples = .0f; 
    181188 
    182189        for (int i = 0; i < NUM_SAMPLES; ++ i)  
    183190        { 
    184                 const float2 offset = samples[i]; 
    185  
    186 #if 1 
     191                float2 offset; 
     192 
    187193                //////////////////// 
    188                 //-- add random noise: reflect around random normal vector (rather slow!) 
    189  
    190                 const float2 mynoise = tex2Dlod(noiseTex, float4(IN.texCoord * 4.0f, 0, 0)).xy; 
    191                 const float2 offsetTransformed = myreflect(offset, mynoise); 
    192 #else 
    193                 const float2 offsetTransformed = offset; 
    194 #endif 
     194                //-- add random noise: reflect around random normal vector  
     195                //-- (affects performance for some reason!) 
     196 
     197                if (convergence < SSAO_CONVERGENCE_THRESHOLD) 
     198                { 
     199                        float2 mynoise = tex2Dlod(noiseTex, float4(IN.texCoord * 4.0f, 0, 0)).xy; 
     200                        //offset = myreflect(samples[i], mynoise); 
     201                        offset = myrotate(samples[i], mynoise.x); 
     202                } 
     203                else 
     204                { 
     205                        offset = samples[i]; 
     206                } 
     207                 
    195208                // weight with projected coordinate to reach similar kernel size for near and far 
    196                 //const float2 texcoord = IN.texCoord.xy + offsetTransformed * scaleFactor + jitter; 
    197                 const float2 texcoord = IN.texCoord.xy + offsetTransformed * scaleFactor; 
    198  
    199                 //if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f)) ++ numSamples; 
    200                 float4 sampleColor = tex2Dlod(colors, float4(texcoord, 0, 0)); 
    201  
     209                const float2 texcoord = IN.texCoord.xy + offset * scaleFactor; 
     210 
     211                const float4 sampleColor = tex2Dlod(colors, float4(texcoord, .0f, .0f)); 
    202212                const float3 samplePos = ReconstructSamplePos(sampleColor.w, texcoord, bl, br, tl, tr); 
     213                 
     214 
     215                //////////////// 
     216                //-- compute contribution of sample using the direction and angle 
     217 
     218                float3 dirSample = samplePos - centerPosition; 
     219 
     220                //const float minDist = 9e-1f; 
     221                const float minDist = 1e-2f; 
     222 
     223                //const float sqrLen = max(SqrLen(dirSample), minDist); 
     224                //const float lengthToSample = sqrt(sqrLen); 
     225                const float lengthToSample =  max(length(dirSample), minDist); 
     226 
     227                dirSample /= lengthToSample; // normalize 
     228 
     229                // angle between current normal and direction to sample controls AO intensity. 
     230                float cosAngle = dot(dirSample, normal); 
     231 
    203232                // the normal of the current sample 
    204233                const float3 sampleNormal = tex2Dlod(normalTex, float4(texcoord, 0, 0)).xyz; 
    205234 
    206  
    207                 //////////////// 
    208                 //-- compute contribution of sample using the direction and angle 
    209  
    210                 float3 dirSample = samplePos - centerPosition; 
    211  
    212                 const float sqrLen = max(SqrLen(dirSample), 1e-2f); 
    213                 const float lengthToSample = sqrt(sqrLen); 
    214                 //const float lengthToSample = max(length(dirSample), 1e-6f); 
    215  
    216                 dirSample /= lengthToSample; // normalize 
    217  
    218235                // angle between current normal and direction to sample controls AO intensity. 
    219                 float cosAngle = .5f + dot(sampleNormal, -normal) * 0.5f; 
    220                 // use binary decision to cull samples that are behind current shading point 
    221                 cosAngle *= step(0.0f, dot(dirSample, normal)); 
    222          
    223                 const float aoContrib = sampleIntensity / sqrLen; 
     236                float cosAngle2 = .5f + dot(sampleNormal, -normal) * 0.5f; 
     237                 
     238                //const float aoContrib = sampleIntensity / sqrLen; 
     239                const float aoContrib = sampleIntensity / lengthToSample; 
     240 
    224241                //const float aoContrib = (1.0f > lengthToSample) ? occlusionPower(9e-2f, DISTANCE_SCALE + lengthToSample): .0f; 
    225  
    226                 total_ao += cosAngle * aoContrib; 
     242                total_ao += max(cosAngle, .0f) * aoContrib * cosAngle2; 
     243 
     244                ++ numSamples; 
    227245 
    228246                // check if the samples have been valid in the last frame 
    229                 validSamples += (1.0f - step(1.0f, lengthToSample)) * sampleColor.x; 
    230  
    231                 ++ numSamples; 
    232         } 
    233  
     247                // only mark sample as invalid if in the last / current frame 
     248                // they possibly have any influence on the ao 
     249 
     250                const float changeFactor = sampleColor.y; 
     251                const float pixelValid = sampleColor.x; 
     252 
     253                // hack: 
     254                // we check if the sample could have been near enough  
     255                // to the current pixel or if the angle is small enough 
     256                // to have any influence in the current or last frame 
     257#if 1 
     258                const float tooFarAway = step(0.5f, lengthToSample - changeFactor); 
     259                if (pixelValid < 2.0f) 
     260                        validSamples = max(validSamples, pixelValid * (1.0f - tooFarAway) * step(-0.1f, cosAngle)); 
     261                else 
     262                        validSamples = max(validSamples, pixelValid); 
     263#else 
     264                validSamples = max(validSamples, pixelValid); 
     265#endif 
     266 
     267#ifdef USE_GTX 
     268                // we can bail out early and use a minimal #samples) 
     269                // if some conditions are met as long as the hardware supports it 
     270                if (numSamples >= MIN_SAMPLES) 
     271                { 
     272                        //break; 
     273                        // if the pixel belongs to a static object and all the samples stay valid in the current frame 
     274                        if (!isMovingObject && (validSamples < 1.0f) && (convergence > NUM_SAMPLES)) break; 
     275                        // if the pixel belongs to a dynamic object but the #accumulated samples for this pixel is sufficiently high  
     276                        // (=> there was no discontinuity recently) 
     277                        //else if (isMovingObject && (convergence > SSAO_CONVERGENCE_THRESHOLD)) break; 
     278                        //else if (isMovingObject && (convergence > NUM_SAMPLES * 5)) break; 
     279                } 
     280#endif 
     281        } 
     282 
     283        // "normalize" ao contribution 
    234284        total_ao /= numSamples; 
    235285 
     
    238288        // => compensate for this (on the other hand, projected sampling area could be larger!) 
    239289        const float viewCorrection = 1.0f + VIEW_CORRECTION_SCALE * max(dot(viewDir, normal), 0.0f); 
    240         total_ao += cosAngle * aoContrib * viewCorrection; 
    241  
     290        total_ao *= viewCorrection; 
    242291#endif 
    243292 
    244         return float3(max(0.0f, 1.0f - total_ao), validSamples, numSamples); 
     293        //return float3(total_ao, validSamples, numSamples); 
     294        return float3(min(1.0f, total_ao), validSamples, numSamples); 
    245295} 
    246296 
     
    450500        if (eyeSpaceDepth < DEPTH_THRESHOLD) 
    451501        { 
    452                 ao = ssao(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), oldWeight, sampleIntensity, isMovingObject); 
     502                //ao = ssao(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), oldWeight, sampleIntensity, isMovingObject); 
     503                ao = ssao2(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), oldWeight, sampleIntensity, isMovingObject, normals); 
    453504                //ao = ssao2(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, scaleFactor, bl, br, tl, tr, normalize(viewDir), normals, sampleIntensity); 
    454505        } 
Note: See TracChangeset for help on using the changeset viewer.