Added Gaussian blur post-process shader

Added ability to manually input values in post-process shader menu
This commit is contained in:
Shyotl
2011-02-10 04:03:22 -06:00
parent a44d633bc8
commit a579663eb9
9 changed files with 203 additions and 64 deletions

View File

@@ -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;i<pass_count;++i)
{
for(int j = 0;j<2;++j)
{
if(i || j)
copyFrameBuffer(mSceneRenderTexture->getTexName(), 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);

View File

@@ -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<LLImageGL>& 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<LLImageGL>& texture);
bool checkError(void);
void checkShaderError(GLhandleARB shader);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -170,6 +170,10 @@
<boolean>0</boolean>
<key>enable_night_vision</key>
<boolean>0</boolean>
<key>enable_gauss_blur</key>
<boolean>0</boolean>
<key>gauss_blur_passes</key>
<integer>2</integer>
<key>extract_high</key>
<real>1</real>
<key>extract_low</key>

View File

@@ -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<LLComboBox>("PPEffectsCombo");
childSetAction("PPLoadEffect", &LLFloaterPostProcess::onLoadEffect, comboBox);

View File

@@ -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<string> 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<string> 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<string> 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;

View File

@@ -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;

View File

@@ -19,9 +19,9 @@
width="355">
Brightness
</text>
<slider bottom_delta="-30" can_edit_text="false"
<slider bottom_delta="-30" can_edit_text="true"
control_name="ColorFilterBrightness" decimal_digits="2" follows="left"
height="10" increment="0.01" initial_val="1.0" label="" left="14"
height="18" increment="0.01" initial_val="1.0" label="" left="14"
max_val="4" min_val="0" mouse_opaque="true" name="ColorFilterBrightness"
show_text="true" value="1.0" width="200" />
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
@@ -31,9 +31,9 @@
width="355">
Saturation
</text>
<slider bottom_delta="-30" can_edit_text="false"
<slider bottom_delta="-30" can_edit_text="true"
control_name="ColorFilterSaturation" decimal_digits="2" follows="left"
height="10" increment="0.01" initial_val="1.0" label="" left="14"
height="18" increment="0.01" initial_val="1.0" label="" left="14"
max_val="2" min_val="-1" mouse_opaque="true"
name="ColorFilterSaturation" show_text="true" value="1.0" width="200" />
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
@@ -43,8 +43,8 @@
width="355">
Contrast
</text>
<slider bottom_delta="-30" can_edit_text="false" control_name="ColorFilterContrast"
decimal_digits="2" follows="left" height="10" increment="0.01"
<slider bottom_delta="-30" can_edit_text="true" control_name="ColorFilterContrast"
decimal_digits="2" follows="left" height="18" increment="0.01"
initial_val="1.0" label="" left="14" max_val="4" min_val="0"
mouse_opaque="true" name="ColorFilterContrast" show_text="true"
value="1.0" width="200" />
@@ -55,27 +55,46 @@
width="355">
Contrast Base Color
</text>
<slider bottom_delta="-30" can_edit_text="false" control_name="ColorFilterBaseR"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-30" can_edit_text="true" control_name="ColorFilterBaseR"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="1.0" label="R" left="14" max_val="1" min_val="0"
mouse_opaque="true" name="ColorFilterBaseR" show_text="true" value="1.0"
width="200" />
<slider bottom_delta="-20" can_edit_text="false" control_name="ColorFilterBaseG"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-20" can_edit_text="true" control_name="ColorFilterBaseG"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="1.0" label="G" left="14" max_val="1" min_val="0"
mouse_opaque="true" name="ColorFilterBaseG" show_text="true" value="1.0"
width="200" />
<slider bottom_delta="-20" can_edit_text="false" control_name="ColorFilterBaseB"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-20" can_edit_text="true" control_name="ColorFilterBaseB"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="1.0" label="B" left="14" max_val="1" min_val="0"
mouse_opaque="true" name="ColorFilterBaseB" show_text="true" value="1.0"
width="200" />
<slider bottom_delta="-20" can_edit_text="false" control_name="ColorFilterBaseI"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-20" can_edit_text="true" control_name="ColorFilterBaseI"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="0.5" label="I" left="14" max_val="1" min_val="0"
mouse_opaque="true" name="ColorFilterBaseI" show_text="true" value="1.0"
width="200" />
</panel>
<panel border="true" bottom="-180" follows="left|top|right|bottom" height="400"
label="Gauss Blur" left="1" mouse_opaque="false"
name="GaussBlurPanel" width="398">
<check_box bottom="-20" control_name="GaussBlurToggle" follows="left|top"
font="SansSerifSmall" height="16" initial_value="false" label="Enable"
left="14" mouse_opaque="true" name="GaussBlurToggle" width="200" />
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom_delta="-21" drop_shadow_visible="true" follows="left|top|right"
font="SansSerif" h_pad="0" halign="left" height="16"
left="10" mouse_opaque="true" name="GaussBlurPassesText" v_pad="0"
width="355">
Passes to apply
</text>
<slider bottom_delta="-30" can_edit_text="true"
control_name="GaussBlurPasses" decimal_digits="0" follows="left"
height="18" increment="1" initial_val="9" label="" left="14"
max_val="25" min_val="1" mouse_opaque="true"
name="GaussBlurPasses" show_text="true" value="0.7" width="200" />
</panel>
<panel border="true" bottom="-180" follows="left|top|right|bottom" height="400"
label="Night Vision" left="1" mouse_opaque="false"
name="NightVisionPanel" width="398">
@@ -89,9 +108,9 @@
width="355">
Light Amplification Multiple
</text>
<slider bottom_delta="-30" can_edit_text="false"
<slider bottom_delta="-30" can_edit_text="true"
control_name="NightVisionBrightMult" decimal_digits="3" follows="left"
height="10" increment="0.01" initial_val="3.0" label="" left="14"
height="18" increment="0.01" initial_val="3.0" label="" left="14"
max_val="10" min_val="1" mouse_opaque="true"
name="NightVisionBrightMult" show_text="true" value="0.7" width="200" />
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
@@ -101,8 +120,8 @@
width="355">
Noise Size
</text>
<slider bottom_delta="-30" can_edit_text="false" control_name="NightVisionNoiseSize"
decimal_digits="3" follows="left" height="10" increment="0.1"
<slider bottom_delta="-30" can_edit_text="true" control_name="NightVisionNoiseSize"
decimal_digits="3" follows="left" height="18" increment="0.1"
initial_val="1" label="" left="14" max_val="100" min_val="1"
mouse_opaque="true" name="NightVisionNoiseSize" show_text="true"
value="1.0" width="200" />
@@ -113,9 +132,9 @@
v_pad="0" width="355">
Noise Strength
</text>
<slider bottom_delta="-30" can_edit_text="false"
<slider bottom_delta="-30" can_edit_text="true"
control_name="NightVisionNoiseStrength" decimal_digits="3"
follows="left" height="10" increment="0.01" initial_val="0.3" label=""
follows="left" height="18" increment="0.01" initial_val="0.3" label=""
left="14" max_val="1" min_val="0" mouse_opaque="true"
name="NightVisionNoiseStrength" show_text="true" value="1.0" width="200" />
</panel>
@@ -132,8 +151,8 @@
width="355">
Luminosity Extraction
</text>
<slider bottom_delta="-30" can_edit_text="false" control_name="BloomExtract"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-30" can_edit_text="true" control_name="BloomExtract"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="0.9" label="" left="14" max_val="1" min_val="0"
mouse_opaque="true" name="BloomExtract" show_text="true" value="0.7"
width="200" />
@@ -143,8 +162,8 @@
left="10" mouse_opaque="true" name="BloomSizeText" v_pad="0" width="355">
Bloom Size
</text>
<slider bottom_delta="-30" can_edit_text="false" control_name="BloomSize"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-30" can_edit_text="true" control_name="BloomSize"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="3.0" label="" left="14" max_val="20" min_val="0"
mouse_opaque="true" name="BloomSize" show_text="true" value="1.0"
width="200" />
@@ -155,8 +174,8 @@
width="355">
Bloom Strength
</text>
<slider bottom_delta="-30" can_edit_text="false" control_name="BloomStrength"
decimal_digits="3" follows="left" height="10" increment="0.01"
<slider bottom_delta="-30" can_edit_text="true" control_name="BloomStrength"
decimal_digits="3" follows="left" height="18" increment="0.01"
initial_val="1.2" label="" left="14" max_val="10" min_val="0"
mouse_opaque="true" name="BloomStrength" show_text="true" value="1.0"
width="200" />