Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.09 KB | None | 0 0
  1. // -----------------------------------------------------------------------------
  2.  
  3. /*
  4. * This method creates a mipmap hierarchy for
  5. * the texture.
  6. *
  7. * This is done by iteratively reducing the
  8. * dimenison of a mipmap level and averaging
  9. * pixel values until the size of a mipmap
  10. * level is [1, 1].
  11. *
  12. * The original data of the texture is stored
  13. * in mip_levels[0].
  14. *
  15. * You can allocale memory for a new mipmap level
  16. * with dimensions (size_x, size_y) using
  17. * mip_levels.emplace_back(new Image(size_x, size_y));
  18. */
  19. void ImageTexture::
  20. create_mipmap()
  21. {
  22. /* this are the dimensions of the original texture/image */
  23. int size_x = mip_levels[0]->getWidth();
  24. int size_y = mip_levels[0]->getHeight();
  25.  
  26. cg_assert((size_x % 2 == 0) && !(size_x & (size_x - 1)));
  27. cg_assert((size_y % 2 == 0) && !(size_y & (size_y - 1)));
  28. int level = 0;
  29.  
  30. while (size_x > 1 && size_y > 1) {
  31. level++;
  32.  
  33. int redx = size_x > 1 ? 2 : 1;
  34. int redy = size_y > 1 ? 2 : 1;
  35.  
  36. size_x = size_x /redx;
  37. size_y = size_y /redy;
  38.  
  39.  
  40.  
  41. mip_levels.emplace_back(new Image(size_x, size_y));
  42. for (int x = 0; x < size_x; x++) {
  43. for ( int y = 0; y < size_y; y++){
  44. glm::vec4 px1 = mip_levels[level -1]->getPixel(x*redx, y*redy);
  45. glm::vec4 px2 = mip_levels[level -1]->getPixel(x*redx+1, y*redy);
  46. glm::vec4 px3 = mip_levels[level -1]->getPixel(x*redx, y*redy+1);
  47. glm::vec4 px4 = mip_levels[level -1]->getPixel(x*redx+1, y*redy+1);
  48. glm::vec4 avgpx = (px1 + px2 + px3 + px4)/ 4.f ;
  49. mip_levels[level]->setPixel(x, y, avgpx);
  50.  
  51. }
  52. }
  53. }
  54.  
  55. }
  56.  
  57. /*
  58. * Compute the dimensions of the pixel footprint's AABB in uv-space.
  59. *
  60. * First intersect the four rays through the pixel corners with
  61. * the tangent plane at the given intersection.
  62. *
  63. * Then the given code computes uv-coordinates for these
  64. * intersection points.
  65. *
  66. * Finally use the uv-coordinates and compute the AABB in
  67. * uv-space.
  68. *
  69. * Return width (du) and height (dv) of the AABB.
  70. *
  71. */
  72. glm::vec2 Object::
  73. compute_uv_aabb_size(const Ray rays[4], Intersection const& isect)
  74. {
  75. // TODO: compute intersection positions
  76. glm::vec3 intersection_positions[4] = {
  77. isect.position, isect.position, isect.position, isect.position
  78. };
  79.  
  80.  
  81. for (int i = 0; i < 4; ++i) {
  82. // todo: compute intersection positions using a ray->plane
  83. // intersection
  84. Ray r = rays[i];
  85. float t = 0;
  86. if (intersect_plane(r.origin,r.direction, isect.position, isect.normal, &t)) {
  87. if( t>0) {
  88. intersection_positions[i] = r.origin + t * r.direction;
  89. }
  90. }
  91. }
  92.  
  93. // compute uv coordinates from intersection positions
  94. glm::vec2 intersection_uvs[4];
  95. get_intersection_uvs(intersection_positions, isect, intersection_uvs);
  96.  
  97. // TODO: compute dudv = length of sides of AABB in uv space
  98. float minx = intersection_positions[0].x;
  99. float maxx = intersection_positions[0].x;
  100. float miny = intersection_positions[0].y;
  101. float maxy = intersection_positions[0].y;
  102.  
  103. for (int i = 0; i < 4; i++){
  104. minx = std::min(minx, intersection_uvs[i].x);
  105. maxx = std::max(maxx, intersection_uvs[i].x);
  106. miny = std::min(miny, intersection_uvs[i].y);
  107. maxy = std::max(maxy, intersection_uvs[i].y);
  108. }
  109. return glm::vec2(maxx-minx, maxy-miny);
  110. }
  111.  
  112. /*
  113. * Implement trilinear filtering at a given uv-position.
  114. *
  115. * Transform the AABB dimensions dudv in st-space and
  116. * take the maximal coordinate as the 1D footprint size T.
  117. *
  118. * Determine mipmap levels i and i+1 such that
  119. * texel_size(i) <= T <= texel_size(i+1)
  120. *
  121. * Hint: use std::log2(T) for that.
  122. *
  123. * Perform bilinear filtering in both mipmap levels and
  124. * linearly interpolate the resulting values.
  125. *
  126. */
  127. glm::vec4 ImageTexture::
  128. evaluate_trilinear(glm::vec2 const& uv, glm::vec2 const& dudv) const
  129. {
  130. float T = std::max(dudv.x * mip_levels[0]->getWidth(), dudv.y * mip_levels[0]->getHeight());
  131. float level = std::max(0.f, log2(T));
  132.  
  133. if (level >= mip_levels.size() - 1) {
  134. return evaluate_bilinear(mip_levels.size() - 1, uv);
  135. }
  136. float fak = level - floor(level);
  137. return (1-fak) * evaluate_bilinear(floor(level), uv) + fak * evaluate_bilinear(ceil(level), uv);
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement