Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.10 KB | None | 0 0
  1. inline float3 uv_to_sphere(const float2 uv, const float2 image_size)
  2. {
  3. float2 st = (uv+float2(0.5f)) / image_size;
  4. float latitude = (st.y - 0.5f) * PI;
  5. float longitude = (st.x - 0.5f) * 2 * PI;
  6. float radiusAtLat = cos(latitude);
  7. float3 normal;
  8. normal.x = radiusAtLat * cos(longitude);
  9. normal.y = sin(latitude);
  10. normal.z = radiusAtLat * sin(longitude);
  11. return normal;
  12. }
  13.  
  14. inline float2 sphere_to_uv(const float3 normal, const float2 image_size)
  15. {
  16. float latitude = asin(normal.y);
  17. float radiusAtLat = cos(latitude);
  18. float longitude = atan2(normal.z, normal.x);
  19. float2 st = float2(longitude/ (2 * PI) + 0.5f, latitude / PI + 0.5f);
  20. return st*image_size-float2(0.5f);
  21. }
  22.  
  23.  
  24. kernel Irradiance : ImageComputationKernel<ePixelWise>
  25. {
  26. Image<eRead, eAccessRandom, eEdgeConstant> src;
  27. Image<eWrite, eAccessPoint> dst;
  28.  
  29. param:
  30. float sampleDelta;
  31. float2 size;
  32.  
  33. void define() {
  34. defineParam(sampleDelta, "SampleDelta", 0.25f);
  35. defineParam(size, "Image Size", float2(1280.0f, 720.0f));
  36. }
  37.  
  38. void process(int2 pos)
  39. {
  40. SampleType(src) irradiance(0);
  41. float2 fpos = float2(pos.x,pos.y);
  42. float3 normal = normalize(uv_to_sphere(fpos, size));
  43.  
  44.  
  45. float3 up = float3(0.0f, 1.0f, 0.0f);
  46. float3 right = cross(up, normal);
  47. up = cross(normal, right);
  48.  
  49. int nrSamples = 0.0;
  50. for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
  51. {
  52. for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta)
  53. {
  54. // spherical to cartesian (in tangent space)
  55. float3 tangentSample = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
  56. // tangent space to world
  57. float3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * normal;
  58.  
  59. float2 coordinates = sphere_to_uv(sampleVec, size);
  60.  
  61. irradiance += bilinear(src, coordinates.x, coordinates.y) * cos(theta) * sin(theta);
  62. nrSamples++;
  63. }
  64. }
  65. irradiance = PI * irradiance * (1.0 / float(nrSamples));
  66.  
  67. //Use a bilinear filter to get the value at that src position.
  68. dst() = irradiance;
  69. }
  70.  
  71. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement