Make code less dumb, save 7 fps

This commit is contained in:
FakeShemp
2016-02-27 18:04:33 +01:00
parent ecab5de056
commit 8647267cad
5 changed files with 113 additions and 108 deletions
+16 -22
View File
@@ -10,10 +10,9 @@
#include "imgui/imgui.h"
#define MAX_SPLITS 4
#define MAP_SIZE 216.f
enum NearFar { Near = 0, Far = 1 };
enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 };
enum NearFar { NEAR = 0, FAR = 1 };
enum LRBT { LEFT = 0, RIGHT = 1, BOTTOM = 2, TOP = 3 };
struct Frustum
{
@@ -30,8 +29,8 @@ struct Frustum
class ShadowPass
{
public:
ShadowPass(IRenderer* renderer);
ShadowPass(IRenderer * renderer, int ShadowResX, int ShadowResY);
~ShadowPass();
void InitializeFrameBuffers();
@@ -39,45 +38,40 @@ public:
void ClearBuffer();
void Draw(RenderScene& scene);
//GLuint DepthMap(int level) const { return m_DepthMap[level]; }
GLuint DepthMap() const { return m_DepthMap; }
std::array<glm::mat4, MAX_SPLITS> LightP() const { return m_LightProjection; }
std::array<glm::mat4, MAX_SPLITS> LightV() const { return m_LightView; }
std::array<float, MAX_SPLITS> FarDistance() const { return { m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; }
int CurrentNrOfSplits() const { return m_CurrentNrOfSplits; }
void SetSplitWeight(float split_weight) { m_SplitWeight = split_weight; };
private:
void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v);
void UpdateSplitDist(std::array<Frustum, MAX_SPLITS>& frusta, float near_distance, float far_distance);
void InitializeCameras(RenderScene & scene);
float FindRadius(Frustum& frustum);
void UpdateSplitDist(std::array<Frustum, MAX_SPLITS>& frusta, float near_distance, float far_distance);
void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir);
void UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v);
void PointsToLightspace(Frustum& frustum, glm::mat4 v);
void RadiusToLightspace(Frustum& frustum, glm::mat4 v);
float FindRadius(Frustum& frustum);
void RadiusToLightspace(Frustum& frustum);
EventBroker* m_EventBroker;
const IRenderer* m_Renderer;
//std::array<GLuint, MAX_SPLITS> m_DepthMap;
//std::array<FrameBuffer, MAX_SPLITS> m_DepthBuffer;
GLuint m_DepthMap;
FrameBuffer m_DepthBuffer;
ShaderProgram* m_ShadowProgram;
std::array<glm::mat4, MAX_SPLITS> m_LightProjection;
std::array<glm::mat4, MAX_SPLITS> m_LightView;
ShaderProgram* m_ShadowProgram;
GLuint m_DepthFBO;
GLfloat m_NearFarPlane[2] = { -34.f, 27.f };
//GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f };
GLuint m_ResolutionSizeWidth = 1024 * 2;
GLuint m_ResolutionSizeHeigth = 1024 * 2;
GLuint m_ResolutionSizeHeight = 1024 * 2;
bool m_ShadowOn = true;
int m_ShadowLevel = 0;
int m_CurrentNrOfSplits = 3;
float m_SplitWeight = 0.7f;
int m_CurrentNrOfSplits = 4;
float m_SplitWeight = 0.91f;
std::array<Frustum, MAX_SPLITS> m_shadowFrusta;
};
+55 -32
View File
@@ -1,7 +1,6 @@
#version 430
#define MAX_SPLITS 4
#define SPLIT_WEIGHT 0.7
uniform mat4 M;
uniform mat4 V;
@@ -139,6 +138,7 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu
return vec4(TBN * normalize(NormalMap), 0.0);
}
// Returns a "random" value.
float Random(vec3 seed, int i)
{
vec4 seed4 = vec4(seed, i);
@@ -162,7 +162,7 @@ float PoissonShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_co
for (int i = 0; i < taps; i++)
{
loop = i;
vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * SPLIT_WEIGHT * (1.0 + layer_index));
vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * (1.0 + layer_index));
shadowMapDepth += multiplier * texture(depth_texture_array, vec4(newProjCoords.xy, layer_index, newProjCoords.z));
}
@@ -179,7 +179,7 @@ float PoissonDotShadow(sampler2DArrayShadow depth_texture_array, vec3 projection
for (int i = 0; i < taps; i++)
{
loop = int(16.0 * Random(gl_FragCoord.xyy, i)) % 16;
vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * SPLIT_WEIGHT * (1.0 + layer_index));
vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * (1.0 + layer_index));
shadowMapDepth += multiplier * texture(depth_texture_array, vec4(newProjCoords.xy, layer_index, newProjCoords.z));
}
@@ -196,7 +196,7 @@ float SoftwarePCF(sampler2DArrayShadow depth_texture_array, vec3 projection_coor
{
for(int y = -1; y <= 1; y++)
{
shadow += texture(depth_texture_array, vec4(projection_coords.xy + vec2(x, y) * texelSize.xy, layer_index, projection_coords.z));
shadow += texture(depth_texture_array, vec4(projection_coords.xy + vec2(x, y) * texelSize.xy / (1.0 + layer_index), layer_index, projection_coords.z));
}
}
@@ -206,40 +206,56 @@ float SoftwarePCF(sampler2DArrayShadow depth_texture_array, vec3 projection_coor
float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler2DArrayShadow depth_texture_array, int layer_index)
{
float shadowMapDepth;
float bias;
float bias = 0.005;
// Various bias methods.
//bias = 0.005;
//bias = max(0.05 * (1.0 - dot(normal, light_dir)), 0.005);
bias = 0.005 * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0)));
bias = max(0.05 * (1.0 - dot(normal, light_dir)), bias);
//bias = bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0)));
// Calculate coordinates in projection space.
// Calculate coordinates in projection space
vec3 projCoords = vec3(light_space_pos.xy, light_space_pos.z + bias) / light_space_pos.w;
projCoords = projCoords * 0.5 + 0.5;
// Various methods for shadow calculation in fastest to slowest order.
shadowMapDepth = PCFShadow(depth_texture_array, projCoords, layer_index);
//shadowMapDepth = PoissonShadow(depth_texture_array, projCoords, layer_index, 4, 1500.0);
//shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 1500.0);
//shadowMapDepth = PoissonShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS - 1]);
//shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS]);
//shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias);
float shadow = 1.0 - shadowMapDepth;
return shadow;
return 1.0 - shadowMapDepth;
}
int getShadowIndex(float far_distance[MAX_SPLITS])
int getShadowIndex(float far_distance[1])
{
return 0;
}
int getShadowIndex(float far_distance[2])
{
float depth = gl_FragCoord.z / gl_FragCoord.w;
int index = 1;
if ( depth < far_distance[0] )
{
index = 0;
}
return index;
}
int getShadowIndex(float far_distance[3])
{
float depth = gl_FragCoord.z / gl_FragCoord.w;
int index = 2;
if( depth < far_distance[0] )
if ( depth < far_distance[0] )
{
index = 0;
}
else if( depth < far_distance[1] && depth > far_distance[0] )
else if ( depth < far_distance[1] && depth > far_distance[0] )
{
index = 1;
}
@@ -247,6 +263,27 @@ int getShadowIndex(float far_distance[MAX_SPLITS])
return index;
}
int getShadowIndex(float far_distance[4])
{
float depth = gl_FragCoord.z / gl_FragCoord.w;
int index = 3;
if ( depth < far_distance[0] )
{
index = 0;
}
else if ( depth < far_distance[1] && depth > far_distance[0] )
{
index = 1;
}
else if ( depth < far_distance[2] && depth > far_distance[1] )
{
index = 2;
}
return index;
}
void main()
{
vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate);
@@ -282,9 +319,7 @@ void main()
light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff);
} else if (light.Type == 2) { //Directional
int DepthMapIndex = getShadowIndex(FarDistance);
light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap, DepthMapIndex);
}
@@ -298,19 +333,7 @@ void main()
//LightResult getInformation;
vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed);
color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel));
//color_result = (totalLighting.Diffuse + (1.0 - shadowFactor) * (getInformation.Diffuse + (getInformation.Specular * specularTexel))) * color_result;
//vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color;
color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel));
float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0;
+1 -5
View File
@@ -47,11 +47,8 @@ void main()
+ BoneWeights[2] * Bones[int(BoneIndices[2])]
+ BoneWeights[3] * Bones[int(BoneIndices[3])];
}
//vec4 lightPos = LightP * LightV * M * vec4(Position, 1.0); // N
gl_Position = P*V*M*boneTransform * vec4(Position, 1.0);
//gl_Position = lightPos; // N
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
Output.TextureCoordinate = TextureCoords;
@@ -61,7 +58,6 @@ void main()
Output.ExplosionColor = vec4(1.0);
Output.ExplosionPercentageElapsed = 0.0;
//Output.PositionLightSpace = lightPos; // N
for(int i = 0; i < MAX_SPLITS; i++)
{
Output.PositionLightSpace[i] = LightP[i] * LightV[i] * M * vec4(Position, 1.0);
+1 -1
View File
@@ -18,7 +18,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
m_ActualCamera = m_EditorCamera;
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform");
auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera");
(double&)cCamera["FarClip"] = 60.0;
(double&)cCamera["FarClip"] = 300.0;
m_EditorCameraInputController = new EditorCameraInputController<EditorSystem>(m_EventBroker, -1);
+40 -48
View File
@@ -1,6 +1,16 @@
#include "Rendering/ShadowPass.h"
ShadowPass::ShadowPass(IRenderer * renderer, int shadow_res_x, int shadow_res_y)
{
m_Renderer = renderer;
m_ResolutionSizeWidth = shadow_res_x;
m_ResolutionSizeHeight = shadow_res_y;
InitializeFrameBuffers();
InitializeShaderPrograms();
}
ShadowPass::ShadowPass(IRenderer * renderer)
{
m_Renderer = renderer;
@@ -41,8 +51,28 @@ void ShadowPass::UpdateSplitDist(std::array<Frustum, MAX_SPLITS>& frusta, float
frusta[m_CurrentNrOfSplits - 1].FarClip = far_distance;
}
void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v)
{
std::array<glm::vec4, 8> CornerPoint = {
glm::vec4(-1.f, -1.f, -1.f, 1.f),
glm::vec4(-1.f, 1.f, -1.f, 1.f),
glm::vec4(1.f, 1.f, -1.f, 1.f),
glm::vec4(1.f, -1.f, -1.f, 1.f),
glm::vec4(-1.f, -1.f, 1.f, 1.f),
glm::vec4(-1.f, 1.f, 1.f, 1.f),
glm::vec4(1.f, 1.f, 1.f, 1.f),
glm::vec4(1.f, -1.f, 1.f, 1.f)
};
for (int i = 0; i < 8; i++) {
glm::vec4 NDC = glm::inverse(p) * CornerPoint[i];
NDC = NDC / NDC.w;
frustum.CornerPoint[i] = glm::vec3(glm::inverse(v) * NDC);
}
}
// Compute the 8 corner points of the current view frustum in world space
void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v)
void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir)
{
glm::vec3 up = glm::vec3(0.f, 1.f, 0.f);
glm::vec3 right = glm::normalize(glm::cross(view_dir, up));
@@ -68,25 +98,6 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position
frustum.CornerPoint[5] = far_center + up * far_height - right * far_width;
frustum.CornerPoint[6] = far_center + up * far_height + right * far_width;
frustum.CornerPoint[7] = far_center - up * far_height + right * far_width;
// Alternative way.
//std::array<glm::vec4, 8> CornerPoint = {
// glm::vec4(-1.f, -1.f, -1.f, 1.f),
// glm::vec4(-1.f, 1.f, -1.f, 1.f),
// glm::vec4(1.f, 1.f, -1.f, 1.f),
// glm::vec4(1.f, -1.f, -1.f, 1.f),
// glm::vec4(-1.f, -1.f, 1.f, 1.f),
// glm::vec4(-1.f, 1.f, 1.f, 1.f),
// glm::vec4(1.f, 1.f, 1.f, 1.f),
// glm::vec4(1.f, -1.f, 1.f, 1.f) };
//std::array<glm::vec3, 8> FinalPoints;
//for (int i = 0; i < 8; i++) {
// glm::vec4 NDC = glm::inverse(p) * CornerPoint[i];
// NDC = NDC / NDC.w;
// FinalPoints[i] = glm::vec3(glm::inverse(v) * NDC);
//}
}
float ShadowPass::FindRadius(Frustum& frustum)
@@ -106,18 +117,13 @@ float ShadowPass::FindRadius(Frustum& frustum)
void ShadowPass::InitializeFrameBuffers()
{
GLERROR("depthMap failed PRE");
// Depth texture
glGenTextures(1, &m_DepthMap);
GLERROR("depthMap failed1");
glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap);
GLERROR("depthMap failed2");
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits);
GLERROR("depthMap failed3");
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
GLERROR("depthMap failed4");
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -126,11 +132,9 @@ void ShadowPass::InitializeFrameBuffers()
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
GLERROR("depthMap failed5");
m_DepthBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT, m_CurrentNrOfSplits)));
m_DepthBuffer.Generate();
//}
GLERROR("depthMap failed END");
}
@@ -178,7 +182,7 @@ void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v)
frustum.LRBT = { left, right, bottom, top };
}
void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v)
void ShadowPass::RadiusToLightspace(Frustum& frustum)
{
float left = -frustum.Radius;
float right = frustum.Radius;
@@ -190,10 +194,7 @@ void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v)
void ShadowPass::Draw(RenderScene & scene)
{
// ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f);
ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f);
ImGui::Checkbox("EnableShadow", &m_ShadowOn);
//ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1);
InitializeCameras(scene);
UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip());
@@ -201,19 +202,14 @@ void ShadowPass::Draw(RenderScene & scene)
ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle());
m_ShadowProgram->Bind();
GLuint shaderHandle = m_ShadowProgram->GetHandle();
glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight);
for (int i = 0; i < m_CurrentNrOfSplits; i++) {
UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix());
//float test = FindRadius(m_shadFrusta[i]);
GLuint shaderHandle = m_ShadowProgram->GetHandle();
UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward());
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i);
glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth);
//state->Disable(GL_CULL_FACE);
for (auto &job : scene.DirectionalLightJobs) {
auto directionalLightJob = std::dynamic_pointer_cast<DirectionalLightJob>(job);
@@ -221,7 +217,7 @@ void ShadowPass::Draw(RenderScene & scene)
m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f));
PointsToLightspace(m_shadowFrusta[i], m_LightView[i]);
m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[Left], m_shadowFrusta[i].LRBT[Right], m_shadowFrusta[i].LRBT[Bottom], m_shadowFrusta[i].LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]);
m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[LEFT], m_shadowFrusta[i].LRBT[RIGHT], m_shadowFrusta[i].LRBT[BOTTOM], m_shadowFrusta[i].LRBT[TOP], m_NearFarPlane[NEAR], m_NearFarPlane[FAR]);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i]));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i]));
@@ -240,14 +236,10 @@ void ShadowPass::Draw(RenderScene & scene)
GLERROR("Shadow Draw ERROR");
}
}
}
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
m_ShadowProgram->Unbind();
}
m_ShadowProgram->Unbind();
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
m_DepthBuffer.Unbind();
delete state;
}