RaytraceRender.fs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. out vec4 OutColor;
  2. // Seed for random number generator (generated on CPU).
  3. uniform int uFrameRndSeed;
  4. //! Enables/disables using of single RNG seed for 16x16 image
  5. //! blocks. Increases performance up to 4x, but the noise has
  6. //! become structured. Can be used fo final rendering.
  7. uniform int uBlockedRngEnabled;
  8. //! Number of previously rendered frames (used in non-ISS mode).
  9. uniform int uAccumSamples;
  10. #ifndef ADAPTIVE_SAMPLING
  11. //! Input image with previously accumulated samples.
  12. uniform sampler2D uAccumTexture;
  13. #endif
  14. //! Maximum radiance that can be added to the pixel.
  15. //! Decreases noise level, but introduces some bias.
  16. uniform float uMaxRadiance;
  17. #ifdef ADAPTIVE_SAMPLING
  18. //! Wrapper over imageLoad()+imageStore() having similar syntax as imageAtomicAdd().
  19. //! Modifies one component of 3Wx2H uRenderImage:
  20. //! |RGL| Red, Green, Luminance
  21. //! |SBH| Samples, Blue, Hit time transformed into OpenGL NDC space
  22. //! Returns previous value of the component.
  23. float addRenderImageComp (in ivec2 theFrag, in ivec2 theComp, in float theVal)
  24. {
  25. ivec2 aCoord = ivec2 (3 * theFrag.x + theComp.x,
  26. 2 * theFrag.y + theComp.y);
  27. #ifdef ADAPTIVE_SAMPLING_ATOMIC
  28. return imageAtomicAdd (uRenderImage, aCoord, theVal);
  29. #else
  30. float aVal = imageLoad (uRenderImage, aCoord).x;
  31. imageStore (uRenderImage, aCoord, vec4 (aVal + theVal));
  32. return aVal;
  33. #endif
  34. }
  35. #endif
  36. // =======================================================================
  37. // function : main
  38. // purpose :
  39. // =======================================================================
  40. void main (void)
  41. {
  42. SeedRand (uFrameRndSeed, uWinSizeX, uBlockedRngEnabled == 0 ? 1 : 16);
  43. #ifndef PATH_TRACING
  44. SRay aRay = GenerateRay (vPixel);
  45. #else
  46. ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);
  47. #ifdef ADAPTIVE_SAMPLING
  48. #ifdef ADAPTIVE_SAMPLING_ATOMIC
  49. ivec2 aTileXY = imageLoad (uOffsetImage, aFragCoord / uTileSize).xy * uTileSize;
  50. if (aTileXY.x < 0) { discard; }
  51. ivec2 aRealBlockSize = ivec2 (min (uWinSizeX - aTileXY.x, uTileSize.x),
  52. min (uWinSizeY - aTileXY.y, uTileSize.y));
  53. aFragCoord.x = aTileXY.x + (aFragCoord.x % aRealBlockSize.x);
  54. aFragCoord.y = aTileXY.y + (aFragCoord.y % aRealBlockSize.y);
  55. #else
  56. int aNbTileSamples = imageAtomicAdd (uTilesImage, aFragCoord / uTileSize, int(-1));
  57. if (aNbTileSamples <= 0)
  58. {
  59. discard;
  60. }
  61. #endif
  62. #endif // ADAPTIVE_SAMPLING
  63. vec2 aPnt = vec2 (float(aFragCoord.x) + RandFloat(),
  64. float(aFragCoord.y) + RandFloat());
  65. SRay aRay = GenerateRay (aPnt / vec2 (uWinSizeX, uWinSizeY));
  66. #endif // PATH_TRACING
  67. vec3 aInvDirect = InverseDirection (aRay.Direct);
  68. #ifdef PATH_TRACING
  69. #ifndef ADAPTIVE_SAMPLING
  70. vec4 aColor = PathTrace (aRay, aInvDirect, uAccumSamples);
  71. #else
  72. float aNbSamples = addRenderImageComp (aFragCoord, ivec2 (0, 1), 1.0);
  73. vec4 aColor = PathTrace (aRay, aInvDirect, int (aNbSamples));
  74. #endif
  75. if (any (isnan (aColor.rgb)))
  76. {
  77. aColor.rgb = ZERO;
  78. }
  79. aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));
  80. #ifdef ADAPTIVE_SAMPLING
  81. // accumulate RGB color and depth
  82. addRenderImageComp (aFragCoord, ivec2 (0, 0), aColor.r);
  83. addRenderImageComp (aFragCoord, ivec2 (1, 0), aColor.g);
  84. addRenderImageComp (aFragCoord, ivec2 (1, 1), aColor.b);
  85. addRenderImageComp (aFragCoord, ivec2 (2, 1), aColor.w);
  86. if (int (aNbSamples) % 2 == 0) // accumulate luminance for even samples only
  87. {
  88. addRenderImageComp (aFragCoord, ivec2 (2, 0), dot (LUMA, aColor.rgb));
  89. }
  90. #else
  91. if (uAccumSamples == 0)
  92. {
  93. OutColor = aColor;
  94. }
  95. else
  96. {
  97. OutColor = mix (texture (uAccumTexture, vPixel), aColor, 1.0 / float(uAccumSamples + 1));
  98. }
  99. #endif // ADAPTIVE_SAMPLING
  100. #else
  101. OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
  102. #endif // PATH_TRACING
  103. }