Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2015
608
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. buffer CameraUniforms  : register(b0) { float4x4 u_view;  float4x4 u_proj;  float4x4 u_viewProj;  float4x4 u_prevView;  float4x4 u_prevViewProj;  float4x4 u_prevViewProjInvView;  float4 u_projInfo;  float4 u_uvProjInfo;  float4x4 u_viewToWorld;  float4x4 u_worldmapToView;  float3 u_clipInfo;  float u_time;  float3 u_viewUp;  float u_gameTime;  float2 u_screenSize;  float2 u_invScreenSize;  float3 u_cameraPosition;  int u_frameNum;  float3 u_gameCameraPosition;  float u_prevGameTime;  }
  2. Texture2D u_color : register(t0); Texture2D u_normal : register(t1); Texture2D u_depth : register(t2); Texture2D u_motionVectors : register(t3);
  3. Texture2D u_texture0 : register(t4);
  4.  
  5.  
  6. SamplerState pointClamp : register(s0);
  7. //  {
  8. //      Filter      = MIN_MAG_MIP_POINT;
  9. //         
  10. //      AddressU    = CLAMP;
  11. //      AddressV    = CLAMP;                       
  12. //  };
  13.  
  14. SamplerState samLinear : register(s1);
  15. //  {
  16. //      Filter      = MIN_MAG_LINEAR_MIP_POINT;
  17. //         
  18. //      AddressU    = BORDER;
  19. //      AddressV    = BORDER;
  20. //      BorderColor = (0.65, 0.65, 0.65, 0.65);
  21. //      MaxLOD      = 0;
  22. //  };
  23.  
  24. /** The height in pixels of a 1m object if viewed from 1m away.  
  25. You can compute it from your projection matrix.  The actual value is just
  26. a scale factor on radius; you can simply hardcode this to a constant (~500)
  27. and make your radius value unitless (...but resolution dependent.)  */
  28. //float u_projScale;
  29.  
  30. ////////////////////////////////////////////////////////
  31. // Total number of direct samples to take at each pixel
  32.  
  33. #define NUM_SAMPLES (16)
  34. #define radius 2.6
  35. static const float intensity = 1.85 / NUM_SAMPLES;
  36.  
  37. // This is the number of turns around the circle that the spiral pattern makes.  This should be prime to prevent
  38. // taps from lining up.  This particular choice was tuned for NUM_SAMPLES == 10
  39. #define NUM_SPIRAL_TURNS (7)
  40.  
  41. /** Bias to avoid AO in smooth corners, e.g., 0.01m */
  42. #define BIAS    0.01
  43.  
  44. // If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
  45. // miplevel to maintain reasonable spatial locality in the cache
  46. // If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
  47. // If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively
  48. #define invMaxOffset 0.34
  49.  
  50. //////////////////////////////////////////////////
  51.  
  52. /**  vec4 u_projInfo (-2.0f / (width*P[0][0]),
  53.           2.0f / (height*P[1][1]),
  54.          ( 1.0f - P[0][2]) / P[0][0],
  55.          ( -1.0f - P[1][2]) / P[1][1])
  56.            
  57.         where P is the projection matrix that maps camera space points
  58.         to [-1, 1] x [-1, 1].  That is, GCamera::getProjectUnit(). */
  59.  
  60. /** Reconstruct camera-space P.xyz from screen-space S = (x, y) in
  61.         pixels and camera-space z < 0.  Assumes that the upper-left pixel center
  62.         is at (0.5, 0.5) [but that need not be the location at which the sample tap
  63.         was placed!]
  64. */
  65. float3 reconstructCSPositionUV(float2 S, float z) {
  66.     return float3((S.xy * u_uvProjInfo.xy + u_uvProjInfo.zw) * z, z);
  67. }
  68.  
  69. float getAO(float2 uv, float3 viewPos, float3 normal, float mipLevel, float epsilon)
  70. {
  71.     float3 Q = reconstructCSPositionUV(uv, u_depth.SampleLevel(pointClamp, uv, mipLevel).r);
  72.     float3 v = Q - viewPos;
  73.     float vv = dot(v, v) + epsilon;
  74.     float vn = max(dot(v, normal) - BIAS, 0.0);
  75.            
  76.     return vn / vv;
  77. }
  78.        
  79. float sampleAO(in float2 uv, in float3 viewPos, in float3 normal, in float ssDiskRadius, in float tapIndex, in float randomAngle, in float logOffset, float epsilon)
  80. {
  81.     // Offset on the unit disk, spun for this pixel
  82.     float ssR = (tapIndex+0.5) / NUM_SAMPLES * ssDiskRadius;
  83.  
  84.     // Derivation:
  85.     //  mipLevel = floor(log(ssR / MAX_OFFSET));
  86.     float mipLevel = log2(ssR * logOffset);
  87.            
  88.     float angle = tapIndex * (NUM_SPIRAL_TURNS * 6.28 / NUM_SAMPLES) + randomAngle;
  89.     float2 offset = float2(cos(angle), sin(angle)) * ssR;
  90.  
  91.     return getAO(uv + offset, viewPos, normal, mipLevel, epsilon);
  92. }
  93.  
  94. struct PS_INPUT
  95. {
  96.     float4  position    : SV_Position;
  97.     float2  uv          : TEXCOORD0;
  98. };
  99.        
  100. float4 main (PS_INPUT input) : SV_Target
  101. {
  102.     int3 ssC = int3(input.position.xy, 0);
  103.     float z = u_depth.Load(ssC).r;
  104.     float2 motionVectors = u_motionVectors.Load(ssC).rg;
  105.     float2 prevUv = input.uv + motionVectors;
  106.     float3 viewPos = reconstructCSPositionUV( input.uv, z);
  107.  
  108.     // Choose the screen-space sample radius
  109.     // proportional to the projected area of the sphere
  110.     float ssDiskRadius = 0.5 * radius / viewPos.z;
  111.            
  112.     float epsilon = 0.0025 - 0.0002 * viewPos.z;
  113.     float randomPatternRotationAngle = (61.111231231 * u_time + (9.2735171213125 * ssC.x + -7.235171213125 * ssC.y + 1.53713171123412415411 * (ssC.x ^ ssC.y)));
  114.     float logOffset = invMaxOffset / u_projInfo.x;
  115.            
  116.     float4 normalTex = u_normal.Load(ssC);
  117.     float3 normal = normalTex.xyz;
  118.     //float validity = normalTex.a >= 0.0 ? 0.825 : 0.0; // is previous frame data valid is stored at normalTex.a sign
  119.            
  120.     //validity *= saturate(2.0 - length(motionVectors) * 200.0);
  121.  
  122.     float sum = 0.0;
  123.     [unroll]   
  124.     for (int i = 0; i < NUM_SAMPLES; ++i)
  125.     {
  126.         sum += sampleAO(input.uv, viewPos, normal, ssDiskRadius, i, randomPatternRotationAngle, logOffset, epsilon);
  127.     }
  128.  
  129.     float ao = saturate(sum * intensity);
  130.     return ao;
  131.     //float prevValue = u_texture0.SampleLevel(samLinear, prevUv, 0).r;
  132.            
  133.     //validity = saturate(validity - 4.0 * saturate(-0.8 + abs(ao - prevValue))); // avoid ghosting if samples are too different.
  134.     //return lerp(ao, prevValue, validity);
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement