From 16953ba9326cbb208c7bb26deb3f322824c92074 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Tue, 29 Apr 2014 00:30:14 -0700 Subject: [PATCH] Implemented camera downsampling (without reducing the render target resolution, for temporary drops of resolution without any skipped frames) --HG-- branch : nfb --- KREngine/kraken/KRCamera.cpp | 41 ++++++++++++------- KREngine/kraken/KRCamera.h | 6 ++- KREngine/kraken/KRShader.cpp | 13 ++++-- KREngine/kraken/KRShader.h | 1 + .../Shaders/PostShader.vsh | 3 +- .../Shaders/PostShader_osx.vsh | 5 ++- 6 files changed, 46 insertions(+), 23 deletions(-) diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index 915a873..54638a6 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -39,8 +39,8 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { m_last_frame_start = 0; m_particlesAbsoluteTime = 0.0f; - backingWidth = 0; - backingHeight = 0; + m_backingWidth = 0; + m_backingHeight = 0; volumetricBufferWidth = 0; volumetricBufferHeight = 0; m_pSkyBoxTexture = NULL; @@ -54,6 +54,7 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { volumetricLightAccumulationBuffer = 0; volumetricLightAccumulationTexture = 0; m_frame_times_filled = 0; + m_downsample = KRVector2::One(); } KRCamera::~KRCamera() { @@ -83,7 +84,7 @@ void KRCamera::flushSkybox() } void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight) -{ +{ // ----====---- Record timing information for measuring FPS ----====---- uint64_t current_time = m_pContext->getAbsoluteTimeMilliseconds(); if(m_last_frame_start != 0) { @@ -104,7 +105,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende //KRMat4 viewMatrix = KRMat4::Invert(getModelMatrix()); - settings.setViewportSize(KRVector2(backingWidth, backingHeight)); + settings.setViewportSize(KRVector2(m_backingWidth, m_backingHeight)); KRMat4 projectionMatrix; projectionMatrix.perspective(settings.perspective_fov, settings.m_viewportSize.x / settings.m_viewportSize.y, settings.perspective_nearz, settings.perspective_farz); m_viewport = KRViewport(settings.getViewportSize(), viewMatrix, projectionMatrix); @@ -175,6 +176,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Set render target GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, lightAccumulationBuffer)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); + GLDEBUG(glViewport(0, 0, m_viewport.getSize().x * m_downsample.x, m_viewport.getSize().y * m_downsample.y)); GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); @@ -251,7 +253,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Set render target GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); - GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); + GLDEBUG(glViewport(0, 0, m_viewport.getSize().x * m_downsample.x, m_viewport.getSize().y * m_downsample.y)); // Disable alpha blending GLDEBUG(glDisable(GL_BLEND)); @@ -517,9 +519,9 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) { - if(renderBufferWidth != backingWidth || renderBufferHeight != backingHeight) { - backingWidth = renderBufferWidth; - backingHeight = renderBufferHeight; + if(renderBufferWidth != m_backingWidth || renderBufferHeight != m_backingHeight) { + m_backingWidth = renderBufferWidth; + m_backingHeight = renderBufferHeight; if (compositeDepthTexture) { GLDEBUG(glDeleteTextures(1, &compositeDepthTexture)); @@ -558,7 +560,7 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_backingWidth, m_backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, compositeColorTexture, 0)); // ----- Create Depth Texture for compositeFramebuffer ----- @@ -568,9 +570,9 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, backingWidth, backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); - //GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, backingWidth, backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); - //GLDEBUG(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, backingWidth, backingHeight)); + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_backingWidth, m_backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); + //GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_backingWidth, m_backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); + //GLDEBUG(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, m_backingWidth, m_backingHeight)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); // ===== Create offscreen compositing framebuffer object ===== @@ -584,7 +586,7 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_backingWidth, m_backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0)); } @@ -692,7 +694,7 @@ void KRCamera::renderPost() }}; - + GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); GLDEBUG(glDisable(GL_DEPTH_TEST)); KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); @@ -1117,3 +1119,14 @@ const KRViewport &KRCamera::getViewport() const { return m_viewport; } + + +KRVector2 KRCamera::getDownsample() +{ + return m_downsample; +} + +void KRCamera::setDownsample(float v) +{ + m_downsample = v; +} diff --git a/KREngine/kraken/KRCamera.h b/KREngine/kraken/KRCamera.h index d84b589..b1d2070 100644 --- a/KREngine/kraken/KRCamera.h +++ b/KREngine/kraken/KRCamera.h @@ -69,11 +69,13 @@ public: std::string getDebugText(); void flushSkybox(); // this will delete the skybox and cause the camera to reload a new skybox based on the settings + KRVector2 getDownsample(); + void setDownsample(float v); private: void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight); - GLint backingWidth, backingHeight; + GLint m_backingWidth, m_backingHeight; GLint volumetricBufferWidth, volumetricBufferHeight; GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture; @@ -91,7 +93,7 @@ private: float m_particlesAbsoluteTime; - + KRVector2 m_downsample; typedef struct { GLfloat x; diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index a2fd09a..ff74cf5 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -64,6 +64,7 @@ const char *KRShader::KRENGINE_UNIFORM_NAMES[] = { "projection_matrix", // KRENGINE_UNIFORM_PROJECTION_MATRIX "camera_position_model_space", // KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE "viewport", // KRENGINE_UNIFORM_VIEWPORT + "viewport_downsample", // KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE "diffuseTexture", // KRENGINE_UNIFORM_DIFFUSETEXTURE "specularTexture", // KRENGINE_UNIFORM_SPECULARTEXTURE "reflectionCubeTexture", // KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE @@ -502,14 +503,18 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) { setUniform(KRENGINE_UNIFORM_VIEWPORT, KRVector4( - (GLfloat)0.0, - (GLfloat)0.0, - (GLfloat)viewport.getSize().x, - (GLfloat)viewport.getSize().y + (GLfloat)0.0, + (GLfloat)0.0, + (GLfloat)viewport.getSize().x, + (GLfloat)viewport.getSize().y ) ); } + if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE] != -1) { + setUniform(KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE, camera.getDownsample()); + } + // Rim highlighting parameters setUniform(KRENGINE_UNIFORM_RIM_COLOR, rim_color); setUniform(KRENGINE_UNIFORM_RIM_POWER, rim_power); diff --git a/KREngine/kraken/KRShader.h b/KREngine/kraken/KRShader.h index f0cdccc..c198ce6 100644 --- a/KREngine/kraken/KRShader.h +++ b/KREngine/kraken/KRShader.h @@ -76,6 +76,7 @@ public: KRENGINE_UNIFORM_PROJECTION_MATRIX, KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE, KRENGINE_UNIFORM_VIEWPORT, + KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE, KRENGINE_UNIFORM_DIFFUSETEXTURE, KRENGINE_UNIFORM_SPECULARTEXTURE, KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE, diff --git a/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh b/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh index 58b3827..c147629 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh @@ -25,6 +25,7 @@ // or implied, of Kearwood Gilbert. // +uniform mediump vec2 viewport_downsample; attribute vec4 vertex_position; attribute lowp vec4 vertex_uv; @@ -33,5 +34,5 @@ varying mediump vec2 textureCoordinate; void main() { gl_Position = vertex_position; - textureCoordinate = vertex_uv.xy; + textureCoordinate = vertex_uv.xy * viewport_downsample.xy; } \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh index 7a4719f..c147629 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh @@ -25,6 +25,7 @@ // or implied, of Kearwood Gilbert. // +uniform mediump vec2 viewport_downsample; attribute vec4 vertex_position; attribute lowp vec4 vertex_uv; @@ -33,5 +34,5 @@ varying mediump vec2 textureCoordinate; void main() { gl_Position = vertex_position; - textureCoordinate = vertex_uv.xy; -} + textureCoordinate = vertex_uv.xy * viewport_downsample.xy; +} \ No newline at end of file