Drawing of light framebuffers kind of works

simple_math_single_header
Martin Felis 2018-03-12 21:48:26 +01:00
parent 0810224356
commit ef4479ba71
6 changed files with 88 additions and 43 deletions

View File

@ -13,7 +13,7 @@ void main() {
float z = texture(uDepthTexture, ioUV).r; float z = texture(uDepthTexture, ioUV).r;
float c; float c;
if (uIsOrthographic == 1.0) { if (uIsOrthographic == 1.0) {
c = (z - uNear) / (uFar - uNear); c = z;
} else { } else {
c = (2.0 * uNear) / (uFar + uNear - z * (uFar - uNear)); c = (2.0 * uNear) / (uFar + uNear - z * (uFar - uNear));
} }

View File

@ -1,6 +1,7 @@
#version 330 core #version 330 core
in vec3 inVertex; in vec3 inVertex;
uniform mat4 uModelViewProj; uniform mat4 uModelViewProj;
uniform float uTime; uniform float uTime;

View File

@ -13,6 +13,7 @@ struct Renderer;
struct RendererSettings { struct RendererSettings {
bool DrawDepth = false; bool DrawDepth = false;
bool DrawLightDepth = false;
}; };
static RendererSettings sRendererSettings; static RendererSettings sRendererSettings;
@ -78,6 +79,7 @@ static void module_serialize (
struct module_state *state, struct module_state *state,
Serializer* serializer) { Serializer* serializer) {
SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth); SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth);
SerializeBool(*serializer, "protot.RenderModule.DrawLightDepth", sRendererSettings.DrawLightDepth);
SerializeBool(*serializer, "protot.RenderModule.Camera.mIsOrthographic", gRenderer->mCamera.mIsOrthographic); SerializeBool(*serializer, "protot.RenderModule.Camera.mIsOrthographic", gRenderer->mCamera.mIsOrthographic);
SerializeFloat(*serializer, "protot.RenderModule.Camera.mFov", gRenderer->mCamera.mFov); SerializeFloat(*serializer, "protot.RenderModule.Camera.mFov", gRenderer->mCamera.mFov);
SerializeVec3(*serializer, "protot.RenderModule.Camera.mEye", gRenderer->mCamera.mEye); SerializeVec3(*serializer, "protot.RenderModule.Camera.mEye", gRenderer->mCamera.mEye);
@ -86,6 +88,8 @@ static void module_serialize (
SerializeFloat(*serializer, "protot.RenderModule.Camera.mNear", gRenderer->mCamera.mNear); SerializeFloat(*serializer, "protot.RenderModule.Camera.mNear", gRenderer->mCamera.mNear);
SerializeFloat(*serializer, "protot.RenderModule.Camera.mFar", gRenderer->mCamera.mFar); SerializeFloat(*serializer, "protot.RenderModule.Camera.mFar", gRenderer->mCamera.mFar);
SerializeVec3(*serializer, "protot.RenderModule.mLight.mDirection", gRenderer->mLight.mDirection); SerializeVec3(*serializer, "protot.RenderModule.mLight.mDirection", gRenderer->mLight.mDirection);
SerializeFloat(*serializer, "protot.RenderModule.mLight.mNear", gRenderer->mLight.mNear);
SerializeFloat(*serializer, "protot.RenderModule.mLight.mFar", gRenderer->mLight.mFar);
// SerializeBool (*serializer, "protot.RenderModule.draw_floor", gRenderer->drawFloor); // SerializeBool (*serializer, "protot.RenderModule.draw_floor", gRenderer->drawFloor);
// SerializeBool (*serializer, "protot.RenderModule.draw_skybox", gRenderer->drawSkybox); // SerializeBool (*serializer, "protot.RenderModule.draw_skybox", gRenderer->drawSkybox);
@ -167,16 +171,21 @@ void Light::Initialize() {
RenderTarget::EnableColor RenderTarget::EnableColor
| RenderTarget::EnableDepthTexture | RenderTarget::EnableDepthTexture
| RenderTarget::EnableLinearizedDepthTexture); | RenderTarget::EnableLinearizedDepthTexture);
glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapTarget.mFrameBufferId);
gLog("Framebuffer of light has id: %d", mShadowMapTarget.mFrameBufferId);
gLog("Initializing light done");
} }
void Light::UpdateMatrices() { void Light::UpdateMatrices() {
mLightProjection = Ortho (-mBBoxSize * 0.5f, mBBoxSize * 0.5f, -mBBoxSize * 0.5f, mBBoxSize * 0.5f, mNear, mFar); mCamera.mIsOrthographic = true;
mLightView = LookAt(mDirection * mBBoxSize * 0.5f, Vector3f (0.0f, 0.0f, 0.0f), Vector3f (0.0f, 1.0f, 0.0f)); mCamera.mWidth = mShadowMapSize;
mLightSpaceMatrix = mLightProjection * mLightView; mCamera.mHeight = mShadowMapSize;
mCamera.mNear = mNear;
mCamera.mFar = mFar;
mCamera.mEye = mDirection * mBBoxSize * 0.5;
mCamera.mPoi = mCamera.mEye - mDirection;
mCamera.UpdateMatrices();
mLightSpaceMatrix = mCamera.mProjectionMatrix * mCamera.mViewMatrix;
} }
// //
@ -331,9 +340,14 @@ void Renderer::Initialize(int width, int height) {
mRenderTarget.mQuadVertexArray = mRenderQuadVertexArrayId; mRenderTarget.mQuadVertexArray = mRenderQuadVertexArrayId;
mRenderTarget.mQuadVertexBuffer = mRenderQuadVertexBufferId; mRenderTarget.mQuadVertexBuffer = mRenderQuadVertexBufferId;
mRenderTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth; mRenderTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth;
mRenderTarget.mLinearizeDepthProgram.RegisterFileModification();
// Light // Light
mLight.Initialize(); mLight.Initialize();
mLight.mShadowMapTarget.mQuadVertexArray = mRenderQuadVertexArrayId;
mLight.mShadowMapTarget.mQuadVertexBuffer = mRenderQuadVertexBufferId;
mLight.mShadowMapTarget.mLinearizeDepthProgram = mRenderQuadProgramDepth;
mLight.mShadowMapTarget.mLinearizeDepthProgram.RegisterFileModification();
} }
void Renderer::Shutdown() { void Renderer::Shutdown() {
@ -345,19 +359,24 @@ void Renderer::RenderGl() {
mSceneAreaHeight = mSceneAreaHeight < 1 ? 1 : mSceneAreaHeight; mSceneAreaHeight = mSceneAreaHeight < 1 ? 1 : mSceneAreaHeight;
if (mSceneAreaWidth != mRenderTarget.mWidth || mSceneAreaHeight != mRenderTarget.mHeight) { if (mSceneAreaWidth != mRenderTarget.mWidth || mSceneAreaHeight != mRenderTarget.mHeight) {
mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight); mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight);
}
if (mCamera.mWidth != mSceneAreaWidth
|| mCamera.mHeight != mSceneAreaHeight) {
mCamera.mWidth = mSceneAreaWidth; mCamera.mWidth = mSceneAreaWidth;
mCamera.mHeight = mSceneAreaHeight; mCamera.mHeight = mSceneAreaHeight;
} }
// Shadow Map // Shadow Map
glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize);
mLight.mShadowMapTarget.Bind(); mLight.mShadowMapTarget.Bind();
glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize);
mLight.UpdateMatrices();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glUseProgram(mLight.mShadowMapProgram.mProgramId); glUseProgram(mLight.mShadowMapProgram.mProgramId);
RenderScene(mLight.mShadowMapProgram); RenderScene(mLight.mShadowMapProgram, mLight.mCamera);
mLight.mShadowMapTarget.RenderToLinearizedDepth(mLight.mCamera.mNear, mLight.mCamera.mFar, mLight.mCamera.mIsOrthographic);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
// TODO: render linearized depth for the light
// mLight.mShadowMapTarget.RenderToLinearizedDepth(mCamera);
// Regular rendering // Regular rendering
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
@ -375,7 +394,7 @@ void Renderer::RenderGl() {
* mCamera.mProjectionMatrix; * mCamera.mProjectionMatrix;
// enable the render target // enable the render target
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget.mFrameBufferId); mRenderTarget.Bind();
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); glDrawBuffers(1, DrawBuffers);
@ -416,29 +435,31 @@ void Renderer::RenderGl() {
glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture); glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
RenderScene(mDefaultProgram); RenderScene(mDefaultProgram, mCamera);
if (mSettings->DrawDepth) { if (mSettings->DrawDepth) {
mRenderTarget.RenderToLinearizedDepth(mCamera); mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic);
} }
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void Renderer::RenderScene(RenderProgram &program) { void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
glUseProgram(program.mProgramId);
Matrix44f model_matrix = TranslateMat44(3.0f, 0.0f, 1.0f); Matrix44f model_matrix = TranslateMat44(3.0f, 0.0f, 1.0f);
Matrix33f normal_matrix = model_matrix.block<3,3>(0,0).transpose(); Matrix33f normal_matrix = model_matrix.block<3,3>(0,0).transpose();
normal_matrix = normal_matrix.inverse(); normal_matrix = normal_matrix.inverse();
program.SetMat44("uModelMatrix", model_matrix); program.SetMat44("uModelMatrix", model_matrix);
program.SetMat44("uViewMatrix", mCamera.mViewMatrix); program.SetMat44("uViewMatrix", camera.mViewMatrix);
program.SetMat44("uProjectionMatrix", mCamera.mProjectionMatrix); program.SetMat44("uProjectionMatrix", camera.mProjectionMatrix);
program.SetMat33("uNormalMatrix", normal_matrix); program.SetMat33("uNormalMatrix", normal_matrix);
program.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f)); program.SetVec4("uColor", Vector4f (1.0f, 0.0f, 0.0f, 1.0f));
program.SetVec3("uLightDirection", mLight.mDirection); program.SetVec3("uLightDirection", mLight.mDirection);
program.SetVec3("uViewPosition", mCamera.mEye); program.SetVec3("uViewPosition", camera.mEye);
gVertexArray.Bind(); gVertexArray.Bind();
gUnitCubeMesh.Draw(GL_TRIANGLES); gUnitCubeMesh.Draw(GL_TRIANGLES);
} }
@ -468,20 +489,35 @@ void Renderer::RenderGui() {
ImGui::EndDock(); ImGui::EndDock();
if (ImGui::BeginDock("Render Settings")) { if (ImGui::BeginDock("Light Settings")) {
ImGui::Text("Light"); mLight.mCamera.DrawGui();
ImGui::SliderFloat3("Direction", mLight.mDirection.data(), -10.0f, 10.0f); ImGui::SliderFloat3("Direction", mLight.mDirection.data(), -10.0f, 10.0f);
ImVec2 content_avail = ImGui::GetContentRegionAvail(); ImVec2 content_avail = ImGui::GetContentRegionAvail();
ImGui::Image((void*) mLight.mShadowMapTarget.mLinearizedDepthTexture,
ImGui::SliderFloat("Light Near", &mLight.mNear, -10.0f, 10.0f);
ImGui::SliderFloat("Light Far", &mLight.mFar, -10.0f, 50.0f);
ImGui::Checkbox("Draw Light Depth", &mSettings->DrawLightDepth);
void* texture;
if (mSettings->DrawLightDepth) {
texture = (void*) mLight.mShadowMapTarget.mLinearizedDepthTexture;
} else {
texture = (void*) mLight.mShadowMapTarget.mColorTexture;
}
ImGui::Image(texture,
ImVec2(content_avail.x, content_avail.x), ImVec2(content_avail.x, content_avail.x),
ImVec2(0.0f, 1.0f), ImVec2(0.0f, 1.0f),
ImVec2(1.0f, 0.0f) ImVec2(1.0f, 0.0f)
); );
}
ImGui::EndDock();
if (ImGui::BeginDock("Render Settings")) {
ImGui::Text("Camera"); ImGui::Text("Camera");
mCamera.DrawGui(); mCamera.DrawGui();
ImGui::Text("Default Texture"); ImGui::Text("Default Texture");
content_avail = ImGui::GetContentRegionAvail(); ImVec2 content_avail = ImGui::GetContentRegionAvail();
ImGui::Image((void*) mDefaultTexture.mTextureId, ImGui::Image((void*) mDefaultTexture.mTextureId,
ImVec2(content_avail.x, content_avail.x), ImVec2(content_avail.x, content_avail.x),
ImVec2(0.0f, 1.0f), ImVec2(0.0f, 1.0f),

View File

@ -21,6 +21,8 @@ struct Light {
RenderTarget mShadowMapTarget; RenderTarget mShadowMapTarget;
RenderProgram mShadowMapProgram; RenderProgram mShadowMapProgram;
Camera mCamera;
float mShadowMapBias; float mShadowMapBias;
uint16_t mShadowMapSize; uint16_t mShadowMapSize;
@ -28,8 +30,6 @@ struct Light {
float mFar; float mFar;
float mBBoxSize; float mBBoxSize;
Matrix44f mLightProjection;
Matrix44f mLightView;
Matrix44f mLightSpaceMatrix; Matrix44f mLightSpaceMatrix;
Light() : Light() :
@ -37,11 +37,9 @@ struct Light {
mDirection (Vector3f(-1.f, -1.f, -1.f)), mDirection (Vector3f(-1.f, -1.f, -1.f)),
mShadowMapBias (0.004f), mShadowMapBias (0.004f),
mShadowMapSize (1024), mShadowMapSize (1024),
mNear (0.1f), mNear (0.01f),
mFar (100.f), mFar (6.f),
mBBoxSize (10.f), mBBoxSize (5.f),
mLightProjection(Matrix44f::Identity()),
mLightView(Matrix44f::Identity()),
mLightSpaceMatrix(Matrix44f::Identity()) mLightSpaceMatrix(Matrix44f::Identity())
{ {
} }
@ -97,6 +95,6 @@ struct Renderer {
void Initialize(int width, int height); void Initialize(int width, int height);
void Shutdown(); void Shutdown();
void RenderGl(); void RenderGl();
void RenderScene(RenderProgram &program); void RenderScene(RenderProgram &program, const Camera& camera);
void RenderGui(); void RenderGui();
}; };

View File

@ -26,7 +26,10 @@ void Camera::UpdateMatrices() {
mViewMatrix = LookAt(mEye, mPoi, mUp); mViewMatrix = LookAt(mEye, mPoi, mUp);
if (mIsOrthographic) { if (mIsOrthographic) {
mProjectionMatrix = Ortho(-1.0f, 1.0f, -1.0f, 1.0f, mNear, mFar); float width = mWidth * 0.5f * (mFar - mNear * 0.5f) * 0.001f;
float height = width * mHeight / mWidth;
mProjectionMatrix = Ortho(-width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, mNear, mFar);
} else { } else {
mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar); mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar);
} }
@ -280,6 +283,8 @@ void RenderTarget::Initialize(int width, int height, int flags) {
void RenderTarget::Bind() { void RenderTarget::Bind() {
assert(glIsFramebuffer(mFrameBufferId)); assert(glIsFramebuffer(mFrameBufferId));
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers);
} }
void RenderTarget::Cleanup() { void RenderTarget::Cleanup() {
@ -362,6 +367,8 @@ void RenderTarget::Resize(int width, int height) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mLinearizedDepthTexture, 0);
} }
} else if (mFlags & EnableDepth) { } else if (mFlags & EnableDepth) {
assert((mFlags & EnableDepthTexture) == false); assert((mFlags & EnableDepthTexture) == false);
@ -387,15 +394,16 @@ void RenderTarget::Resize(int width, int height) {
assert(result == GL_FRAMEBUFFER_COMPLETE); assert(result == GL_FRAMEBUFFER_COMPLETE);
} }
void RenderTarget::RenderToLinearizedDepth(const Camera& camera) { void RenderTarget::RenderToLinearizedDepth(const float& near, const float& far, bool is_orthographic) {
assert(mFlags & EnableLinearizedDepthTexture); assert(mFlags & EnableLinearizedDepthTexture);
assert(mLinearizedDepthTexture != -1); assert(mLinearizedDepthTexture != -1);
assert(mQuadVertexArray != -1); assert(mQuadVertexArray != -1);
assert(mQuadVertexBuffer != -1); assert(mQuadVertexBuffer != -1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mLinearizedDepthTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum draw_attachment_1[] = { GL_COLOR_ATTACHMENT1 };
glDrawBuffers(1, draw_attachment_1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@ -407,9 +415,9 @@ void RenderTarget::RenderToLinearizedDepth(const Camera& camera) {
// render depth texture // render depth texture
glUseProgram(mLinearizeDepthProgram.mProgramId); glUseProgram(mLinearizeDepthProgram.mProgramId);
mLinearizeDepthProgram.SetMat44("uModelViewProj", model_view_projection); mLinearizeDepthProgram.SetMat44("uModelViewProj", model_view_projection);
mLinearizeDepthProgram.SetFloat("uNear", camera.mNear); mLinearizeDepthProgram.SetFloat("uNear", near);
mLinearizeDepthProgram.SetFloat("uFar", camera.mFar); mLinearizeDepthProgram.SetFloat("uFar", far);
mLinearizeDepthProgram.SetFloat("uIsOrthographic", camera.mIsOrthographic ? 1.0f : 0.0f); mLinearizeDepthProgram.SetFloat("uIsOrthographic", is_orthographic ? 1.0f : 0.0f);
mLinearizeDepthProgram.SetInt("uDepthTexture", 0); mLinearizeDepthProgram.SetInt("uDepthTexture", 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -425,8 +433,10 @@ void RenderTarget::RenderToLinearizedDepth(const Camera& camera) {
glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total
if (mFlags & EnableColor) if (mFlags & EnableColor) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture, 0); GLenum draw_attachment_0[] = { GL_COLOR_ATTACHMENT1 };
glDrawBuffers(1, draw_attachment_0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }

View File

@ -152,8 +152,8 @@ struct Camera {
mFar (150.f), mFar (150.f),
mFov (60.f), mFov (60.f),
mIsOrthographic (false), mIsOrthographic (false),
mWidth (-1.f), mWidth (100.0f),
mHeight (-1.f), mHeight (100.0f),
mProjectionMatrix ( mProjectionMatrix (
1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f,
@ -263,7 +263,7 @@ struct RenderTarget {
void Cleanup(); void Cleanup();
void Resize(int width, int height); void Resize(int width, int height);
void RenderToLinearizedDepth(const Camera &camera); void RenderToLinearizedDepth(const float& near, const float& far, bool is_orthographic);
}; };
struct Texture { struct Texture {