Rendering linearized depth buffer by rendering it to another RGB texture
parent
ea2b5d1e13
commit
9c56d3f061
|
@ -10,27 +10,7 @@ uniform float uFar;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float z = texture(uTexture, ioUV).r;
|
float z = texture(uTexture, ioUV).r;
|
||||||
float c = (2.0 * uNear) / (uFar + uNear - z * (uFar - uNear));
|
float c = (z - uNear) / (uFar - uNear);
|
||||||
// c = 2.0 * uNear * uFar / (uFar + uNear - z * (uFar - uNear));
|
|
||||||
// c = (uNear + (z - uNear) / (uFar - uNear);
|
|
||||||
|
|
||||||
c = (z - uNear) / (uFar - uNear);
|
|
||||||
|
|
||||||
outColor = vec3(c);
|
outColor = vec3(c);
|
||||||
|
|
||||||
if (abs(c + 1) < 0.2)
|
|
||||||
outColor = vec3(1, 0, 0);
|
|
||||||
// if (abs(c - 0.1) < 0.1)
|
|
||||||
// outColor = vec3(0, 0, 1);
|
|
||||||
// if (abs(c - 0.8) < 0.1)
|
|
||||||
// outColor = vec3(1, 0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
// n ---- z ------- f
|
|
||||||
// 0 1
|
|
||||||
//
|
|
||||||
// (n + (z - n)) (f - n)
|
|
||||||
//
|
|
||||||
// (f - n)
|
|
||||||
// outColor = vec3(z);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "RenderModule.h"
|
#include "RenderModule.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "Serializer.h"
|
||||||
|
|
||||||
#include "imgui/imgui.h"
|
#include "imgui/imgui.h"
|
||||||
#include "imgui_dock.h"
|
#include "imgui_dock.h"
|
||||||
|
@ -10,10 +11,16 @@ using namespace SimpleMath::GL;
|
||||||
|
|
||||||
struct Renderer;
|
struct Renderer;
|
||||||
|
|
||||||
|
struct RendererSettings {
|
||||||
|
bool DrawDepth = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
static RendererSettings sRendererSettings;
|
||||||
|
|
||||||
static const GLfloat g_vertex_buffer_data[] = {
|
static const GLfloat g_vertex_buffer_data[] = {
|
||||||
-0.9f, -0.9f, 0.0f,
|
-0.9f, -0.9f, 0.0f,
|
||||||
0.9f, -0.9f, 0.0f,
|
0.9f, -0.9f, 0.0f,
|
||||||
0.0f, 0.9f, 1.0f
|
0.0f, 0.9f, 4.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
static const GLfloat g_quad_vertex_buffer_data[] = {
|
static const GLfloat g_quad_vertex_buffer_data[] = {
|
||||||
|
@ -47,6 +54,7 @@ template <typename Serializer>
|
||||||
static void module_serialize (
|
static void module_serialize (
|
||||||
struct module_state *state,
|
struct module_state *state,
|
||||||
Serializer* serializer) {
|
Serializer* serializer) {
|
||||||
|
SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth);
|
||||||
// // get the state from the serializer
|
// // get the state from the serializer
|
||||||
// Camera* camera = &gRenderer->cameras[gRenderer->activeCameraIndex];
|
// Camera* camera = &gRenderer->cameras[gRenderer->activeCameraIndex];
|
||||||
// assert (camera != nullptr);
|
// assert (camera != nullptr);
|
||||||
|
@ -74,6 +82,7 @@ static void module_reload(struct module_state *state, void *read_serializer) {
|
||||||
gLog ("Renderer initialize");
|
gLog ("Renderer initialize");
|
||||||
assert (state != nullptr);
|
assert (state != nullptr);
|
||||||
state->renderer->Initialize(100, 100);
|
state->renderer->Initialize(100, 100);
|
||||||
|
state->renderer->mSettings = &sRendererSettings;
|
||||||
|
|
||||||
gRenderer = state->renderer;
|
gRenderer = state->renderer;
|
||||||
|
|
||||||
|
@ -147,7 +156,10 @@ glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data
|
||||||
muDefaultColor = mDefaultProgram.GetUniformLocation("uColor");
|
muDefaultColor = mDefaultProgram.GetUniformLocation("uColor");
|
||||||
|
|
||||||
// Render Target
|
// Render Target
|
||||||
mRenderTarget = RenderTarget (width, height, RenderTarget::EnableColor | RenderTarget::EnableDepthTexture);
|
mRenderTarget = RenderTarget (width, height,
|
||||||
|
RenderTarget::EnableColor
|
||||||
|
| RenderTarget::EnableDepthTexture
|
||||||
|
| RenderTarget::EnableLinearizedDepthTexture);
|
||||||
|
|
||||||
// Render Target Quad
|
// Render Target Quad
|
||||||
glGenVertexArrays(1, &mRenderQuadVertexArrayId);
|
glGenVertexArrays(1, &mRenderQuadVertexArrayId);
|
||||||
|
@ -186,11 +198,11 @@ void Renderer::RenderGl() {
|
||||||
if (width != mWidth || height != mHeight)
|
if (width != mWidth || height != mHeight)
|
||||||
Resize(width, height);
|
Resize(width, height);
|
||||||
|
|
||||||
mCamera.eye = Vector3f (0.0f, 0.0f, 1.0f);
|
mCamera.eye = Vector3f (0.0f, 0.0f, 4.0f);
|
||||||
mCamera.poi = Vector3f (0.0f, 0.0f, 0.0f);
|
mCamera.poi = Vector3f (0.0f, 0.0f, 0.0f);
|
||||||
mCamera.up = Vector3f (0.0f, 1.0f, 0.0f);
|
mCamera.up = Vector3f (0.0f, 1.0f, 0.0f);
|
||||||
mCamera.near = 0.0f;
|
mCamera.near = 0.0f;
|
||||||
mCamera.far = 1.0f;
|
mCamera.far = 4.0f;
|
||||||
mCamera.orthographic = true;
|
mCamera.orthographic = true;
|
||||||
|
|
||||||
mCamera.UpdateMatrices();
|
mCamera.UpdateMatrices();
|
||||||
|
@ -230,56 +242,26 @@ void Renderer::RenderGl() {
|
||||||
);
|
);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3); // starting from vertex 0; 3 vertices total
|
glDrawArrays(GL_TRIANGLES, 0, 3); // starting from vertex 0; 3 vertices total
|
||||||
glDisableVertexAttribArray(0);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::RenderGui() {
|
if (mSettings->DrawDepth) {
|
||||||
bool render_color = true;
|
mRenderTarget.RenderToLinearizedDepth(true);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
GLuint texture;
|
glDisable(GL_DEPTH_TEST);
|
||||||
if (render_color) {
|
|
||||||
texture = mRenderTarget.mColorTexture;
|
|
||||||
} else {
|
|
||||||
texture = mRenderTarget.mDepthTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginDock("Scene")) {
|
|
||||||
ImGui::Text("Scene");
|
|
||||||
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
|
|
||||||
ImGui::Image((void*) texture,
|
|
||||||
content_avail,
|
|
||||||
ImVec2(0.0f, 1.0f),
|
|
||||||
ImVec2(1.0f, 0.0f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ImGui::EndDock();
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
Matrix44f model_view_projection = Matrix44f::Identity();
|
Matrix44f model_view_projection = Matrix44f::Identity();
|
||||||
|
|
||||||
if (render_color) {
|
|
||||||
// Render the full screen quad
|
|
||||||
glUseProgram(mRenderQuadProgramColor.mProgramId);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture);
|
|
||||||
glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data());
|
|
||||||
glUniform1i(muRenderQuadTexture, 0);
|
|
||||||
glUniform1f(muRenderQuadTime, (float)(glfwGetTime() * 10.0f));
|
|
||||||
} else {
|
|
||||||
// render depth texture
|
// render depth texture
|
||||||
glUseProgram(mRenderQuadProgramDepth.mProgramId);
|
glUseProgram(mRenderQuadProgramDepth.mProgramId);
|
||||||
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
|
|
||||||
glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data());
|
glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
|
||||||
glUniform1i(muRenderQuadTexture, 0);
|
glUniform1i(muRenderQuadTexture, 0);
|
||||||
|
|
||||||
|
// TODO: adjust for perspective
|
||||||
glUniform1f(muRenderQuadDepthNear, mCamera.near);
|
glUniform1f(muRenderQuadDepthNear, mCamera.near);
|
||||||
glUniform1f(muRenderQuadDepthFar, mCamera.far);
|
// TODO: why do I have to divide by depth range?
|
||||||
}
|
glUniform1f(muRenderQuadDepthFar, mCamera.far / (mCamera.far - mCamera.near));
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId);
|
glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId);
|
||||||
|
@ -293,7 +275,37 @@ void Renderer::RenderGui() {
|
||||||
);
|
);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total
|
glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total
|
||||||
|
|
||||||
|
mRenderTarget.RenderToLinearizedDepth(false);
|
||||||
|
}
|
||||||
|
|
||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderGui() {
|
||||||
|
if (ImGui::BeginDock("Scene")) {
|
||||||
|
ImGui::Checkbox("Draw Depth", &mSettings->DrawDepth);
|
||||||
|
|
||||||
|
GLuint texture;
|
||||||
|
if (mSettings->DrawDepth) {
|
||||||
|
texture = mRenderTarget.mLinearizedDepthTexture;
|
||||||
|
} else {
|
||||||
|
texture = mRenderTarget.mColorTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Scene");
|
||||||
|
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
|
// mRenderTarget.Resize(content_avail.x, content_avail.y);
|
||||||
|
|
||||||
|
ImGui::Image((void*) texture,
|
||||||
|
content_avail,
|
||||||
|
ImVec2(0.0f, 1.0f),
|
||||||
|
ImVec2(1.0f, 0.0f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ImGui::EndDock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Resize (int width, int height) {
|
void Renderer::Resize (int width, int height) {
|
||||||
|
|
|
@ -106,7 +106,11 @@ struct Mesh {
|
||||||
GLuint mVertexBuffer = -1;
|
GLuint mVertexBuffer = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RendererSettings;
|
||||||
|
|
||||||
struct Renderer {
|
struct Renderer {
|
||||||
|
RendererSettings* mSettings = nullptr;
|
||||||
|
|
||||||
bool mInitialized = false;
|
bool mInitialized = false;
|
||||||
uint32_t mWidth = 1;
|
uint32_t mWidth = 1;
|
||||||
uint32_t mHeight = 1;
|
uint32_t mHeight = 1;
|
||||||
|
|
|
@ -170,6 +170,11 @@ void RenderTarget::Cleanup() {
|
||||||
glDeleteRenderbuffers(1, &mDepthBuffer);
|
glDeleteRenderbuffers(1, &mDepthBuffer);
|
||||||
mDepthBuffer = -1;
|
mDepthBuffer = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mLinearizedDepthTexture != -1) {
|
||||||
|
glDeleteTextures(1, &mLinearizedDepthTexture);
|
||||||
|
mLinearizedDepthTexture = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTarget::Resize(int width, int height) {
|
void RenderTarget::Resize(int width, int height) {
|
||||||
|
@ -210,6 +215,17 @@ void RenderTarget::Resize(int width, int height) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTexture, 0);
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTexture, 0);
|
||||||
|
|
||||||
|
if (mFlags & EnableLinearizedDepthTexture) {
|
||||||
|
glGenTextures(1, &mLinearizedDepthTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mLinearizedDepthTexture);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mWidth, mHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_T, GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
} else if (mFlags & EnableDepth) {
|
} else if (mFlags & EnableDepth) {
|
||||||
assert((mFlags & EnableDepthTexture) == false);
|
assert((mFlags & EnableDepthTexture) == false);
|
||||||
glGenRenderbuffers(1, &mDepthBuffer);
|
glGenRenderbuffers(1, &mDepthBuffer);
|
||||||
|
@ -219,4 +235,11 @@ void RenderTarget::Resize(int width, int height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderTarget::RenderToLinearizedDepth(bool render_to_depth) {
|
||||||
|
if (render_to_depth) {
|
||||||
|
assert(mFlags & EnableLinearizedDepthTexture);
|
||||||
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mLinearizedDepthTexture, 0);
|
||||||
|
} else {
|
||||||
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -146,6 +146,9 @@ struct RenderProgram {
|
||||||
bool Load();
|
bool Load();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RenderSettings;
|
||||||
|
|
||||||
|
|
||||||
struct RenderTarget {
|
struct RenderTarget {
|
||||||
int mWidth = 0;
|
int mWidth = 0;
|
||||||
int mHeight = 0;
|
int mHeight = 0;
|
||||||
|
@ -153,11 +156,13 @@ struct RenderTarget {
|
||||||
GLuint mColorTexture = -1;
|
GLuint mColorTexture = -1;
|
||||||
GLuint mDepthBuffer = -1;
|
GLuint mDepthBuffer = -1;
|
||||||
GLuint mDepthTexture = -1;
|
GLuint mDepthTexture = -1;
|
||||||
|
GLuint mLinearizedDepthTexture = -1;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EnableColor = 1,
|
EnableColor = 1,
|
||||||
EnableDepth = 2,
|
EnableDepth = 2,
|
||||||
EnableDepthTexture = 4
|
EnableDepthTexture = 4,
|
||||||
|
EnableLinearizedDepthTexture = 8
|
||||||
} Flags;
|
} Flags;
|
||||||
|
|
||||||
int mFlags = 0;
|
int mFlags = 0;
|
||||||
|
@ -168,6 +173,7 @@ struct RenderTarget {
|
||||||
|
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
void Resize(int width, int height);
|
void Resize(int width, int height);
|
||||||
|
void RenderToLinearizedDepth(bool render_to_depth);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue