From a579663eb90b21397d628e6dc1b9a5c8b06c3d62 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 10 Feb 2011 04:03:22 -0600 Subject: [PATCH] Added Gaussian blur post-process shader Added ability to manually input values in post-process shader menu --- indra/llrender/llpostprocess.cpp | 93 +++++++++++++++---- indra/llrender/llpostprocess.h | 15 ++- .../shaders/class2/effects/blurF.glsl | 23 ++--- .../shaders/class2/effects/gaussBlurF.glsl | 28 ++++++ .../windlight/postprocesseffects.xml | 4 + indra/newview/llfloaterpostprocess.cpp | 4 + indra/newview/llviewershadermgr.cpp | 28 +++++- indra/newview/llviewershadermgr.h | 1 + .../xui/en-us/floater_post_process.xml | 71 ++++++++------ 9 files changed, 203 insertions(+), 64 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class2/effects/gaussBlurF.glsl diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index 86e77b7bc..208ed6aba 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -40,6 +40,7 @@ #include "lldir.h" extern LLGLSLShader gPostColorFilterProgram; extern LLGLSLShader gPostNightVisionProgram; +extern LLGLSLShader gPostGaussianBlurProgram; LLPostProcess * gPostProcess = NULL; @@ -108,6 +109,8 @@ LLPostProcess::LLPostProcess(void) : contrastBase.append(1.0); contrastBase.append(1.0); contrastBase.append(0.5); + + defaultEffect["gauss_blur_passes"] = 2; } setSelectedEffect("default"); @@ -190,6 +193,7 @@ void LLPostProcess::initialize(unsigned int width, unsigned int height) createNightVisionShader(); createBloomShader(); createColorFilterShader(); + createGaussBlurShader(); checkError(); } @@ -197,40 +201,53 @@ inline bool LLPostProcess::shadersEnabled(void) { return (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean() || - tweaks.useBloomShader().asBoolean() ); + tweaks.useBloomShader().asBoolean() || + tweaks.useGaussBlurFilter().asBoolean() ); } void LLPostProcess::applyShaders(void) { - if (tweaks.useColorFilter()){ + bool copy_buffer = false; + if (tweaks.useColorFilter()) + { applyColorFilterShader(); checkError(); - } - if (tweaks.useNightVisionShader()){ + copy_buffer = true; + } + if (tweaks.useGaussBlurFilter()) + { /// If any of the above shaders have been called update the frame buffer; - if (tweaks.useColorFilter()) - { - U32 tex = mSceneRenderTexture->getTexName() ; - copyFrameBuffer(tex, screenW, screenH); - } + if (copy_buffer) + copyFrameBuffer(mSceneRenderTexture->getTexName(), screenW, screenH); + applyGaussBlurShader(); + checkError(); + copy_buffer = true; + } + if (tweaks.useNightVisionShader()) + { + /// If any of the above shaders have been called update the frame buffer; + if (copy_buffer) + copyFrameBuffer(mSceneRenderTexture->getTexName(), screenW, screenH); applyNightVisionShader(); checkError(); + copy_buffer = true; } - if (tweaks.useBloomShader()){ + if (tweaks.useBloomShader()) + { /// If any of the above shaders have been called update the frame buffer; - if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()) - { - U32 tex = mSceneRenderTexture->getTexName() ; - copyFrameBuffer(tex, screenW, screenH); - } + if (copy_buffer) + copyFrameBuffer(mSceneRenderTexture->getTexName(), screenW, screenH); applyBloomShader(); checkError(); + copy_buffer = true; } } void LLPostProcess::applyColorFilterShader(void) { + if(gPostColorFilterProgram.mProgramObject == 0) + return; /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/ gPostColorFilterProgram.bind(); @@ -275,6 +292,8 @@ void LLPostProcess::createColorFilterShader(void) void LLPostProcess::applyNightVisionShader(void) { + if(gPostNightVisionProgram.mProgramObject == 0) + return; /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/ gPostNightVisionProgram.bind(); @@ -330,7 +349,7 @@ void LLPostProcess::applyBloomShader(void) void LLPostProcess::createBloomShader(void) { - createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); + //createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); /// Create Bloom Extract Shader bloomExtractUniforms["RenderTexture"] = 0; @@ -346,6 +365,43 @@ void LLPostProcess::createBloomShader(void) bloomBlurUniforms["blurWidth"] = 0; } +void LLPostProcess::applyGaussBlurShader(void) +{ + int pass_count = tweaks.getGaussBlurPasses(); + if(!pass_count || gPostGaussianBlurProgram.mProgramObject == 0) + return; + + getShaderUniforms(gaussBlurUniforms, gPostGaussianBlurProgram.mProgramObject); + gPostGaussianBlurProgram.bind(); + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mSceneRenderTexture.get()->getTexName()); + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + glUniform1iARB(gaussBlurUniforms["RenderTexture"], 0); + GLint horiz_pass = gaussBlurUniforms["hoizontalPass"]; + for(int i = 0;igetTexName(), screenW, screenH); + glUniform1iARB(horiz_pass, j); + drawOrthoQuad(screenW, screenH, QUAD_NORMAL); + + } + } + gPostGaussianBlurProgram.unbind(); + +} + +void LLPostProcess::createGaussBlurShader(void) +{ + gaussBlurUniforms["RenderTexture"] = 0; + gaussBlurUniforms["hoizontalPass"] = 0; +} + void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog) { /// Find uniform locations and insert into map @@ -363,8 +419,7 @@ void LLPostProcess::doEffects(void) /// Copy the screen buffer to the render texture { - U32 tex = mSceneRenderTexture->getTexName() ; - copyFrameBuffer(tex, screenW, screenH); + copyFrameBuffer(mSceneRenderTexture->getTexName(), screenW, screenH); } /// Clear the frame buffer. @@ -389,7 +444,7 @@ void LLPostProcess::doEffects(void) checkError(); } -void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height) +void LLPostProcess::copyFrameBuffer(LLGLuint texture, unsigned int width, unsigned int height) { gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture); glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h index 009e4bd41..007020af1 100644 --- a/indra/llrender/llpostprocess.h +++ b/indra/llrender/llpostprocess.h @@ -124,7 +124,10 @@ public: inline LLSD & useColorFilter() { return (*this)["enable_color_filter"]; } - + + inline LLSD & useGaussBlurFilter() { + return (*this)["enable_gauss_blur"]; + } inline F32 getBrightMult() const { return F32((*this)["brightness_multiplier"].asReal()); @@ -182,6 +185,9 @@ public: return F32((*this)["saturation"].asReal()); } + inline LLSD & getGaussBlurPasses() { + return (*this)["gauss_blur_passes"]; + } }; bool initialized; @@ -230,6 +236,7 @@ private: glslUniforms bloomExtractUniforms; glslUniforms bloomBlurUniforms; glslUniforms colorFilterUniforms; + glslUniforms gaussBlurUniforms; // the name of currently selected effect in mAllEffects // invariant: tweaks == mAllEffects[mSelectedEffectName] @@ -253,10 +260,14 @@ private: void createColorFilterShader(void); void applyColorFilterShader(void); + /// Gaussian blur Filter Functions + void createGaussBlurShader(void); + void applyGaussBlurShader(void); + /// OpenGL Helper Functions void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog); void createTexture(LLPointer& texture, unsigned int width, unsigned int height); - void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height); + void copyFrameBuffer(LLGLuint texture, unsigned int width, unsigned int height); void createNoiseTexture(LLPointer& texture); bool checkError(void); void checkShaderError(GLhandleARB shader); diff --git a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl index 94433202a..7db969ef0 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl @@ -9,21 +9,18 @@ uniform sampler2DRect RenderTexture; uniform float bloomStrength; varying vec4 gl_TexCoord[gl_MaxTextureCoords]; + +float blurWeights[4] = float[4](.05,.1,.2,.3); + void main(void) { - float blurWeights[7]; - blurWeights[0] = 0.05; - blurWeights[1] = 0.1; - blurWeights[2] = 0.2; - blurWeights[3] = 0.3; - blurWeights[4] = 0.2; - blurWeights[5] = 0.1; - blurWeights[6] = 0.05; - - vec3 color = vec3(0,0,0); - for (int i = 0; i < 7; i++){ - color += vec3(texture2DRect(RenderTexture, gl_TexCoord[i].st)) * blurWeights[i]; - } + vec3 color = blurWeights[0] * texture2DRect(RenderTexture, gl_TexCoord[0].st).rgb; + color+= blurWeights[1] * texture2DRect(RenderTexture, gl_TexCoord[1].st).rgb; + color+= blurWeights[2] * texture2DRect(RenderTexture, gl_TexCoord[2].st).rgb; + color+= blurWeights[3] * texture2DRect(RenderTexture, gl_TexCoord[3].st).rgb; + color+= blurWeights[2] * texture2DRect(RenderTexture, gl_TexCoord[4].st).rgb; + color+= blurWeights[1] * texture2DRect(RenderTexture, gl_TexCoord[5].st).rgb; + color+= blurWeights[0] * texture2DRect(RenderTexture, gl_TexCoord[6].st).rgb; color *= bloomStrength; diff --git a/indra/newview/app_settings/shaders/class2/effects/gaussBlurF.glsl b/indra/newview/app_settings/shaders/class2/effects/gaussBlurF.glsl new file mode 100644 index 000000000..47c9f875b --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/effects/gaussBlurF.glsl @@ -0,0 +1,28 @@ +uniform sampler2DRect RenderTexture; +uniform int horizontalPass; + +uniform float offset[2] = float[2]( 1.3846153846, 3.2307692308 ); +uniform float weight[3] = float[3]( 0.2270270270, 0.3162162162, 0.0702702703 ); + +void main(void) +{ + vec4 color = texture2DRect(RenderTexture, gl_TexCoord[0].st)*weight[0]; + + + if(horizontalPass == 1) + { + color += weight[1] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x+offset[0],gl_TexCoord[0].y)); + color += weight[1] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x-offset[0],gl_TexCoord[0].y)); + color += weight[2] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x+offset[1],gl_TexCoord[0].y)); + color += weight[2] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x-offset[1],gl_TexCoord[0].y)); + + } + else + { + color += weight[1] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x,gl_TexCoord[0].y+offset[0])); + color += weight[1] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x,gl_TexCoord[0].y-offset[0])); + color += weight[2] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x,gl_TexCoord[0].y+offset[1])); + color += weight[2] * texture2DRect(RenderTexture, vec2(gl_TexCoord[0].x,gl_TexCoord[0].y-offset[1])); + } + gl_FragColor = color; +} \ No newline at end of file diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml index aeafc5641..8c25df6ff 100644 --- a/indra/newview/app_settings/windlight/postprocesseffects.xml +++ b/indra/newview/app_settings/windlight/postprocesseffects.xml @@ -170,6 +170,10 @@ 0 enable_night_vision 0 + enable_gauss_blur + 0 + gauss_blur_passes + 2 extract_high 1 extract_low diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp index de9b598b1..87615837a 100644 --- a/indra/newview/llfloaterpostprocess.cpp +++ b/indra/newview/llfloaterpostprocess.cpp @@ -75,6 +75,10 @@ LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater(std::string("Post-Proce childSetCommitCallback("BloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); childSetCommitCallback("BloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); + // Gauss Blur Callbacks + childSetCommitCallback("GaussBlurToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_gauss_blur"); + childSetCommitCallback("GaussBlurPasses", &LLFloaterPostProcess::onFloatControlMoved, (char*)"gauss_blur_passes"); + // Effect loading and saving. LLComboBox* comboBox = getChild("PPEffectsCombo"); childSetAction("PPLoadEffect", &LLFloaterPostProcess::onLoadEffect, comboBox); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 40f49c894..30cc972e7 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -101,6 +101,7 @@ LLGLSLShader gGlowProgram; LLGLSLShader gGlowExtractProgram; LLGLSLShader gPostColorFilterProgram; LLGLSLShader gPostNightVisionProgram; +LLGLSLShader gPostGaussianBlurProgram; // Deferred rendering shaders LLGLSLShader gDeferredImpostorProgram; @@ -494,6 +495,7 @@ void LLViewerShaderMgr::unloadShaders() gPostColorFilterProgram.unload(); gPostNightVisionProgram.unload(); + gPostGaussianBlurProgram.unload(); gDeferredDiffuseProgram.unload(); @@ -723,6 +725,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gGlowExtractProgram.unload(); gPostColorFilterProgram.unload(); gPostNightVisionProgram.unload(); + gPostGaussianBlurProgram.unload(); return FALSE; } @@ -759,7 +762,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() // ATI sampler2DRect compatibility. //load Color Filter Shader - if (success) + //if (success) { vector shaderUniforms; shaderUniforms.reserve(7); @@ -776,11 +779,11 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/colorFilterF.glsl", GL_FRAGMENT_SHADER_ARB)); gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); gPostColorFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; - success = gPostColorFilterProgram.createShader(NULL, &shaderUniforms); + /*success = */gPostColorFilterProgram.createShader(NULL, &shaderUniforms); } //load Night Vision Shader - if (success) + //if (success) { vector shaderUniforms; shaderUniforms.reserve(5); @@ -795,8 +798,25 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/nightVisionF.glsl", GL_FRAGMENT_SHADER_ARB)); gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); gPostNightVisionProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; - success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms); + /*success = */gPostNightVisionProgram.createShader(NULL, &shaderUniforms); } + + //if (success) + { + vector shaderUniforms; + shaderUniforms.reserve(2); + shaderUniforms.push_back("RenderTexture"); + shaderUniforms.push_back("hoizontalPass"); + + gPostGaussianBlurProgram.mName = "Gaussian Blur Shader (Post)"; + gPostGaussianBlurProgram.mShaderFiles.clear(); + gPostGaussianBlurProgram.mShaderFiles.push_back(make_pair("effects/gaussBlurF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPostGaussianBlurProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); + gPostGaussianBlurProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; + /*success = */gPostGaussianBlurProgram.createShader(NULL, &shaderUniforms); + } + + #endif return success; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index a743966d9..cd19e7ae7 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -316,6 +316,7 @@ extern LLGLSLShader gWLCloudProgram; // Post Process Shaders extern LLGLSLShader gPostColorFilterProgram; extern LLGLSLShader gPostNightVisionProgram; +extern LLGLSLShader gPostGaussianBlurProgram; // Deferred rendering shaders extern LLGLSLShader gDeferredImpostorProgram; diff --git a/indra/newview/skins/default/xui/en-us/floater_post_process.xml b/indra/newview/skins/default/xui/en-us/floater_post_process.xml index 7e24601bb..8c3eeb083 100644 --- a/indra/newview/skins/default/xui/en-us/floater_post_process.xml +++ b/indra/newview/skins/default/xui/en-us/floater_post_process.xml @@ -19,9 +19,9 @@ width="355"> Brightness - Saturation - Contrast - @@ -55,27 +55,46 @@ width="355"> Contrast Base Color - - - - + + + + Passes to apply + + + @@ -89,9 +108,9 @@ width="355"> Light Amplification Multiple - Noise Size - @@ -113,9 +132,9 @@ v_pad="0" width="355"> Noise Strength - @@ -132,8 +151,8 @@ width="355"> Luminosity Extraction - @@ -143,8 +162,8 @@ left="10" mouse_opaque="true" name="BloomSizeText" v_pad="0" width="355"> Bloom Size - @@ -155,8 +174,8 @@ width="355"> Bloom Strength -