diff --git a/ArchitectureColoredPainting/Camera.h b/ArchitectureColoredPainting/Camera.h index df6541a..a464c8f 100644 --- a/ArchitectureColoredPainting/Camera.h +++ b/ArchitectureColoredPainting/Camera.h @@ -43,7 +43,7 @@ public: float Zoom; float Ratio; float NearPlane = 10.f; - float FarPlane = 10000.f; + float FarPlane = 5000.f; // constructor with vectors Camera(QVector3D position = QVector3D(0.0f, 0.0f, 0.0f), QVector3D up = QVector3D(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH); diff --git a/ArchitectureColoredPainting/Light.cpp b/ArchitectureColoredPainting/Light.cpp index 5553046..72ee815 100644 --- a/ArchitectureColoredPainting/Light.cpp +++ b/ArchitectureColoredPainting/Light.cpp @@ -2,136 +2,146 @@ #include Light::Light(Camera* camera) - : camera(camera) - , shadowCascadeLevels{ camera->FarPlane / 50.0f, camera->FarPlane / 25.0f, camera->FarPlane / 10.0f, camera->FarPlane / 2.0f } + : camera(camera) + //, shadowCascadeLevels{ camera->FarPlane / 25.0f, camera->FarPlane / 12.0f, camera->FarPlane / 6.0f, camera->FarPlane / 3.0f } { + const float levelCount = 5; + const float lambda = 0.5; + for (int i = 1; i < levelCount; i++) + { + shadowCascadeLevels.push_back( + lambda * camera->NearPlane * pow(camera->FarPlane / camera->NearPlane, i / levelCount) + + (1 - lambda) * (camera->NearPlane + i / levelCount * (camera->FarPlane - camera->NearPlane))); + //qDebug() << shadowCascadeLevels[i-1]; + } + } std::vector Light::getFrustumCornersWorldSpace(const QMatrix4x4& projview) { - const auto inv = projview.inverted(); + const auto inv = projview.inverted(); - std::vector frustumCorners; - for (unsigned int x = 0; x < 2; ++x) - { - for (unsigned int y = 0; y < 2; ++y) - { - for (unsigned int z = 0; z < 2; ++z) - { - const QVector4D pt = inv * QVector4D(2.0f * x - 1.0f, 2.0f * y - 1.0f, 2.0f * z - 1.0f, 1.0f); - frustumCorners.push_back(pt / pt.w()); - } - } - } + std::vector frustumCorners; + for (unsigned int x = 0; x < 2; ++x) + { + for (unsigned int y = 0; y < 2; ++y) + { + for (unsigned int z = 0; z < 2; ++z) + { + const QVector4D pt = inv * QVector4D(2.0f * x - 1.0f, 2.0f * y - 1.0f, 2.0f * z - 1.0f, 1.0f); + frustumCorners.push_back(pt / pt.w()); + } + } + } - return frustumCorners; + return frustumCorners; } std::vector Light::getFrustumCornersWorldSpace(const QMatrix4x4& proj, const QMatrix4x4& view) { - return getFrustumCornersWorldSpace(proj * view); + return getFrustumCornersWorldSpace(proj * view); } QMatrix4x4 Light::getLightSpaceMatrix(const float nearPlane, const float farPlane) { - QMatrix4x4 proj; - proj.perspective(camera->Zoom, camera->Ratio, nearPlane, farPlane); + QMatrix4x4 proj; + proj.perspective(camera->Zoom, camera->Ratio, nearPlane, farPlane); - const std::vector corners = getFrustumCornersWorldSpace(proj, camera->GetViewMatrix()); + const std::vector corners = getFrustumCornersWorldSpace(proj, camera->GetViewMatrix()); - QVector3D center = QVector3D(0, 0, 0); - for (const QVector4D& v : corners) - { - center += QVector3D(v); - } - center /= corners.size(); + QVector3D center = QVector3D(0, 0, 0); + for (const QVector4D& v : corners) + { + center += QVector3D(v); + } + center /= corners.size(); - QVector3D right = QVector3D::crossProduct(lightDirection, QVector3D(1, 0, 0)).normalized(); - QVector3D up = QVector3D::crossProduct(right, lightDirection).normalized(); - QMatrix4x4 lightView; - //qDebug() << "lightDirection:" << lightDirection << "up:" << up; - lightView.lookAt(center, center - lightDirection, up); + QVector3D right = QVector3D::crossProduct(lightDirection, QVector3D(1, 0, 0)).normalized(); + QVector3D up = QVector3D::crossProduct(right, lightDirection).normalized(); + QMatrix4x4 lightView; + //qDebug() << "lightDirection:" << lightDirection << "up:" << up; + lightView.lookAt(center, center - lightDirection, up); - float minX = std::numeric_limits::max(); - float maxX = std::numeric_limits::min(); - float minY = std::numeric_limits::max(); - float maxY = std::numeric_limits::min(); - float minZ = std::numeric_limits::max(); - float maxZ = std::numeric_limits::min(); - for (const QVector4D& v : corners) - { - QVector4D trf = lightView * v; - //qDebug() << v; - //qDebug() << trf; - minX = std::min(minX, trf.x()); - maxX = std::max(maxX, trf.x()); - minY = std::min(minY, trf.y()); - maxY = std::max(maxY, trf.y()); - minZ = std::min(minZ, -trf.z()); - maxZ = std::max(maxZ, -trf.z()); - } - for (const QVector3D& v : model->AABB) - { - const QVector4D trf = lightView * QVector4D(v, 1); - //qDebug() << v; - //qDebug() << trf; - //minX = std::min(minX, trf.x()); - //maxX = std::max(maxX, trf.x()); - //minY = std::min(minY, trf.y()); - //maxY = std::max(maxY, trf.y()); - minZ = std::min(minZ, -trf.z()); - //maxZ = std::max(maxZ, trf.z()); - - } - //qDebug() << minZ; - // Tune this parameter according to the scene + float minX = std::numeric_limits::max(); + float maxX = std::numeric_limits::min(); + float minY = std::numeric_limits::max(); + float maxY = std::numeric_limits::min(); + float minZ = std::numeric_limits::max(); + float maxZ = std::numeric_limits::min(); + for (const QVector4D& v : corners) + { + QVector4D trf = lightView * v; + //qDebug() << v; + //qDebug() << trf; + minX = std::min(minX, trf.x()); + maxX = std::max(maxX, trf.x()); + minY = std::min(minY, trf.y()); + maxY = std::max(maxY, trf.y()); + minZ = std::min(minZ, -trf.z()); + maxZ = std::max(maxZ, -trf.z()); + } + for (const QVector3D& v : model->AABB) + { + const QVector4D trf = lightView * QVector4D(v, 1); + //qDebug() << v; + //qDebug() << trf; + //minX = std::min(minX, trf.x()); + //maxX = std::max(maxX, trf.x()); + //minY = std::min(minY, trf.y()); + //maxY = std::max(maxY, trf.y()); + minZ = std::min(minZ, -trf.z()); + //maxZ = std::max(maxZ, trf.z()); + + } + //qDebug() << minZ; + // Tune this parameter according to the scene /* constexpr float zMult = 10.0f; - if (minZ < 0) - { - minZ *= zMult; - } - else - { - minZ /= zMult; - } - if (maxZ < 0) - { - maxZ /= zMult; - } - else - { - maxZ *= zMult; - }*/ + if (minZ < 0) + { + minZ *= zMult; + } + else + { + minZ /= zMult; + } + if (maxZ < 0) + { + maxZ /= zMult; + } + else + { + maxZ *= zMult; + }*/ - QMatrix4x4 lightProjection; - //qDebug() << minX<< maxX<< minY<< maxY<< minZ<< maxZ; - lightProjection.ortho(minX, maxX, minY, maxY, minZ, maxZ); - frustumSizes.push_back(std::max(maxX - minX, maxY - minY)); - return lightProjection * lightView; + QMatrix4x4 lightProjection; + //qDebug() << minX<< maxX<< minY<< maxY<< minZ<< maxZ; + lightProjection.ortho(minX, maxX, minY, maxY, minZ, maxZ); + frustumSizes.push_back(std::max(maxX - minX, maxY - minY)); + return lightProjection * lightView; } std::vector Light::getLightSpaceMatrices() { - std::vector ret; - frustumSizes.clear(); - for (size_t i = 0; i < shadowCascadeLevels.size() + 1; ++i) - { - if (i == 0) - { - ret.push_back(getLightSpaceMatrix(camera->NearPlane, shadowCascadeLevels[i])); - } - else if (i < shadowCascadeLevels.size()) - { - ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], shadowCascadeLevels[i])); - } - else - { - ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], camera->FarPlane)); - } - } - return ret; + std::vector ret; + frustumSizes.clear(); + for (size_t i = 0; i < shadowCascadeLevels.size() + 1; ++i) + { + if (i == 0) + { + ret.push_back(getLightSpaceMatrix(camera->NearPlane, shadowCascadeLevels[i])); + } + else if (i < shadowCascadeLevels.size()) + { + ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], shadowCascadeLevels[i])); + } + else + { + ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], camera->FarPlane)); + } + } + return ret; } diff --git a/ArchitectureColoredPainting/Shaders/final.frag b/ArchitectureColoredPainting/Shaders/final.frag index 574b35b..c9393c8 100644 --- a/ArchitectureColoredPainting/Shaders/final.frag +++ b/ArchitectureColoredPainting/Shaders/final.frag @@ -84,13 +84,13 @@ float Calculate_Avg_Dblockreceiver(vec2 projCoords , int AvgTextureSize) return result/(AvgTextureSize*AvgTextureSize*2*2); } -float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal) +float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer) { // select cascade layer vec4 fragPosViewSpace = view * vec4(fragPosWorldSpace, 1.0); float depthValue = abs(fragPosViewSpace.z); - int layer = -1; + layer = -1; for (int i = 0; i < shadowCascadeCount; ++i) { if (depthValue < shadowCascadePlaneDistances[i]) @@ -225,11 +225,14 @@ void main() //vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0); //float bias = 0.08 * max(0.05 * (1.0 - dot(N, L)), 0.005); - float shadow = ShadowCalculation(WorldPos, N); + int debugLayer; + float shadow = ShadowCalculation(WorldPos, N, debugLayer); //vec3 color = ambient + Lo; //vec3 color = indirect*1; vec3 color = ambient + (1.0 - shadow) * Lo; + //color*=mix(mix(vec3(1,0,0), vec3(0,1,0), float(debugLayer)/shadowCascadeCount/0.5), + //mix(vec3(0,1,0), vec3(0,0,1), float(debugLayer)/(shadowCascadeCount)/0.5-1), float(debugLayer)/(shadowCascadeCount)); //vec3 color = (1.0 - shadow) * Lo; //vec3 color = (1.0 - shadow) * Lo + indirect*10; color = color / (color + vec3(1.0));