And after a great deal of slow debugging we have deferred blinn-phong. Yayso

simple_math_single_header
Martin Felis 2018-04-10 14:08:28 +02:00
parent 37ffc2da1e
commit 796886b717
9 changed files with 356 additions and 77 deletions

View File

@ -0,0 +1,38 @@
#version 150 core
in vec2 ioFragTexCoords;
out vec3 outColor;
uniform sampler2D uColor;
uniform sampler2D uAmbientOcclusion;
uniform int uBlurSize;
uniform int uDisableColor;
float box_blur_occlusion (sampler2D ambient_occlusion, vec2 tex_coord, int size) {
vec2 texel_size = 1.0 / vec2(textureSize(uAmbientOcclusion, 0));
float value = 0.;
int count = 0;
for (int i = -size; i < size; i++) {
for (int j = -size; j < size; j++) {
value += texture(ambient_occlusion, tex_coord + vec2(i,j) * texel_size).x;
count++;
}
}
return value / (4 * size * size);
}
void main() {
float occlusion;
if (uBlurSize > 0) {
occlusion = box_blur_occlusion(uAmbientOcclusion, ioFragTexCoords, uBlurSize);
} else {
occlusion = texture(uAmbientOcclusion, ioFragTexCoords).x;
}
vec4 color = texture(uColor, ioFragTexCoords);
outColor = color.xyz * (1.0 - uDisableColor) * occlusion + uDisableColor * vec3(occlusion);
}

View File

@ -13,6 +13,9 @@ uniform sampler2DShadow uShadowMap;
uniform sampler2D uShadowMap; uniform sampler2D uShadowMap;
#endif #endif
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
in vec3 ioFragPosition; in vec3 ioFragPosition;
in vec3 ioFragNormal; in vec3 ioFragNormal;
in vec2 ioFragTexCoords; in vec2 ioFragTexCoords;
@ -78,15 +81,16 @@ void main() {
// diffuse lighting // diffuse lighting
vec3 normal_dir = normalize(ioFragNormal); vec3 normal_dir = normalize(ioFragNormal);
vec3 light_dir = normalize(uLightDirection); // vec3 light_dir = normalize(uLightDirection);
vec3 light_dir = transpose(inverse(mat3(uViewMatrix * uModelMatrix))) * uLightDirection;
float diff = max(dot(normal_dir, light_dir), 0.0); float diff = max(dot(normal_dir, light_dir), 0.0);
vec4 diffuse = diff * albedo_color; vec4 diffuse = diff * albedo_color;
// specular lighting // specular lighting
vec3 view_dir = normalize(uViewPosition - ioFragPosition); vec3 view_dir = normalize(-ioFragPosition);
vec3 halfway_dir = normalize(light_dir + view_dir); vec3 halfway_dir = normalize(light_dir + view_dir);
float spec = pow(max(dot(normal_dir, halfway_dir), 0.0), 32); float spec = pow(max(dot(normal_dir, halfway_dir), 0.0), 64);
vec4 specular = spec * vec4(0.5); vec4 specular = spec * vec4(0.5);
// shadow // shadow
@ -94,5 +98,5 @@ void main() {
outColor = ambient + (1.0 - shadow) * (diffuse + specular); outColor = ambient + (1.0 - shadow) * (diffuse + specular);
outPosition = ioFragPosition.xyz; outPosition = ioFragPosition.xyz;
outNormal = ioFragNormal; outNormal = normalize(ioFragNormal);
} }

View File

@ -0,0 +1,19 @@
#version 150 core
uniform vec4 uColor;
uniform sampler2D uAlbedoTexture;
in vec3 ioFragPosition;
in vec3 ioFragNormal;
in vec2 ioFragTexCoords;
in vec4 ioFragColor;
out vec4 outColor;
out vec3 outNormal;
out vec3 outPosition;
void main() {
outColor = texture(uAlbedoTexture, ioFragTexCoords) * ioFragColor * uColor;
outNormal = normalize(ioFragNormal);
outPosition = ioFragPosition.xyz;
}

View File

@ -0,0 +1,50 @@
#version 150 core
uniform sampler2D uColor;
uniform sampler2D uNormal;
uniform sampler2D uDepth;
#define USE_SAMPLER2D_SHADOW 1
#ifdef USE_SAMPLER2D_SHADOW
uniform sampler2DShadow uShadowMap;
#else
uniform sampler2D uShadowMap;
#endif
uniform sampler2D uPosition;
uniform vec3 uViewPosition;
uniform vec3 uLightDirection;
uniform mat4 uLightSpaceMatrix;
in vec2 ioFragTexCoords;
out vec3 outColor;
void main() {
vec3 color = texture(uColor, ioFragTexCoords).rgb;
vec3 normal = texture (uNormal, ioFragTexCoords).xyz;
float depth = texture (uDepth, ioFragTexCoords).r;
vec3 position = texture (uPosition, ioFragTexCoords).xyz;
// ambient lighting
float ambient_strength = 0.2;
vec3 ambient = ambient_strength * color;
vec3 light_dir = normalize(uLightDirection);
// diffuse lighting
float diff = max(dot(normal, light_dir), 0.0);
vec3 diffuse = diff * color;
// specular lighting
vec3 view_dir = normalize(-position);
vec3 halfway_dir = normalize(light_dir + view_dir);
float spec = pow(max(dot(normal, halfway_dir), 0.0), 32);
vec3 specular = spec * vec3(0.5);
// shadow
outColor = ambient + (diffuse + specular);
}

View File

@ -0,0 +1,26 @@
#version 150 core
in vec4 inCoord;
in vec3 inNormal;
in vec2 inUV;
in vec4 inColor;
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
out vec3 ioFragPosition;
out vec3 ioFragNormal;
out vec2 ioFragTexCoords;
out vec4 ioFragColor;
void main() {
mat4 model_view_matrix = uViewMatrix * uModelMatrix;
ioFragPosition = (model_view_matrix * inCoord).xyz;
ioFragNormal = transpose(inverse(mat3(model_view_matrix))) * inNormal;
ioFragTexCoords = inUV;
ioFragColor = inColor;
gl_Position = uProjectionMatrix * model_view_matrix * inCoord;
}

View File

@ -15,9 +15,18 @@ struct Renderer;
float moving_factor = 1.0f; float moving_factor = 1.0f;
struct RendererSettings { struct RendererSettings {
bool DrawDepth = false;
bool DrawLightDepth = false; bool DrawLightDepth = false;
bool DrawSSAO = false; int RenderMode = 0;
};
enum SceneRenderMode {
SceneRenderModeDefault = 0,
SceneRenderModeColor = 1,
SceneRenderModeDepth = 2,
SceneRenderModeNormals = 3,
SceneRenderModePositions = 4,
SceneRenderModeAmbientOcclusion = 5,
SceneRenderModeCount
}; };
static RendererSettings sRendererSettings; static RendererSettings sRendererSettings;
@ -86,10 +95,10 @@ 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);
SerializeBool(*serializer, "protot.RenderModule.DrawLightDepth", sRendererSettings.DrawLightDepth); SerializeBool(*serializer, "protot.RenderModule.DrawLightDepth", sRendererSettings.DrawLightDepth);
SerializeBool(*serializer, "protot.RenderModule.DrawSSAO", sRendererSettings.DrawSSAO); SerializeInt(*serializer, "protot.RenderModule.RenderMode", sRendererSettings.RenderMode);
SerializeBool(*serializer, "protot.RenderModule.mUseDeferred", gRenderer->mUseDeferred);
SerializeBool(*serializer, "protot.RenderModule.mIsSSAOEnabled", gRenderer->mIsSSAOEnabled); 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);
@ -374,12 +383,28 @@ void Renderer::Initialize(int width, int height) {
mRenderQuadProgramDepth.RegisterFileModification(); mRenderQuadProgramDepth.RegisterFileModification();
assert(load_result); assert(load_result);
// Deferred geomemtry pass
mDeferredGeometry = RenderProgram("data/shaders/vs_deferred_geometry.glsl", "data/shaders/fs_deferred_geometry.glsl");
load_result = mDeferredGeometry.Load();
mDeferredGeometry.RegisterFileModification();
assert(load_result);
mDeferredLighting = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_deferred_lighting.glsl");
load_result = mDeferredLighting.Load();
mDeferredLighting.RegisterFileModification();
assert(load_result);
// Program for SSAO // Program for SSAO
mSSAOProgram = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_ssao.glsl"); mSSAOProgram = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_ssao.glsl");
load_result = mSSAOProgram.Load(); load_result = mSSAOProgram.Load();
mSSAOProgram.RegisterFileModification(); mSSAOProgram.RegisterFileModification();
assert(load_result); assert(load_result);
mBlurSSAOProgram = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_blur_ssao.glsl");
load_result = mBlurSSAOProgram.Load();
mBlurSSAOProgram.RegisterFileModification();
assert(load_result);
InitializeSSAOKernelAndNoise(); InitializeSSAOKernelAndNoise();
// Render Target // Render Target
@ -403,6 +428,11 @@ void Renderer::Initialize(int width, int height) {
// SSAO Target // SSAO Target
mSSAOTarget.Initialize(width, height, RenderTarget::EnableColor); mSSAOTarget.Initialize(width, height, RenderTarget::EnableColor);
// Postprocess Target
mPostprocessTarget.Initialize(width, height, RenderTarget::EnableColor);
mDeferredLightingTarget.Initialize(width, height, RenderTarget::EnableColor);
// Light // Light
mLight.Initialize(); mLight.Initialize();
mLight.mShadowMapTarget.mVertexArray = &gVertexArray; mLight.mShadowMapTarget.mVertexArray = &gVertexArray;
@ -422,7 +452,6 @@ 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;
@ -438,13 +467,30 @@ void Renderer::RenderGl() {
| RenderTarget::EnableNormalTexture; | RenderTarget::EnableNormalTexture;
} }
if (mUseDeferred) {
required_render_flags = RenderTarget::EnableColor
| RenderTarget::EnableDepthTexture
| RenderTarget::EnableNormalTexture
// TODO: remove these
| RenderTarget::EnablePositionTexture
| RenderTarget::EnableLinearizedDepthTexture
;
}
if (mSceneAreaWidth != mRenderTarget.mWidth if (mSceneAreaWidth != mRenderTarget.mWidth
|| mSceneAreaHeight != mRenderTarget.mHeight || mSceneAreaHeight != mRenderTarget.mHeight
|| mRenderTarget.mFlags != required_render_flags ) { || mRenderTarget.mFlags != required_render_flags ) {
mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, required_render_flags); mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, required_render_flags);
mPostprocessTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor);
if (mIsSSAOEnabled) { if (mIsSSAOEnabled) {
mSSAOTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor); mSSAOTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor);
} }
if (mUseDeferred) {
mDeferredLightingTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor);
}
} }
if (mCamera.mWidth != mSceneAreaWidth if (mCamera.mWidth != mSceneAreaWidth
@ -491,9 +537,29 @@ void Renderer::RenderGl() {
gLog ("Cannot render: frame buffer invalid!"); gLog ("Cannot render: frame buffer invalid!");
} }
glEnable(GL_DEPTH_TEST);
RenderProgram *program = &mDefaultProgram;
if (mUseDeferred) {
program = &mDeferredGeometry;
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, buffers);
glClear(GL_COLOR_BUFFER_BIT);
} else {
if (program->SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) {
gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix");
}
GLenum buffers[] = { GL_COLOR_ATTACHMENT0};
glDrawBuffers (1, buffers);
}
// clear color and depth // clear color and depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_MULTISAMPLE);
glEnable(GL_CULL_FACE);
glUseProgram(mSimpleProgram.mProgramId); glUseProgram(mSimpleProgram.mProgramId);
mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); mSimpleProgram.SetMat44("uModelViewProj", model_view_projection);
@ -515,32 +581,23 @@ void Renderer::RenderGl() {
* mCamera.mViewMatrix * mCamera.mViewMatrix
* mCamera.mProjectionMatrix; * mCamera.mProjectionMatrix;
mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); mSimpleProgram.SetMat44("uModelViewProj", model_view_projection);
mSimpleProgram.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 0.4f)); mSimpleProgram.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 0.1f));
gVertexArray.Bind(); gVertexArray.Bind();
gXZPlaneGrid.Draw(GL_LINES); gXZPlaneGrid.Draw(GL_LINES);
// Scene // Scene
glUseProgram(mDefaultProgram.mProgramId); glUseProgram(program->mProgramId);
glEnable(GL_DEPTH_TEST);
if (mDefaultProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { RenderScene(*program, mCamera);
gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix");
if (mSettings->RenderMode == SceneRenderModeDepth) {
mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic);
} }
if (mIsSSAOEnabled) { if (mIsSSAOEnabled) {
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers (3, buffers); glDrawBuffers (3, buffers);
} else {
GLenum buffers[] = { GL_COLOR_ATTACHMENT0};
glDrawBuffers (1, buffers);
}
RenderScene(mDefaultProgram, mCamera);
if (mSettings->DrawDepth) {
mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic);
}
if (mIsSSAOEnabled) {
mSSAOTarget.Bind(); mSSAOTarget.Bind();
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight); glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
GLenum draw_attachment_0[] = {GL_COLOR_ATTACHMENT0 }; GLenum draw_attachment_0[] = {GL_COLOR_ATTACHMENT0 };
@ -556,7 +613,7 @@ void Renderer::RenderGl() {
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture); glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture);
// TODO: noise texture // Noise
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, mSSAONoiseTexture); glBindTexture(GL_TEXTURE_2D, mSSAONoiseTexture);
@ -572,9 +629,74 @@ void Renderer::RenderGl() {
mSSAOProgram.SetMat44("uProjection", mCamera.mProjectionMatrix); mSSAOProgram.SetMat44("uProjection", mCamera.mProjectionMatrix);
mSSAOProgram.SetVec3Array("uSamples", mSSAOKernel.size(), &mSSAOKernel[0][0]); mSSAOProgram.SetVec3Array("uSamples", mSSAOKernel.size(), &mSSAOKernel[0][0]);
// for (int i = 0; i < mSSAOKernel.size(); ++i) {
// mSSAOProgram.SetVec3(std::string("uSamples[" + std::to_string(i) + "]").c_str(), mSSAOKernel[i]); gVertexArray.Bind();
// } gScreenQuad.Draw(GL_TRIANGLES);
// Blur pass
mPostprocessTarget.Bind();
glViewport(0, 0, mCamera.mWidth, mCamera.mHeight);
glDrawBuffers(1, draw_attachment_0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mSSAOTarget.mColorTexture);
glUseProgram(mBlurSSAOProgram.mProgramId);
mBlurSSAOProgram.SetInt("uColor", 0);
mBlurSSAOProgram.SetInt("uAmbientOcclusion", 1);
mBlurSSAOProgram.SetInt("uBlurSize", mSSAOBlurSize);
mBlurSSAOProgram.SetInt("uDisableColor", mSSAODisableColor);
gScreenQuad.Draw(GL_TRIANGLES);
}
if (mUseDeferred) {
GLenum buffers[] = { GL_COLOR_ATTACHMENT0};
glDrawBuffers (1, buffers);
mDeferredLightingTarget.Bind();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(mDeferredLighting.mProgramId);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture);
mDeferredLighting.SetInt("uColorTexture", 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture);
mDeferredLighting.SetInt("uNormal", 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
mDeferredLighting.SetInt("uDepth", 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture);
mDeferredLighting.SetInt("uDepth", 3);
mDeferredLighting.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix);
// TODO: remove and reconstruct position from depth
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mPositionTexture);
mDeferredLighting.SetInt("uPosition", 4);
mDeferredLighting.SetMat44("uViewMatrix", mCamera.mViewMatrix);
Matrix33f view_mat_rot = mCamera.mViewMatrix.block<3,3>(0,0);
view_mat_rot = view_mat_rot.transpose();
Vector3f light_direction = view_mat_rot * mLight.mDirection.normalized();
// gLog ("Light direction %3.4f, %3.4f, %3.4f",
// light_direction[0],
// light_direction[1],
// light_direction[2]);
mDeferredLighting.SetVec3("uLightDirection", light_direction);
mDeferredLighting.SetVec3("uViewPosition", mCamera.mEye);
gVertexArray.Bind(); gVertexArray.Bind();
gScreenQuad.Draw(GL_TRIANGLES); gScreenQuad.Draw(GL_TRIANGLES);
@ -596,6 +718,13 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
program.SetMat33("uNormalMatrix", normal_matrix); program.SetMat33("uNormalMatrix", normal_matrix);
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
Vector3f light_dir = (camera.mViewMatrix * Vector4f (
mLight.mDirection[0],
mLight.mDirection[1],
mLight.mDirection[2],
1.0f
)).block<3,1>(0,0);
// program.SetVec3("uLightDirection", light_dir.normalize());
program.SetVec3("uLightDirection", mLight.mDirection); program.SetVec3("uLightDirection", mLight.mDirection);
program.SetVec3("uViewPosition", camera.mEye); program.SetVec3("uViewPosition", camera.mEye);
@ -614,7 +743,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
program.SetMat44("uModelMatrix", program.SetMat44("uModelMatrix",
RotateMat44(sin(0.3 * gTimer->mCurrentTime) * 180.0f, RotateMat44(sin(0.3 * gTimer->mCurrentTime) * 180.0f,
0.0f, 1.0f, 0.0f) 0.0f, 1.0f, 0.0f)
* TranslateMat44(3.0, 1.0 + sin(2.0f * gTimer->mCurrentTime), 0.0)) ; * TranslateMat44(5.0, 1.0 + sin(2.0f * gTimer->mCurrentTime), 0.0)) ;
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
gUnitCubeMesh.Draw(GL_TRIANGLES); gUnitCubeMesh.Draw(GL_TRIANGLES);
@ -634,7 +763,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
program.SetMat44("uModelMatrix", program.SetMat44("uModelMatrix",
RotateMat44(200.0f, 0.0f, 1.0f, 0.0f) RotateMat44(200.0f, 0.0f, 1.0f, 0.0f)
* TranslateMat44(moving_factor * sin(gTimer->mCurrentTime), 1.0f, 0.0f) * TranslateMat44(moving_factor * sin(gTimer->mCurrentTime), 1.0f, -3.0f)
* ScaleMat44(0.5f, 0.5f, 0.5f)); * ScaleMat44(0.5f, 0.5f, 0.5f));
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
@ -650,35 +779,37 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
void Renderer::DrawGui() { void Renderer::DrawGui() {
if (ImGui::BeginDock("Scene")) { if (ImGui::BeginDock("Scene")) {
static int e = 0; ImGui::RadioButton("Default", &sRendererSettings.RenderMode, 0); ImGui::SameLine();
if (mSettings->DrawDepth) { ImGui::RadioButton("Color", &sRendererSettings.RenderMode, 1); ImGui::SameLine();
e = 1; ImGui::RadioButton("Depth", &sRendererSettings.RenderMode, 2); ImGui::SameLine();
} else if (mSettings->DrawSSAO) { ImGui::RadioButton("Normals", &sRendererSettings.RenderMode, 3); ImGui::SameLine();
e = 2; ImGui::RadioButton("Positions", &sRendererSettings.RenderMode, 4);
}
ImGui::RadioButton("Default", &e, 0); ImGui::SameLine(); if (mIsSSAOEnabled) {
ImGui::RadioButton("Depth", &e, 1); ImGui::SameLine(); ImGui::SameLine();
ImGui::RadioButton("SSAO", &e, 2); ImGui::RadioButton("AO", &sRendererSettings.RenderMode, 5);
};
switch (e) { switch (sRendererSettings.RenderMode) {
case 0: mSettings->DrawDepth = 0; case SceneRenderModeDefault:
mSettings->DrawSSAO = 0; mRenderTextureRef.mTextureIdPtr =
mUseDeferred ? &mDeferredLightingTarget.mColorTexture : &mPostprocessTarget.mColorTexture;
break; break;
case 1: mSettings->DrawDepth = 1; case SceneRenderModeColor:
mSettings->DrawSSAO = 0;
break;
case 2: mSettings->DrawDepth = 0;
mSettings->DrawSSAO = 1;
break;
}
if (mSettings->DrawDepth) {
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mLinearizedDepthTexture;
} else if (mSettings->DrawSSAO) {
mRenderTextureRef.mTextureIdPtr = &mSSAOTarget.mColorTexture;
} else {
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mColorTexture; mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mColorTexture;
break;
case SceneRenderModeDepth:
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mLinearizedDepthTexture;
break;
case SceneRenderModeNormals:
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mNormalTexture;
break;
case SceneRenderModePositions:
mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mPositionTexture;
break;
case SceneRenderModeAmbientOcclusion:
mRenderTextureRef.mTextureIdPtr = &mSSAOTarget.mColorTexture;
break;
} }
ImGui::Text("Scene"); ImGui::Text("Scene");
@ -705,12 +836,15 @@ void Renderer::DrawGui() {
ImGui::Text("Camera"); ImGui::Text("Camera");
mCamera.DrawGui(); mCamera.DrawGui();
ImGui::Checkbox("Enable Deferred", &mUseDeferred);
ImGui::Checkbox("Enable SSAO", &mIsSSAOEnabled); ImGui::Checkbox("Enable SSAO", &mIsSSAOEnabled);
if (mIsSSAOEnabled) { if (mIsSSAOEnabled) {
ImGui::SliderFloat("Radius", &mSSAORadius, 0.0f, 1.0f); ImGui::SliderFloat("Radius", &mSSAORadius, 0.0f, 1.0f);
ImGui::SliderFloat("Bias", &mSSAOBias, 0.0f, 0.1f); ImGui::SliderFloat("Bias", &mSSAOBias, 0.0f, 0.1f);
ImGui::SliderInt("Samples", &mSSAOKernelSize, 1, 64); ImGui::SliderInt("Samples", &mSSAOKernelSize, 1, 64);
ImGui::SliderInt("Blur Size", &mSSAOBlurSize, 0, 8);
ImGui::Checkbox("Disable Color", &mSSAODisableColor);
if (mSSAOKernelSize != mSSAOKernel.size()) { if (mSSAOKernelSize != mSSAOKernel.size()) {
InitializeSSAOKernelAndNoise(); InitializeSSAOKernelAndNoise();

View File

@ -56,6 +56,7 @@ struct Renderer {
bool mInitialized = false; bool mInitialized = false;
bool mIsSSAOEnabled = false; bool mIsSSAOEnabled = false;
bool mUseDeferred = false;
uint32_t mWidth = 1; uint32_t mWidth = 1;
uint32_t mHeight = 1; uint32_t mHeight = 1;
@ -68,13 +69,18 @@ struct Renderer {
Texture mDefaultTexture; Texture mDefaultTexture;
RenderProgram mSimpleProgram; RenderProgram mSimpleProgram;
RenderProgram mDeferredGeometry;
RenderProgram mDeferredLighting;
RenderProgram mDefaultProgram; RenderProgram mDefaultProgram;
RenderProgram mRenderQuadProgramColor; RenderProgram mRenderQuadProgramColor;
RenderProgram mRenderQuadProgramDepth; RenderProgram mRenderQuadProgramDepth;
RenderProgram mSSAOProgram; RenderProgram mSSAOProgram;
RenderProgram mBlurSSAOProgram;
RenderTarget mRenderTarget; RenderTarget mRenderTarget;
RenderTarget mDeferredLightingTarget;
RenderTarget mSSAOTarget; RenderTarget mSSAOTarget;
RenderTarget mPostprocessTarget;
GLTextureRef mRenderTextureRef = { (int)0xbadface }; GLTextureRef mRenderTextureRef = { (int)0xbadface };
GLTextureRef mPositionTextureRef = { (int)0xbadface }; GLTextureRef mPositionTextureRef = { (int)0xbadface };
@ -85,6 +91,8 @@ struct Renderer {
int mSSAOKernelSize = 64; int mSSAOKernelSize = 64;
std::vector<Vector3f> mSSAOKernel; std::vector<Vector3f> mSSAOKernel;
GLuint mSSAONoiseTexture = -1; GLuint mSSAONoiseTexture = -1;
int mSSAOBlurSize = 1;
bool mSSAODisableColor = false;
Renderer() : Renderer() :
mInitialized(false), mInitialized(false),

View File

@ -154,8 +154,8 @@ GLuint RenderProgram::LinkProgram(GLuint vertex_shader, GLuint fragment_shader)
glBindAttribLocation(ProgramID, 3, "inColor"); glBindAttribLocation(ProgramID, 3, "inColor");
glBindFragDataLocation(ProgramID, 0, "outColor"); glBindFragDataLocation(ProgramID, 0, "outColor");
glBindFragDataLocation(ProgramID, 1, "outPosition"); glBindFragDataLocation(ProgramID, 1, "outNormal");
glBindFragDataLocation(ProgramID, 2, "outNormal"); glBindFragDataLocation(ProgramID, 2, "outPosition");
glLinkProgram(ProgramID); glLinkProgram(ProgramID);
@ -404,7 +404,7 @@ void RenderTarget::Resize(int width, int height, int flags) {
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); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, mLinearizedDepthTexture, 0);
} }
} else if (mFlags & EnableDepth) { } else if (mFlags & EnableDepth) {
assert((mFlags & EnableDepthTexture) == false); assert((mFlags & EnableDepthTexture) == false);
@ -414,6 +414,19 @@ void RenderTarget::Resize(int width, int height, int flags) {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer);
} }
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_ATTACHMENT1, GL_TEXTURE_2D, mNormalTexture, 0);
}
if (mFlags & EnablePositionTexture) { if (mFlags & EnablePositionTexture) {
glGenTextures(1, &mPositionTexture); glGenTextures(1, &mPositionTexture);
glBindTexture(GL_TEXTURE_2D, mPositionTexture); glBindTexture(GL_TEXTURE_2D, mPositionTexture);
@ -427,19 +440,6 @@ void RenderTarget::Resize(int width, int height, int flags) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, mPositionTexture, 0); 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) {
@ -463,7 +463,7 @@ void RenderTarget::RenderToLinearizedDepth(const float& near, const float& far,
assert(mQuadMesh != nullptr); assert(mQuadMesh != nullptr);
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum draw_attachment_1[] = { GL_COLOR_ATTACHMENT1 }; GLenum draw_attachment_1[] = { GL_COLOR_ATTACHMENT4 };
glDrawBuffers(1, draw_attachment_1); glDrawBuffers(1, draw_attachment_1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);

View File

@ -151,8 +151,8 @@ struct Camera {
Matrix44f mViewMatrix; Matrix44f mViewMatrix;
Camera() : Camera() :
mEye {5.f, 4.f, 5.f}, mEye {-4.f, 4.4f, 0.f},
mPoi {0.f, 2.f, 0.f}, mPoi {-3.2f, 3.8f, 0.2f},
mUp {0.f, 1.f, 0.f}, mUp {0.f, 1.f, 0.f},
mNear (0.1f), mNear (0.1f),
mFar (150.f), mFar (150.f),