Ambient Occlusion.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /******************************************************************************
  2. For AO shader, Depth is linearized to 0 .. Viewport.range
  3. /******************************************************************************/
  4. #include "!Header.h"
  5. #include "Ambient Occlusion.h"
  6. /******************************************************************************/
  7. #define AO0Elms 12
  8. #define AO1Elms 28
  9. #define AO2Elms 48
  10. #define AO3Elms 80
  11. #define DUAL (MODEL!=SM_GL) // on Mac (13" MacBook Air, Intel HD Graphics 5000), there's a GPU Driver issue that makes Dual Ambient Occlusion have artifacts, so disable DUAL for OpenGL
  12. /******************************************************************************/
  13. BUFFER(AOConstants)
  14. #if DUAL // divided into 2 equal groups, then Y X sorted
  15. const Vec AO0Vec[]={Vec(0.000, -0.707, 0.356), Vec(-0.354, -0.354, 0.600), Vec(0.354, -0.354, 0.600), Vec(-0.707, 0.000, 0.356), Vec(-0.354, 0.354, 0.600), Vec(0.354, 0.354, 0.600), Vec(-0.707, -0.707, 0.200), Vec(0.707, -0.707, 0.200), Vec(0.707, 0.000, 0.356), Vec(-0.707, 0.707, 0.200), Vec(0.000, 0.707, 0.356), Vec(0.707, 0.707, 0.200), };
  16. const Vec AO1Vec[]={Vec(-0.471, -0.471, 0.398), Vec(0.000, -0.471, 0.636), Vec(0.471, -0.471, 0.398), Vec(-0.707, -0.236, 0.319), Vec(-0.236, -0.236, 0.801), Vec(0.236, -0.236, 0.801), Vec(-0.471, 0.000, 0.636), Vec(0.471, 0.000, 0.636), Vec(-0.236, 0.236, 0.801), Vec(0.236, 0.236, 0.801), Vec(-0.471, 0.471, 0.398), Vec(0.000, 0.471, 0.636), Vec(0.471, 0.471, 0.398), Vec(-0.236, 0.707, 0.319), Vec(0.000, -0.943, 0.206), Vec(-0.707, -0.707, 0.200), Vec(-0.236, -0.707, 0.319), Vec(0.236, -0.707, 0.319), Vec(0.707, -0.707, 0.200), Vec(0.707, -0.236, 0.319), Vec(-0.943, 0.000, 0.206), Vec(0.943, 0.000, 0.206), Vec(-0.707, 0.236, 0.319), Vec(0.707, 0.236, 0.319), Vec(-0.707, 0.707, 0.200), Vec(0.236, 0.707, 0.319), Vec(0.707, 0.707, 0.200), Vec(0.000, 0.943, 0.206), };
  17. const Vec AO2Vec[]={Vec(0.000, -0.707, 0.356), Vec(-0.177, -0.530, 0.526), Vec(0.177, -0.530, 0.526), Vec(-0.354, -0.354, 0.600), Vec(0.000, -0.354, 0.778), Vec(0.354, -0.354, 0.600), Vec(-0.530, -0.177, 0.526), Vec(-0.177, -0.177, 0.884), Vec(0.177, -0.177, 0.884), Vec(0.530, -0.177, 0.526), Vec(-0.707, 0.000, 0.356), Vec(-0.354, 0.000, 0.778), Vec(0.354, 0.000, 0.778), Vec(0.707, 0.000, 0.356), Vec(-0.530, 0.177, 0.526), Vec(-0.177, 0.177, 0.884), Vec(0.177, 0.177, 0.884), Vec(0.530, 0.177, 0.526), Vec(-0.354, 0.354, 0.600), Vec(0.000, 0.354, 0.778), Vec(0.354, 0.354, 0.600), Vec(-0.177, 0.530, 0.526), Vec(0.177, 0.530, 0.526), Vec(0.000, 0.707, 0.356), Vec(-0.177, -0.884, 0.218), Vec(0.177, -0.884, 0.218), Vec(-0.707, -0.707, 0.200), Vec(-0.354, -0.707, 0.281), Vec(0.354, -0.707, 0.281), Vec(0.707, -0.707, 0.200), Vec(-0.530, -0.530, 0.315), Vec(0.530, -0.530, 0.315), Vec(-0.707, -0.354, 0.281), Vec(0.707, -0.354, 0.281), Vec(-0.884, -0.177, 0.218), Vec(0.884, -0.177, 0.218), Vec(-0.884, 0.177, 0.218), Vec(0.884, 0.177, 0.218), Vec(-0.707, 0.354, 0.281), Vec(0.707, 0.354, 0.281), Vec(-0.530, 0.530, 0.315), Vec(0.530, 0.530, 0.315), Vec(-0.707, 0.707, 0.200), Vec(-0.354, 0.707, 0.281), Vec(0.354, 0.707, 0.281), Vec(0.707, 0.707, 0.200), Vec(-0.177, 0.884, 0.218), Vec(0.177, 0.884, 0.218), };
  18. const Vec AO3Vec[]={Vec(-0.141, -0.707, 0.342), Vec(0.141, -0.707, 0.342), Vec(-0.283, -0.566, 0.437), Vec(0.000, -0.566, 0.517), Vec(0.283, -0.566, 0.437), Vec(-0.424, -0.424, 0.475), Vec(-0.141, -0.424, 0.666), Vec(0.141, -0.424, 0.666), Vec(0.424, -0.424, 0.475), Vec(-0.566, -0.283, 0.437), Vec(-0.283, -0.283, 0.724), Vec(0.000, -0.283, 0.853), Vec(0.283, -0.283, 0.724), Vec(0.566, -0.283, 0.437), Vec(-0.424, -0.141, 0.666), Vec(-0.141, -0.141, 0.924), Vec(0.141, -0.141, 0.924), Vec(0.424, -0.141, 0.666), Vec(-0.566, 0.000, 0.517), Vec(-0.283, 0.000, 0.853), Vec(0.283, 0.000, 0.853), Vec(0.566, 0.000, 0.517), Vec(-0.424, 0.141, 0.666), Vec(-0.141, 0.141, 0.924), Vec(0.141, 0.141, 0.924), Vec(0.424, 0.141, 0.666), Vec(0.707, 0.141, 0.342), Vec(-0.566, 0.283, 0.437), Vec(-0.283, 0.283, 0.724), Vec(0.000, 0.283, 0.853), Vec(0.283, 0.283, 0.724), Vec(0.566, 0.283, 0.437), Vec(-0.424, 0.424, 0.475), Vec(-0.141, 0.424, 0.666), Vec(0.141, 0.424, 0.666), Vec(0.424, 0.424, 0.475), Vec(-0.283, 0.566, 0.437), Vec(0.000, 0.566, 0.517), Vec(0.283, 0.566, 0.437), Vec(-0.141, 0.707, 0.342), Vec(-0.141, -0.990, 0.200), Vec(0.141, -0.990, 0.200), Vec(-0.283, -0.849, 0.221), Vec(0.000, -0.849, 0.243), Vec(0.283, -0.849, 0.221), Vec(-0.707, -0.707, 0.200), Vec(-0.424, -0.707, 0.257), Vec(0.424, -0.707, 0.257), Vec(0.707, -0.707, 0.200), Vec(-0.566, -0.566, 0.274), Vec(0.566, -0.566, 0.274), Vec(-0.707, -0.424, 0.257), Vec(0.707, -0.424, 0.257), Vec(-0.849, -0.283, 0.221), Vec(0.849, -0.283, 0.221), Vec(-0.990, -0.141, 0.200), Vec(-0.707, -0.141, 0.342), Vec(0.707, -0.141, 0.342), Vec(0.990, -0.141, 0.200), Vec(-0.849, 0.000, 0.243), Vec(0.849, 0.000, 0.243), Vec(-0.990, 0.141, 0.200), Vec(-0.707, 0.141, 0.342), Vec(0.990, 0.141, 0.200), Vec(-0.849, 0.283, 0.221), Vec(0.849, 0.283, 0.221), Vec(-0.707, 0.424, 0.257), Vec(0.707, 0.424, 0.257), Vec(-0.566, 0.566, 0.274), Vec(0.566, 0.566, 0.274), Vec(-0.707, 0.707, 0.200), Vec(-0.424, 0.707, 0.257), Vec(0.141, 0.707, 0.342), Vec(0.424, 0.707, 0.257), Vec(0.707, 0.707, 0.200), Vec(-0.283, 0.849, 0.221), Vec(0.000, 0.849, 0.243), Vec(0.283, 0.849, 0.221), Vec(-0.141, 0.990, 0.200), Vec(0.141, 0.990, 0.200), };
  19. #else // Y X sorted
  20. const Vec AO0Vec[]={Vec(-0.707f, -0.707f, 0.200f), Vec(0.000f, -0.707f, 0.356f), Vec(0.707f, -0.707f, 0.200f), Vec(-0.354f, -0.354f, 0.600f), Vec(0.354f, -0.354f, 0.600f), Vec(-0.707f, -0.000f, 0.356f), Vec(0.707f, 0.000f, 0.356f), Vec(-0.354f, 0.354f, 0.600f), Vec(0.354f, 0.354f, 0.600f), Vec(-0.707f, 0.707f, 0.200f), Vec(-0.000f, 0.707f, 0.356f), Vec(0.707f, 0.707f, 0.200f), };
  21. const Vec AO1Vec[]={Vec(0.000f, -0.943f, 0.206f), Vec(-0.707f, -0.707f, 0.200f), Vec(-0.236f, -0.707f, 0.319f), Vec(0.236f, -0.707f, 0.319f), Vec(0.707f, -0.707f, 0.200f), Vec(-0.471f, -0.471f, 0.398f), Vec(0.000f, -0.471f, 0.636f), Vec(0.471f, -0.471f, 0.398f), Vec(-0.707f, -0.236f, 0.319f), Vec(-0.236f, -0.236f, 0.801f), Vec(0.236f, -0.236f, 0.801f), Vec(0.707f, -0.236f, 0.319f), Vec(-0.943f, -0.000f, 0.206f), Vec(-0.471f, -0.000f, 0.636f), Vec(0.471f, 0.000f, 0.636f), Vec(0.943f, 0.000f, 0.206f), Vec(-0.707f, 0.236f, 0.319f), Vec(-0.236f, 0.236f, 0.801f), Vec(0.236f, 0.236f, 0.801f), Vec(0.707f, 0.236f, 0.319f), Vec(-0.471f, 0.471f, 0.398f), Vec(-0.000f, 0.471f, 0.636f), Vec(0.471f, 0.471f, 0.398f), Vec(-0.707f, 0.707f, 0.200f), Vec(-0.236f, 0.707f, 0.319f), Vec(0.236f, 0.707f, 0.319f), Vec(0.707f, 0.707f, 0.200f), Vec(-0.000f, 0.943f, 0.206f), };
  22. const Vec AO2Vec[]={Vec(-0.177f, -0.884f, 0.218f), Vec(0.177f, -0.884f, 0.218f), Vec(-0.707f, -0.707f, 0.200f), Vec(-0.354f, -0.707f, 0.281f), Vec(0.000f, -0.707f, 0.356f), Vec(0.354f, -0.707f, 0.281f), Vec(0.707f, -0.707f, 0.200f), Vec(-0.530f, -0.530f, 0.315f), Vec(-0.177f, -0.530f, 0.526f), Vec(0.177f, -0.530f, 0.526f), Vec(0.530f, -0.530f, 0.315f), Vec(-0.707f, -0.354f, 0.281f), Vec(-0.354f, -0.354f, 0.600f), Vec(0.000f, -0.354f, 0.778f), Vec(0.354f, -0.354f, 0.600f), Vec(0.707f, -0.354f, 0.281f), Vec(-0.884f, -0.177f, 0.218f), Vec(-0.530f, -0.177f, 0.526f), Vec(-0.177f, -0.177f, 0.884f), Vec(0.177f, -0.177f, 0.884f), Vec(0.530f, -0.177f, 0.526f), Vec(0.884f, -0.177f, 0.218f), Vec(-0.707f, -0.000f, 0.356f), Vec(-0.354f, -0.000f, 0.778f), Vec(0.354f, 0.000f, 0.778f), Vec(0.707f, 0.000f, 0.356f), Vec(-0.884f, 0.177f, 0.218f), Vec(-0.530f, 0.177f, 0.526f), Vec(-0.177f, 0.177f, 0.884f), Vec(0.177f, 0.177f, 0.884f), Vec(0.530f, 0.177f, 0.526f), Vec(0.884f, 0.177f, 0.218f), Vec(-0.707f, 0.354f, 0.281f), Vec(-0.354f, 0.354f, 0.600f), Vec(-0.000f, 0.354f, 0.778f), Vec(0.354f, 0.354f, 0.600f), Vec(0.707f, 0.354f, 0.281f), Vec(-0.530f, 0.530f, 0.315f), Vec(-0.177f, 0.530f, 0.526f), Vec(0.177f, 0.530f, 0.526f), Vec(0.530f, 0.530f, 0.315f), Vec(-0.707f, 0.707f, 0.200f), Vec(-0.354f, 0.707f, 0.281f), Vec(-0.000f, 0.707f, 0.356f), Vec(0.354f, 0.707f, 0.281f), Vec(0.707f, 0.707f, 0.200f), Vec(-0.177f, 0.884f, 0.218f), Vec(0.177f, 0.884f, 0.218f), };
  23. const Vec AO3Vec[]={Vec(-0.141f, -0.990f, 0.200f), Vec(0.141f, -0.990f, 0.200f), Vec(-0.283f, -0.849f, 0.221f), Vec(0.000f, -0.849f, 0.243f), Vec(0.283f, -0.849f, 0.221f), Vec(-0.707f, -0.707f, 0.200f), Vec(-0.424f, -0.707f, 0.257f), Vec(-0.141f, -0.707f, 0.342f), Vec(0.141f, -0.707f, 0.342f), Vec(0.424f, -0.707f, 0.257f), Vec(0.707f, -0.707f, 0.200f), Vec(-0.566f, -0.566f, 0.274f), Vec(-0.283f, -0.566f, 0.437f), Vec(0.000f, -0.566f, 0.517f), Vec(0.283f, -0.566f, 0.437f), Vec(0.566f, -0.566f, 0.274f), Vec(-0.707f, -0.424f, 0.257f), Vec(-0.424f, -0.424f, 0.475f), Vec(-0.141f, -0.424f, 0.666f), Vec(0.141f, -0.424f, 0.666f), Vec(0.424f, -0.424f, 0.475f), Vec(0.707f, -0.424f, 0.257f), Vec(-0.849f, -0.283f, 0.221f), Vec(-0.566f, -0.283f, 0.437f), Vec(-0.283f, -0.283f, 0.724f), Vec(0.000f, -0.283f, 0.853f), Vec(0.283f, -0.283f, 0.724f), Vec(0.566f, -0.283f, 0.437f), Vec(0.849f, -0.283f, 0.221f), Vec(-0.990f, -0.141f, 0.200f), Vec(-0.707f, -0.141f, 0.342f), Vec(-0.424f, -0.141f, 0.666f), Vec(-0.141f, -0.141f, 0.924f), Vec(0.141f, -0.141f, 0.924f), Vec(0.424f, -0.141f, 0.666f), Vec(0.707f, -0.141f, 0.342f), Vec(0.990f, -0.141f, 0.200f), Vec(-0.849f, -0.000f, 0.243f), Vec(-0.566f, -0.000f, 0.517f), Vec(-0.283f, -0.000f, 0.853f), Vec(0.283f, 0.000f, 0.853f), Vec(0.566f, 0.000f, 0.517f), Vec(0.849f, 0.000f, 0.243f), Vec(-0.990f, 0.141f, 0.200f), Vec(-0.707f, 0.141f, 0.342f), Vec(-0.424f, 0.141f, 0.666f), Vec(-0.141f, 0.141f, 0.924f), Vec(0.141f, 0.141f, 0.924f), Vec(0.424f, 0.141f, 0.666f), Vec(0.707f, 0.141f, 0.342f), Vec(0.990f, 0.141f, 0.200f), Vec(-0.849f, 0.283f, 0.221f), Vec(-0.566f, 0.283f, 0.437f), Vec(-0.283f, 0.283f, 0.724f), Vec(-0.000f, 0.283f, 0.853f), Vec(0.283f, 0.283f, 0.724f), Vec(0.566f, 0.283f, 0.437f), Vec(0.849f, 0.283f, 0.221f), Vec(-0.707f, 0.424f, 0.257f), Vec(-0.424f, 0.424f, 0.475f), Vec(-0.141f, 0.424f, 0.666f), Vec(0.141f, 0.424f, 0.666f), Vec(0.424f, 0.424f, 0.475f), Vec(0.707f, 0.424f, 0.257f), Vec(-0.566f, 0.566f, 0.274f), Vec(-0.283f, 0.566f, 0.437f), Vec(-0.000f, 0.566f, 0.517f), Vec(0.283f, 0.566f, 0.437f), Vec(0.566f, 0.566f, 0.274f), Vec(-0.707f, 0.707f, 0.200f), Vec(-0.424f, 0.707f, 0.257f), Vec(-0.141f, 0.707f, 0.342f), Vec(0.141f, 0.707f, 0.342f), Vec(0.424f, 0.707f, 0.257f), Vec(0.707f, 0.707f, 0.200f), Vec(-0.283f, 0.849f, 0.221f), Vec(-0.000f, 0.849f, 0.243f), Vec(0.283f, 0.849f, 0.221f), Vec(-0.141f, 0.990f, 0.200f), Vec(0.141f, 0.990f, 0.200f), };
  24. #endif
  25. BUFFER_END
  26. /******************************************************************************/
  27. Vec4 AO_PS(NOPERSP Vec2 inTex :TEXCOORD ,
  28. NOPERSP Vec2 inPosXY:TEXCOORD1,
  29. PIXEL ,
  30. uniform Int mode ,
  31. uniform Bool jitter ,
  32. uniform Bool normals ):COLOR
  33. {
  34. {
  35. Flt z;
  36. Vec2 nrm;
  37. if(normals)
  38. {
  39. Vec p=GetPos(TexDepthRawPoint(inTex), inPosXY); z=p.z; // !! for AO shader depth is already linearized !!
  40. #if 1 // sharp normal, looks better
  41. Vec n=TexLod(Nrm, inTex).xyz; // use linear filtering because Nrm may be bigger
  42. #if !SIGNED_NRM_RT
  43. n-=0.5f; // normally it should be "n=n*2-1", however since the normal doesn't need to be normalized, we can just do -0.5
  44. #endif
  45. #else // smoothened normal, less detail
  46. Flt zl=TexDepthRawPoint(inTex+ColSize.xy*Vec2(-1, 0)),
  47. zr=TexDepthRawPoint(inTex+ColSize.xy*Vec2( 1, 0)),
  48. zd=TexDepthRawPoint(inTex+ColSize.xy*Vec2( 0,-1)),
  49. zu=TexDepthRawPoint(inTex+ColSize.xy*Vec2( 0, 1)),
  50. dl=z-zl, dr=zr-z, adr=Abs(dr), adl=Abs(dl),
  51. dd=z-zd, du=zu-z, adu=Abs(du), add=Abs(dd);
  52. Vec2 smooth_ru=Vec2(Sat(1-adr*2), Sat(1-adu*2)),
  53. smooth_ld=Vec2(Sat(1-adl*2), Sat(1-add*2));
  54. // read two normals from texture, convert to -1..1 scale and average them
  55. // ((n1*2-1) + (n2*2-1))/2 = n1+n2-1
  56. Vec n=TexLod(Nrm, inTex+ColSize.xy*0.5f*smooth_ru).xyz+ // apply 0.5 scale so we get a smooth texel from 4 values using bilinear filtering
  57. TexLod(Nrm, inTex-ColSize.xy*0.5f*smooth_ld).xyz; // apply 0.5 scale so we get a smooth texel from 4 values using bilinear filtering
  58. #if !SIGNED_NRM_RT
  59. n-=2*0.5f; // same as above (0.5f) but for 2 Tex reads
  60. #endif
  61. #endif
  62. //n=Normalize(n); 'n' does not need to be normalized, because following codes don't require that
  63. Vec dir_right=Normalize(Vec(ScreenToPosXY(inTex+Vec2(ColSize.x, 0)), 1)),
  64. dir_up =Normalize(Vec(ScreenToPosXY(inTex+Vec2(0, ColSize.y)), 1));
  65. #if 0
  66. Vec pr=PointOnPlaneRay(Vec(0, 0, 0), p, n, dir_right),
  67. pu=PointOnPlaneRay(Vec(0, 0, 0), p, n, dir_up );
  68. nrm=Vec2(pr.z-z, pu.z-z)*ColSize.zw;
  69. #else // optimized
  70. Flt pr_z=dir_right.z*Dot(p, n)/Dot(dir_right, n),
  71. pu_z=dir_up .z*Dot(p, n)/Dot(dir_up , n);
  72. nrm=Vec2(pr_z-z, pu_z-z)*ColSize.zw;
  73. #endif
  74. }else
  75. {
  76. // !! for AO shader depth is already linearized !!
  77. z =TexDepthRawPoint(inTex);
  78. Flt zl=TexDepthRawPoint(inTex-Vec2(ColSize.x, 0)),
  79. zr=TexDepthRawPoint(inTex+Vec2(ColSize.x, 0)),
  80. zd=TexDepthRawPoint(inTex-Vec2(0, ColSize.y)),
  81. zu=TexDepthRawPoint(inTex+Vec2(0, ColSize.y)),
  82. dl=z-zl, dr=zr-z,
  83. dd=z-zd, du=zu-z;
  84. nrm=Vec2((Abs(dl)<Abs(dr)) ? dl : dr,
  85. (Abs(dd)<Abs(du)) ? dd : du)*ColSize.zw;
  86. }
  87. Vec2 cos_sin;
  88. if(jitter)
  89. {
  90. Flt a =Sum(pixel.xy*Vec2(0.5f, 0.25f)),
  91. angle=0.8f;
  92. a=Frac(a)*angle - 0.5f*angle; // (Frac(a)-0.5f)*angle;
  93. CosSin(cos_sin.x, cos_sin.y, a);
  94. }
  95. Flt scale =1/Max(1.0f, z),
  96. occl =0,
  97. weight=EPS,
  98. bias =AmbBias/AmbScale + z/1024; // increase bias with camera distance to deal with artifacts (best noticed in World Editor with only Ambient Light set to full, no other lights, terrain material set to white without textures, ambient contrast >=1 and ambient mode "Low")
  99. #if DUAL
  100. Vec2 offs_scale[2]={Viewport.size_fov_tan*scale*AmbRange.x, Viewport.size_fov_tan*scale*AmbRange.y};
  101. #else
  102. Vec2 offs_scale=Viewport.size_fov_tan*scale*AmbRange.x;
  103. #endif
  104. // required for later optimizations
  105. #if DUAL
  106. Flt range[2]={-1/AmbScale/AmbRange.x, -1/AmbScale/AmbRange.y};
  107. Vec2 NRM [2]={nrm*range[0]*-5 , nrm*range[1]*-5 };
  108. Flt Z [2]={ -z*range[0] - bias , -z*range[1] - bias };
  109. #else
  110. Flt range=-1/AmbScale/AmbRange.x;
  111. nrm*=range*-5;
  112. z =-z*range - bias;
  113. #endif
  114. Int elms;
  115. if(mode==0)elms=AO0Elms;else
  116. if(mode==1)elms=AO1Elms;else
  117. if(mode==2)elms=AO2Elms;else
  118. elms=AO3Elms;
  119. Int mid =elms/2;
  120. UNROLL for(Int i=0; i<elms; i++)
  121. {
  122. const Bool index=(i<mid);
  123. Vec pattern;
  124. if(mode==0)pattern=AO0Vec[i];else
  125. if(mode==1)pattern=AO1Vec[i];else
  126. if(mode==2)pattern=AO2Vec[i];else
  127. pattern=AO3Vec[i];
  128. #if DUAL
  129. Vec2 offs=pattern.xy*offs_scale[index];
  130. #else
  131. Vec2 offs=pattern.xy*offs_scale;
  132. #endif
  133. if(jitter)offs=Rotate(offs, cos_sin);
  134. offs=Round (offs*ColSize.zw)*ColSize.xy; // doesn't make a big difference for pixels close to camera, but makes a HUGE difference for pixels far away, keep !! otherwise distant terrain gets unnaturally shaded
  135. Vec2 t=inTex+offs;
  136. // !! for AO shader depth is already linearized !!
  137. #if 0 // Unoptimized
  138. Flt range=AmbScale*AmbRange.x,
  139. delta=z - AmbBias*AmbRange - TexDepthRawPoint(t), // apply bias to Z and calculate delta between TexDepth at that location, can use point filtering because we've rounded 't'
  140. expected=Sum(nrm*offs), // this is the expected delta
  141. o=Sat((delta+expected)/(range/5)),
  142. w=BlendSqr(delta/range); // ignore samples that are out of range (Z dist)
  143. if(delta<=-range){o=0; w=1;} // if sample is behind us and out of range, then set it as brightening
  144. #else // Optimized
  145. #if DUAL
  146. Flt delta=TexDepthRawPoint(t)*range[index]+Z[index], // !! for AO shader depth is already linearized !! can use point filtering because we've rounded 't'
  147. o=Sat(delta*5+Sum(NRM[index]*offs)),
  148. #else
  149. Flt delta=TexDepthRawPoint(t)*range+z, // !! for AO shader depth is already linearized !! can use point filtering because we've rounded 't'
  150. o=Sat(delta*5+Sum(nrm*offs)),
  151. #endif
  152. w=BlendSqr(delta); // ignore samples that are out of range (Z dist)
  153. if(delta<=-1){o=0; w=1;} // if sample is behind us and out of range, then set it as brightening
  154. #endif
  155. //w *=pattern.z; // focus on samples near to the center (XY dist)
  156. occl +=w*o;
  157. weight+=w;
  158. }
  159. return 1-AmbContrast*occl/weight; // result is stored in One Channel 1 Byte RT so it doesn't need 'Sat' saturation
  160. }
  161. }
  162. /******************************************************************************/
  163. TECHNIQUE(AO0 , DrawPosXY_VS(), AO_PS(0, false, false));
  164. TECHNIQUE(AO1 , DrawPosXY_VS(), AO_PS(1, false, false));
  165. TECHNIQUE(AO2 , DrawPosXY_VS(), AO_PS(2, false, false));
  166. TECHNIQUE(AO3 , DrawPosXY_VS(), AO_PS(3, false, false));
  167. TECHNIQUE(AO0J , DrawPosXY_VS(), AO_PS(0, true , false));
  168. TECHNIQUE(AO1J , DrawPosXY_VS(), AO_PS(1, true , false));
  169. TECHNIQUE(AO2J , DrawPosXY_VS(), AO_PS(2, true , false));
  170. TECHNIQUE(AO3J , DrawPosXY_VS(), AO_PS(3, true , false));
  171. TECHNIQUE(AO0N , DrawPosXY_VS(), AO_PS(0, false, true ));
  172. TECHNIQUE(AO1N , DrawPosXY_VS(), AO_PS(1, false, true ));
  173. TECHNIQUE(AO2N , DrawPosXY_VS(), AO_PS(2, false, true ));
  174. TECHNIQUE(AO3N , DrawPosXY_VS(), AO_PS(3, false, true ));
  175. TECHNIQUE(AO0JN, DrawPosXY_VS(), AO_PS(0, true , true ));
  176. TECHNIQUE(AO1JN, DrawPosXY_VS(), AO_PS(1, true , true ));
  177. TECHNIQUE(AO2JN, DrawPosXY_VS(), AO_PS(2, true , true ));
  178. TECHNIQUE(AO3JN, DrawPosXY_VS(), AO_PS(3, true , true ));
  179. /******************************************************************************/