Advertisement
Masterchoc

Untitled

Sep 29th, 2019
785
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.69 KB | None | 0 0
  1. #include "rzpch.h"
  2. #include "ShadowCascade.h"
  3. #include "Razor/Cameras/Camera.h"
  4. #include "Razor/Lighting/Directional.h"
  5. #include "Razor/Buffers/TextureAttachment.h"
  6. #include "Razor/Buffers/FrameBuffer.h"
  7.  
  8. namespace Razor
  9. {
  10.     ShadowCascade::ShadowCascade(FrameBuffer* frame_buffer, const glm::vec2& size, const glm::vec2& clip_planes) :
  11.         frame_buffer(frame_buffer),
  12.         size(size),
  13.         clip_planes(clip_planes),
  14.         depth_texture(nullptr),
  15.         proj_view_matrix(glm::mat4(1.0f)),
  16.         ortho_proj_matrix(glm::mat4(1.0f)),
  17.         light_view_matrix(glm::mat4(1.0f)),
  18.         centroid(glm::vec3(0.0f)),
  19.         frustum_corners({ glm::vec3(0.0f) })
  20.     {
  21.         depth_texture = frame_buffer->addTextureAttachment(size, true);
  22.     }
  23.  
  24.     ShadowCascade::~ShadowCascade()
  25.     {
  26.         delete depth_texture;
  27.     }
  28.  
  29.     void ShadowCascade::update(Camera* camera, const glm::mat4& view_matrix, std::shared_ptr<Directional> light)
  30.     {
  31.         float aspect = camera->getAspectRatio();
  32.  
  33.         proj_view_matrix = glm::perspective(camera->getFov(), aspect, clip_planes.x, clip_planes.y);
  34.         proj_view_matrix *= view_matrix;
  35.  
  36.         float max_z = std::numeric_limits<float>::min();
  37.         float min_z = std::numeric_limits<float>::max();
  38.  
  39.         for (unsigned int i = 0; i < FRUSTUM_CORNERS; i++)
  40.         {
  41.             frustum_corners[i] = glm::vec3(0.0f);
  42.             frustumCorner(proj_view_matrix, i, frustum_corners[i]);
  43.  
  44.             centroid += frustum_corners[i];
  45.             centroid /= 8.0f;
  46.  
  47.             min_z = std::min(min_z, frustum_corners[i].z);
  48.             max_z = std::max(max_z, frustum_corners[i].z);
  49.         }
  50.  
  51.         glm::vec3 light_dir = light->getDirection();
  52.         glm::vec3 pos = glm::vec3(light_dir);
  53.  
  54.         float distance = max_z - min_z;
  55.         pos *= distance;
  56.        
  57.         glm::vec3 light_pos = glm::vec3(centroid);
  58.         light_pos += pos;
  59.  
  60.         updateLightViewMatrix(light_dir, light_pos);
  61.         updateLightProjectionMatrix();
  62.     }
  63.  
  64.     void ShadowCascade::updateLightViewMatrix(const glm::vec3& light_direction, const glm::vec3& light_position)
  65.     {
  66.         float x = glm::degrees(acos(light_direction.z));
  67.         float y = glm::degrees(asin(light_direction.x));
  68.         float z = 0.0f;
  69.  
  70.         glm::mat4 rot_x = glm::rotate(glm::radians(x), glm::vec3(1.0f, 0.0f, 0.0f));
  71.         glm::mat4 rot_y = glm::rotate(glm::radians(y), glm::vec3(0.0f, 1.0f, 0.0f));
  72.         glm::mat4 translation = glm::translate(-light_position);
  73.  
  74.         light_view_matrix = rot_x * rot_y * translation;
  75.     }
  76.  
  77.     void ShadowCascade::updateLightProjectionMatrix()
  78.     {
  79.         const float MIN = std::numeric_limits<float>::min();
  80.         const float MAX = std::numeric_limits<float>::max();
  81.  
  82.         float min_x =  MAX;
  83.         float max_x = -MIN;
  84.  
  85.         float min_y =  MAX;
  86.         float max_y = -MIN;
  87.  
  88.         float min_z =  MAX;
  89.         float max_z = -MIN;
  90.  
  91.         for (unsigned int i = 0; i < FRUSTUM_CORNERS; i++)
  92.         {
  93.             glm::vec3 corner = frustum_corners[i];
  94.             temp = glm::vec4(corner, 1.0f);
  95.             temp = light_view_matrix * temp;
  96.  
  97.             min_x = std::min(temp.x, min_x);
  98.             max_x = std::max(temp.x, max_x);
  99.  
  100.             min_y = std::min(temp.y, min_y);
  101.             max_y = std::max(temp.y, max_y);
  102.  
  103.             min_z = std::min(temp.z, min_z);
  104.             max_z = std::max(temp.z, max_z);
  105.         }
  106.  
  107.         float distance = max_z - min_z;
  108.         ortho_proj_matrix = glm::ortho(min_x, max_x, min_y, max_y, 0.0f, distance);
  109.     }
  110.  
  111.     glm::vec3 ShadowCascade::frustumCorner(const glm::mat4& m, int corner, glm::vec3& point)
  112.     {
  113.         float d1 = 0.0f, d2 = 0.0f, d3 = 0.0f;
  114.  
  115.         float n1x = 0.0f, n1y = 0.0f, n1z = 0.0f,
  116.               n2x = 0.0f, n2y = 0.0f, n2z = 0.0f,
  117.               n3x = 0.0f, n3y = 0.0f, n3z = 0.0f;
  118.  
  119.         switch (corner) {
  120.         case 0:
  121.             n1x = m[0][3] + m[0][0];    n1y = m[1][3] + m[1][0];    n1z = m[2][3] + m[2][0];    d1 = m[3][3] + m[3][0];
  122.             n2x = m[0][3] + m[0][1];    n2y = m[1][3] + m[1][1];    n1z = m[2][3] + m[2][1];    d2 = m[3][3] + m[3][1];
  123.             n3x = m[0][3] + m[0][2];    n3y = m[1][3] + m[1][2];    n3z = m[2][3] + m[2][2];    d3 = m[3][3] + m[3][2];
  124.             break;
  125.         case 1:
  126.             n1x = m[0][3] - m[0][0];    n1y = m[1][3] - m[1][0];    n1z = m[2][3] - m[2][0];    d1 = m[3][3] - m[3][0];
  127.             n2x = m[0][3] + m[0][1];    n2y = m[1][3] + m[1][1];    n1z = m[2][3] + m[2][1];    d2 = m[3][3] + m[3][1];
  128.             n3x = m[0][3] + m[0][2];    n3y = m[1][3] + m[1][2];    n3z = m[2][3] + m[2][2];    d3 = m[3][3] + m[3][2];
  129.             break;
  130.         case 2:
  131.             n1x = m[0][3] - m[0][0];    n1y = m[1][3] - m[1][0];    n1z = m[2][3] - m[2][0];    d1 = m[3][3] - m[3][0];
  132.             n2x = m[0][3] - m[0][1];    n2y = m[1][3] - m[1][1];    n1z = m[2][3] - m[2][1];    d2 = m[3][3] - m[3][1];
  133.             n3x = m[0][3] + m[0][2];    n3y = m[1][3] + m[1][2];    n3z = m[2][3] + m[2][2];    d3 = m[3][3] + m[3][2];
  134.             break;
  135.         case 3:
  136.             n1x = m[0][3] + m[0][0];    n1y = m[1][3] + m[1][0];    n1z = m[2][3] + m[2][0];    d1 = m[3][3] + m[3][0];
  137.             n2x = m[0][3] - m[0][1];    n2y = m[1][3] - m[1][1];    n1z = m[2][3] - m[2][1];    d2 = m[3][3] - m[3][1];
  138.             n3x = m[0][3] + m[0][2];    n3y = m[1][3] + m[1][2];    n3z = m[2][3] + m[2][2];    d3 = m[3][3] + m[3][2];
  139.             break;
  140.         case 4:
  141.             n1x = m[0][3] - m[0][0];    n1y = m[1][3] - m[1][0];    n1z = m[2][3] - m[2][0];    d1 = m[3][3] - m[3][0];
  142.             n2x = m[0][3] + m[0][1];    n2y = m[1][3] + m[1][1];    n1z = m[2][3] + m[2][1];    d2 = m[3][3] + m[3][1];
  143.             n3x = m[0][3] - m[0][2];    n3y = m[1][3] - m[1][2];    n3z = m[2][3] - m[2][2];    d3 = m[3][3] - m[3][2];
  144.             break;
  145.         case 5:
  146.             n1x = m[0][3] + m[0][0];    n1y = m[1][3] + m[1][0];    n1z = m[2][3] + m[2][0];    d1 = m[3][3] + m[3][0];
  147.             n2x = m[0][3] + m[0][1];    n2y = m[1][3] + m[1][1];    n1z = m[2][3] + m[2][1];    d2 = m[3][3] + m[3][1];
  148.             n3x = m[0][3] - m[0][2];    n3y = m[1][3] - m[1][2];    n3z = m[2][3] - m[2][2];    d3 = m[3][3] - m[3][2];
  149.             break;
  150.         case 6:
  151.             n1x = m[0][3] + m[0][0];    n1y = m[1][3] + m[1][0];    n1z = m[2][3] + m[2][0];    d1 = m[3][3] + m[3][0];
  152.             n2x = m[0][3] - m[0][1];    n2y = m[1][3] - m[1][1];    n1z = m[2][3] - m[2][1];    d2 = m[3][3] - m[3][1];
  153.             n3x = m[0][3] - m[0][2];    n3y = m[1][3] - m[1][2];    n3z = m[2][3] - m[2][2];    d3 = m[3][3] - m[3][2];
  154.             break;
  155.         case 7:
  156.             n1x = m[0][3] - m[0][0];    n1y = m[1][3] - m[1][0];    n1z = m[2][3] - m[2][0];    d1 = m[3][3] - m[3][0];
  157.             n2x = m[0][3] - m[0][1];    n2y = m[1][3] - m[1][1];    n1z = m[2][3] - m[2][1];    d2 = m[3][3] - m[3][1];
  158.             n3x = m[0][3] - m[0][2];    n3y = m[1][3] - m[1][2];    n3z = m[2][3] - m[2][2];    d3 = m[3][3] - m[3][2];
  159.             break;
  160.         }
  161.  
  162.         float
  163.             c23x = 0.0f, c23y = 0.0f, c23z = 0.0f,
  164.             c31x = 0.0f, c31y = 0.0f, c31z = 0.0f,
  165.             c12x = 0.0f, c12y = 0.0f, c12z = 0.0f;
  166.  
  167.         c23x = n2y * n3z - n2z * n3y;
  168.         c23y = n2z * n3x - n2x * n3z;
  169.         c23z = n2x * n3y - n2y * n3x;
  170.  
  171.         c31x = n3y * n1z - n3z * n1y;
  172.         c31y = n3z * n1x - n3x * n1z;
  173.         c31z = n3x * n1y - n3y * n1x;
  174.  
  175.         c12x = n1y * n2z - n1z * n2y;
  176.         c12y = n1z * n2x - n1x * n2z;
  177.         c12z = n1x * n2y - n1y * n2x;
  178.  
  179.         float inverse = 1.0f / (n1x * c23x + n1y * c23y + n1z * c23z);
  180.  
  181.         point.x = (-c23x * d1 - c31x * d2 - c12x * d3) * inverse;
  182.         point.y = (-c23y * d1 - c31y * d2 - c12y * d3) * inverse;
  183.         point.z = (-c23z * d1 - c31z * d2 * c12z * d3) * inverse;
  184.  
  185.         return point;
  186.     }
  187.  
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement