diff --git a/interface/resources/shaders/ambient_occlusion.frag b/interface/resources/shaders/ambient_occlusion.frag index 2f7a322b05..2707415646 100644 --- a/interface/resources/shaders/ambient_occlusion.frag +++ b/interface/resources/shaders/ambient_occlusion.frag @@ -9,7 +9,7 @@ // // the depth texture -uniform sampler2D depth; +uniform sampler2D depthTexture; // the distance to the near clip plane uniform float near; @@ -25,10 +25,11 @@ uniform vec2 rightTop; // given a texture coordinate, returns the 3D view space coordinate vec3 texCoordToViewSpace(vec2 texCoord) { - float z = (far * near) / (texture2D(depth, texCoord).r * (far - near) - far); + float z = (far * near) / (texture2D(depthTexture, texCoord).r * (far - near) - far); return vec3(((texCoord * 2.0 - vec2(1.0, 1.0)) * (rightTop - leftBottom) + rightTop + leftBottom) * z / (-2.0 * near), z); } void main(void) { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + float depth = texture2D(depthTexture, gl_TexCoord[0].st).r; + gl_FragColor = vec4(depth, depth, depth, 1.0); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6f70c89f3b..c67590f019 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2463,6 +2463,8 @@ void Application::displaySide(Camera& whichCamera) { // Render the world box if (!_lookingInMirror->isChecked() && _renderStatsOn->isChecked()) { render_world_box(); } + _ambientOcclusionEffect.render(_glWidget->width(), _glWidget->height()); + // brad's frustum for debugging if (_frustumOn->isChecked()) renderViewFrustum(_viewFrustum); diff --git a/interface/src/Application.h b/interface/src/Application.h index c6bbd4eec2..6eaa9ee5ca 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -37,6 +37,7 @@ #include "VoxelSystem.h" #include "PacketHeaders.h" #include "Webcam.h" +#include "renderer/AmbientOcclusionEffect.h" #include "renderer/GeometryCache.h" #include "ui/ChatEntry.h" #include "ToolsPalette.h" @@ -366,6 +367,7 @@ private: int _hmdWarpParamLocation; GeometryCache _geometryCache; + AmbientOcclusionEffect _ambientOcclusionEffect; ParticleSystem _particleSystem; diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp new file mode 100644 index 0000000000..74c25235d8 --- /dev/null +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -0,0 +1,70 @@ +// +// AmbientOcclusionEffect.cpp +// interface +// +// Created by Andrzej Kapolka on 7/14/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include + +#include "AmbientOcclusionEffect.h" +#include "ProgramObject.h" + +ProgramObject* AmbientOcclusionEffect::_program = 0; + +AmbientOcclusionEffect::AmbientOcclusionEffect() : _depthTextureID(0) { +} + +void AmbientOcclusionEffect::render(int screenWidth, int screenHeight) { + // copy the z buffer into a depth texture + if (_depthTextureID == 0) { + glGenTextures(1, &_depthTextureID); + glBindTexture(GL_TEXTURE_2D, _depthTextureID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, screenWidth, screenHeight, 0); + + } else { + glBindTexture(GL_TEXTURE_2D, _depthTextureID); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth, screenHeight); + } + + // now render a full screen quad with that texture + if (_program == 0) { + switchToResourcesParentIfRequired(); + _program = new ProgramObject(); + _program->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/ambient_occlusion.frag"); + _program->link(); + + _program->bind(); + _program->setUniformValue("depthTexture", 0); + + } else { + _program->bind(); + } + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex2f(-1.0f, -1.0f); + glTexCoord2f(1.0f, 0.0f); + glVertex2f(1.0f, -1.0f); + glTexCoord2f(1.0f, 1.0f); + glVertex2f(1.0f, 1.0f); + glTexCoord2f(0.0f, 1.0f); + glVertex2f(-1.0f, 1.0f); + glEnd(); + + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + _program->release(); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/interface/src/renderer/AmbientOcclusionEffect.h b/interface/src/renderer/AmbientOcclusionEffect.h new file mode 100644 index 0000000000..4c05e348e6 --- /dev/null +++ b/interface/src/renderer/AmbientOcclusionEffect.h @@ -0,0 +1,30 @@ +// +// AmbientOcclusionEffect.h +// interface +// +// Created by Andrzej Kapolka on 7/14/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __interface__AmbientOcclusionEffect__ +#define __interface__AmbientOcclusionEffect__ + +#include "InterfaceConfig.h" + +class ProgramObject; + +class AmbientOcclusionEffect { +public: + + AmbientOcclusionEffect(); + + void render(int screenWidth, int screenHeight); + +private: + + GLuint _depthTextureID; + + static ProgramObject* _program; +}; + +#endif /* defined(__interface__AmbientOcclusionEffect__) */