Initial work to support SSAO: rendering position and normal maps

simple_math_single_header
Martin Felis 2018-04-04 22:59:22 +02:00
parent eb189326b1
commit 532a0fa9f2
5 changed files with 136 additions and 37 deletions

View File

@ -20,6 +20,8 @@ smooth in vec4 ioFragColor;
in vec4 ioFragPosLightSpace; in vec4 ioFragPosLightSpace;
out vec4 outColor; out vec4 outColor;
out vec3 outPosition;
out vec3 outNormal;
float ShadowCalculationPCF(vec4 frag_pos_light_space) { float ShadowCalculationPCF(vec4 frag_pos_light_space) {
vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w; vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w;
@ -88,19 +90,9 @@ void main() {
vec4 specular = spec * vec4(0.5); vec4 specular = spec * vec4(0.5);
// shadow // shadow
// float shadow = ShadowCalculation(ioFragPosLightSpace);
float shadow = ShadowCalculationPCF(ioFragPosLightSpace); float shadow = ShadowCalculationPCF(ioFragPosLightSpace);
outColor = ambient + (1.0 - shadow) * (diffuse + specular); outColor = ambient + (1.0 - shadow) * (diffuse + specular);
//
//
// vec3 projected_coordinates = ioFragPosLightSpace.xyz / ioFragPosLightSpace.w;
// projected_coordinates = projected_coordinates * 0.5 + 0.5;
// float shadow_map_value = texture(uShadowMap, projected_coordinates.xy).r;
// outColor = shadow_map_value * vec4(1.0, 1.0, 1.0, 1.0);
//
// outColor = vec4(vec3(1.0f - shadow_map_value), 1.0);
// outColor = (shadow) * vec4(1.0, 1.0, 1.0, 1.0); outPosition = ioFragPosition.xyz;
// outColor = ioFragPosLightSpace / ioFragPosLightSpace.w; outNormal = ioFragNormal;
// outColor = ambient + diffuse + specular;
} }

View File

@ -87,6 +87,8 @@ static void module_serialize (
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.DrawLightDepth", sRendererSettings.DrawLightDepth);
SerializeBool(*serializer, "protot.RenderModule.mIsSSAOEnabled", gRenderer->mIsSSAOEnabled);
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);
@ -374,10 +376,16 @@ void Renderer::Initialize(int width, int height) {
// Render Target // Render Target
gLog("Initializing main render target size: %d,%d", width, height); gLog("Initializing main render target size: %d,%d", width, height);
mRenderTarget.Initialize(width, height, int render_target_flags = RenderTarget::EnableColor
RenderTarget::EnableColor
| RenderTarget::EnableDepthTexture | RenderTarget::EnableDepthTexture
| RenderTarget::EnableLinearizedDepthTexture); | RenderTarget::EnableLinearizedDepthTexture;
if (mIsSSAOEnabled) {
render_target_flags = render_target_flags
| RenderTarget::EnablePositionTexture
| RenderTarget::EnableNormalTexture;
}
mRenderTarget.Initialize(width, height, render_target_flags);
mRenderTarget.mVertexArray = &gVertexArray; mRenderTarget.mVertexArray = &gVertexArray;
mRenderTarget.mQuadMesh = &gScreenQuad; mRenderTarget.mQuadMesh = &gScreenQuad;
@ -404,8 +412,22 @@ void Renderer::Shutdown() {
void Renderer::RenderGl() { void Renderer::RenderGl() {
mSceneAreaWidth = mSceneAreaWidth < 1 ? 1 : mSceneAreaWidth; mSceneAreaWidth = mSceneAreaWidth < 1 ? 1 : mSceneAreaWidth;
mSceneAreaHeight = mSceneAreaHeight < 1 ? 1 : mSceneAreaHeight; mSceneAreaHeight = mSceneAreaHeight < 1 ? 1 : mSceneAreaHeight;
if (mSceneAreaWidth != mRenderTarget.mWidth || mSceneAreaHeight != mRenderTarget.mHeight) {
mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight); // TODO: Refactor enabling/disabling buffers for SSAO
int required_render_flags = RenderTarget::EnableColor
| RenderTarget::EnableDepthTexture
| RenderTarget::EnableLinearizedDepthTexture;
if (mIsSSAOEnabled) {
required_render_flags = required_render_flags
| RenderTarget::EnablePositionTexture
| RenderTarget::EnableNormalTexture;
}
if (mSceneAreaWidth != mRenderTarget.mWidth
|| mSceneAreaHeight != mRenderTarget.mHeight
|| mRenderTarget.mFlags != required_render_flags ) {
mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, required_render_flags);
} }
if (mCamera.mWidth != mSceneAreaWidth if (mCamera.mWidth != mSceneAreaWidth
@ -488,6 +510,13 @@ void Renderer::RenderGl() {
gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix");
} }
if (mIsSSAOEnabled) {
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers (3, buffers);
} else {
GLenum buffers[] = { GL_COLOR_ATTACHMENT0};
glDrawBuffers (1, buffers);
}
RenderScene(mDefaultProgram, mCamera); RenderScene(mDefaultProgram, mCamera);
if (mSettings->DrawDepth) { if (mSettings->DrawDepth) {
@ -593,19 +622,32 @@ void Renderer::DrawGui() {
ImGui::EndDock(); ImGui::EndDock();
if (ImGui::BeginDock("Render Settings")) { if (ImGui::BeginDock("Render Settings")) {
ImGui::Text("Scene");
ImGui::SliderFloat("Moving Factor", &moving_factor, -10.0f, 10.0f);
ImGui::Text("Camera"); ImGui::Text("Camera");
mCamera.DrawGui(); mCamera.DrawGui();
ImGui::Text("Default Texture"); ImGui::Checkbox("Enable SSAO", &mIsSSAOEnabled);
ImVec2 content_avail = ImGui::GetContentRegionAvail();
ImGui::Image((void*) mDefaultTexture.mTextureId, if (mIsSSAOEnabled) {
ImVec2(content_avail.x, content_avail.x), ImGui::Text("Position Texture");
ImVec2(0.0f, 1.0f), mPositionTextureRef.mTextureIdPtr = &mRenderTarget.mPositionTexture;
ImVec2(1.0f, 0.0f) mPositionTextureRef.magic = (GLuint)0xbadface;
); float aspect = mRenderTarget.mHeight / mRenderTarget.mWidth;
ImVec2 content_avail = ImGui::GetContentRegionAvail();
ImGui::Image((void*) &mPositionTextureRef,
ImVec2(content_avail.x, content_avail.x * aspect),
ImVec2(0.0f, 1.0f),
ImVec2(1.0f, 0.0f)
);
ImGui::Text("Normal Texture");
mNormalTextureRef.mTextureIdPtr = &mRenderTarget.mNormalTexture;
mNormalTextureRef.magic = (GLuint)0xbadface;
ImGui::Image((void*) &mNormalTextureRef,
ImVec2(content_avail.x, content_avail.x * aspect),
ImVec2(0.0f, 1.0f),
ImVec2(1.0f, 0.0f)
);
}
} }
ImGui::EndDock(); ImGui::EndDock();

View File

@ -55,6 +55,8 @@ struct Renderer {
RendererSettings* mSettings = nullptr; RendererSettings* mSettings = nullptr;
bool mInitialized = false; bool mInitialized = false;
bool mIsSSAOEnabled = false;
uint32_t mWidth = 1; uint32_t mWidth = 1;
uint32_t mHeight = 1; uint32_t mHeight = 1;
uint32_t mSceneAreaWidth = 1; uint32_t mSceneAreaWidth = 1;
@ -72,6 +74,8 @@ struct Renderer {
RenderTarget mRenderTarget; RenderTarget mRenderTarget;
GLTextureRef mRenderTextureRef = { (int)0xbadface }; GLTextureRef mRenderTextureRef = { (int)0xbadface };
GLTextureRef mPositionTextureRef = { (int)0xbadface };
GLTextureRef mNormalTextureRef = { (int)0xbadface };
Renderer() : Renderer() :
mInitialized(false), mInitialized(false),

View File

@ -153,6 +153,10 @@ GLuint RenderProgram::LinkProgram(GLuint vertex_shader, GLuint fragment_shader)
glBindAttribLocation(ProgramID, 2, "inUV"); glBindAttribLocation(ProgramID, 2, "inUV");
glBindAttribLocation(ProgramID, 3, "inColor"); glBindAttribLocation(ProgramID, 3, "inColor");
glBindFragDataLocation(ProgramID, 0, "outColor");
glBindFragDataLocation(ProgramID, 1, "outPosition");
glBindFragDataLocation(ProgramID, 2, "outNormal");
glLinkProgram(ProgramID); glLinkProgram(ProgramID);
GLint Result = GL_FALSE; GLint Result = GL_FALSE;
@ -277,14 +281,29 @@ void RenderTarget::Initialize(int width, int height, int flags) {
mFlags = flags; mFlags = flags;
Resize(width, height); Resize(width, height, mFlags);
} }
void RenderTarget::Bind() { void RenderTarget::Bind() {
assert(glIsFramebuffer(mFrameBufferId)); assert(glIsFramebuffer(mFrameBufferId));
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum shadow_map_draw_buffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, shadow_map_draw_buffers); GLenum buffers[8];
int num_buffers = 0;
if (mFlags & EnableColor) {
buffers[num_buffers++] = GL_COLOR_ATTACHMENT0;
}
if (mFlags & EnablePositionTexture ) {
buffers[num_buffers++] = GL_COLOR_ATTACHMENT2;
}
if (mFlags & EnableNormalTexture) {
buffers[num_buffers++] = GL_COLOR_ATTACHMENT3;
}
glDrawBuffers(num_buffers, buffers);
} }
void RenderTarget::Cleanup() { void RenderTarget::Cleanup() {
@ -313,17 +332,30 @@ void RenderTarget::Cleanup() {
mLinearizedDepthTexture = -1; mLinearizedDepthTexture = -1;
} }
if (mPositionTexture != -1) {
glDeleteTextures(1, &mPositionTexture);
mPositionTexture = -1;
}
if (mNormalTexture != -1) {
glDeleteTextures(1, &mNormalTexture);
mNormalTexture = -1;
}
mWidth = -1; mWidth = -1;
mHeight = -1; mHeight = -1;
mFlags = 0;
} }
void RenderTarget::Resize(int width, int height) { void RenderTarget::Resize(int width, int height, int flags) {
if (width == mWidth && height == mHeight) if (width == mWidth && height == mHeight && flags == mFlags)
return; return;
Cleanup(); Cleanup();
gLog("Resizing RenderTarget to %d,%d", width, height); mFlags = flags;
gLog("Resizing RenderTarget to %d,%d flags: %d", width, height, flags);
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
@ -360,7 +392,6 @@ void RenderTarget::Resize(int width, int height) {
float border_color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; float border_color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture, 0);
if (mFlags & EnableLinearizedDepthTexture) { if (mFlags & EnableLinearizedDepthTexture) {
@ -383,6 +414,32 @@ void RenderTarget::Resize(int width, int height) {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer);
} }
if (mFlags & EnablePositionTexture) {
glGenTextures(1, &mPositionTexture);
glBindTexture(GL_TEXTURE_2D, mPositionTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, mWidth, mHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_ATTACHMENT2, GL_TEXTURE_2D, mPositionTexture, 0);
}
if (mFlags & EnableNormalTexture) {
glGenTextures(1, &mNormalTexture);
glBindTexture(GL_TEXTURE_2D, mNormalTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, mWidth, mHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_ATTACHMENT3, GL_TEXTURE_2D, mNormalTexture, 0);
}
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (result != GL_FRAMEBUFFER_COMPLETE) { if (result != GL_FRAMEBUFFER_COMPLETE) {
switch (result) { switch (result) {

View File

@ -254,12 +254,16 @@ struct RenderTarget {
GLuint mDepthBuffer = -1; GLuint mDepthBuffer = -1;
GLuint mDepthTexture = -1; GLuint mDepthTexture = -1;
GLuint mLinearizedDepthTexture = -1; GLuint mLinearizedDepthTexture = -1;
GLuint mPositionTexture = -1;
GLuint mNormalTexture = -1;
typedef enum { typedef enum {
EnableColor = 1, EnableColor = 1,
EnableDepth = 2, EnableDepth = 2,
EnableDepthTexture = 4, EnableDepthTexture = 4,
EnableLinearizedDepthTexture = 8 EnableLinearizedDepthTexture = 8,
EnablePositionTexture = 16,
EnableNormalTexture = 32,
} Flags; } Flags;
int mFlags = 0; int mFlags = 0;
@ -274,7 +278,7 @@ struct RenderTarget {
void Initialize(int width, int height, int flags); void Initialize(int width, int height, int flags);
void Bind(); void Bind();
void Cleanup(); void Cleanup();
void Resize(int width, int height); void Resize(int width, int height, int flags);
void RenderToLinearizedDepth(const float& near, const float& far, bool is_orthographic); void RenderToLinearizedDepth(const float& near, const float& far, bool is_orthographic);
}; };