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 c;
if (uIsOrthographic == 1.0) {
c = (z - uNear) / (uFar - uNear);
c = z;
} else {
c = (2.0 * uNear) / (uFar + uNear - z * (uFar - uNear));
}

View File

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

View File

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

View File

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

View File

@ -26,7 +26,10 @@ void Camera::UpdateMatrices() {
mViewMatrix = LookAt(mEye, mPoi, mUp);
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 {
mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar);
}
@ -280,6 +283,8 @@ void RenderTarget::Initialize(int width, int height, int flags) {
void RenderTarget::Bind() {
assert(glIsFramebuffer(mFrameBufferId));
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers);
}
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_WRAP_S, 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) {
assert((mFlags & EnableDepthTexture) == false);
@ -387,15 +394,16 @@ void RenderTarget::Resize(int width, int height) {
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(mLinearizedDepthTexture != -1);
assert(mQuadVertexArray != -1);
assert(mQuadVertexBuffer != -1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mLinearizedDepthTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum draw_attachment_1[] = { GL_COLOR_ATTACHMENT1 };
glDrawBuffers(1, draw_attachment_1);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
@ -407,9 +415,9 @@ void RenderTarget::RenderToLinearizedDepth(const Camera& camera) {
// render depth texture
glUseProgram(mLinearizeDepthProgram.mProgramId);
mLinearizeDepthProgram.SetMat44("uModelViewProj", model_view_projection);
mLinearizeDepthProgram.SetFloat("uNear", camera.mNear);
mLinearizeDepthProgram.SetFloat("uFar", camera.mFar);
mLinearizeDepthProgram.SetFloat("uIsOrthographic", camera.mIsOrthographic ? 1.0f : 0.0f);
mLinearizeDepthProgram.SetFloat("uNear", near);
mLinearizeDepthProgram.SetFloat("uFar", far);
mLinearizeDepthProgram.SetFloat("uIsOrthographic", is_orthographic ? 1.0f : 0.0f);
mLinearizeDepthProgram.SetInt("uDepthTexture", 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
if (mFlags & EnableColor)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture, 0);
if (mFlags & EnableColor) {
GLenum draw_attachment_0[] = { GL_COLOR_ATTACHMENT1 };
glDrawBuffers(1, draw_attachment_0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

View File

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