IrradianceDice.hlsl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. // Irradiance dice utilities
  6. #pragma once
  7. #include <AnKi/Shaders/Common.hlsl>
  8. template<typename T>
  9. struct IrradianceDice
  10. {
  11. vector<T, 3> m_directions[6u]; // +x, -x, +y, -y, +z, -z
  12. };
  13. template<typename T>
  14. IrradianceDice<T> appendIrradianceDice(IrradianceDice<T> input, vector<T, 3> direction, vector<T, 3> radiance, U32 sampleCount)
  15. {
  16. const T weight = T(kPi) / (sampleCount / 2u);
  17. const vector<T, 3> wRadiance = radiance * weight;
  18. input.m_directions[0] += wRadiance * max(T(0), dot(direction, vector<T, 3>(1, 0, 0)));
  19. input.m_directions[1] += wRadiance * max(T(0), dot(direction, vector<T, 3>(-1, 0, 0)));
  20. input.m_directions[2] += wRadiance * max(T(0), dot(direction, vector<T, 3>(0, 1, 0)));
  21. input.m_directions[3] += wRadiance * max(T(0), dot(direction, vector<T, 3>(0, -1, 0)));
  22. input.m_directions[4] += wRadiance * max(T(0), dot(direction, vector<T, 3>(0, 0, 1)));
  23. input.m_directions[5] += wRadiance * max(T(0), dot(direction, vector<T, 3>(0, 0, -1)));
  24. return input;
  25. }
  26. // Given the value of the 6 faces of the dice and a normal, sample the correct weighted value.
  27. // https://www.shadertoy.com/view/XtcBDB
  28. template<typename T>
  29. vector<T, 3> evaluateIrradianceDice(IrradianceDice<T> dice, vector<T, 3> direction)
  30. {
  31. const vector<T, 3> axisWeights = direction * direction;
  32. const vector<T, 3> uv = direction * T(0.5) + T(0.5);
  33. vector<T, 3> irradiance = lerp(dice.m_directions[1], dice.m_directions[0], uv.x) * axisWeights.x;
  34. irradiance += lerp(dice.m_directions[3], dice.m_directions[2], uv.y) * axisWeights.y;
  35. irradiance += lerp(dice.m_directions[5], dice.m_directions[4], uv.z) * axisWeights.z;
  36. // Divide by weight
  37. irradiance /= axisWeights.x + axisWeights.y + axisWeights.z + T(0.0001);
  38. return irradiance;
  39. }
  40. template<typename T>
  41. IrradianceDice<T> lerpIrradianceDice(IrradianceDice<T> a, IrradianceDice<T> b, T f)
  42. {
  43. [unroll] for(U32 i = 0; i < 6u; ++i)
  44. {
  45. a.m_directions[i] = lerp(a.m_directions[i], b.m_directions[i], f);
  46. }
  47. return a;
  48. }
  49. template<typename T, U32 kVolumeCount>
  50. IrradianceDice<T> loadIrradianceDice(Texture3D<Vec4> volumes[kVolumeCount], SamplerState sampler, Vec3 uvw, U32 firstVolume = 0)
  51. {
  52. IrradianceDice<T> dice;
  53. [unroll] for(U32 i = 0; i < 6; ++i)
  54. {
  55. dice.m_directions[i] = volumes[firstVolume + i].SampleLevel(sampler, uvw, 0.0).xyz;
  56. // dice.m_directions[i] = textureLinear<F16, 3>(volumes[firstVolume + i], uvw).xyz;
  57. }
  58. return dice;
  59. }
  60. template<typename T, U32 kVolumeCount>
  61. IrradianceDice<T> loadIrradianceDice(Texture3D<Vec4> volumes[kVolumeCount], UVec3 uvw, U32 firstVolume = 0)
  62. {
  63. IrradianceDice<T> dice;
  64. [unroll] for(U32 i = 0; i < 6; ++i)
  65. {
  66. dice.m_directions[i] = volumes[firstVolume + i][uvw].xyz;
  67. }
  68. return dice;
  69. }
  70. template<typename T, U32 kVolumeCount>
  71. IrradianceDice<T> loadIrradianceDice(RWTexture3D<Vec4> volumes[kVolumeCount], UVec3 uvw, U32 firstVolume = 0)
  72. {
  73. IrradianceDice<T> dice;
  74. [unroll] for(U32 i = 0; i < 6; ++i)
  75. {
  76. dice.m_directions[i] = volumes[firstVolume + i][uvw].xyz;
  77. }
  78. return dice;
  79. }
  80. template<typename T, U32 kVolumeCount>
  81. void storeIrradianceDice(IrradianceDice<T> dice, RWTexture3D<Vec4> volumes[kVolumeCount], UVec3 coords, U32 firstVolume = 0)
  82. {
  83. [unroll] for(U32 i = 0; i < 6; ++i)
  84. {
  85. volumes[firstVolume + i][coords] = vector<T, 4>(dice.m_directions[i], T(0));
  86. }
  87. }