Kaynağa Gözat

Merge pull request #515 from DavidWyand-GG/BlinnPhong

Blinn-Phong Specular Changes
David Wyand 12 yıl önce
ebeveyn
işleme
b0d54ef2ca
25 değiştirilmiş dosya ile 167 ekleme ve 26 silme
  1. 2 2
      Engine/source/lighting/advanced/advancedLightBufferConditioner.cpp
  2. 8 3
      Engine/source/lighting/advanced/glsl/advancedLightingFeaturesGLSL.cpp
  3. 7 1
      Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp
  4. 5 1
      Engine/source/materials/materialDefinition.cpp
  5. 1 0
      Engine/source/materials/materialDefinition.h
  6. 2 0
      Engine/source/materials/processedShaderMaterial.cpp
  7. 1 0
      Engine/source/materials/processedShaderMaterial.h
  8. 1 0
      Engine/source/shaderGen/shaderGenVars.cpp
  9. 1 0
      Engine/source/shaderGen/shaderGenVars.h
  10. 1 1
      Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl
  11. 1 1
      Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl
  12. 1 1
      Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl
  13. 1 1
      Templates/Empty/game/shaders/common/lighting/advanced/pointLightP.hlsl
  14. 1 1
      Templates/Empty/game/shaders/common/lighting/advanced/spotLightP.hlsl
  15. 1 1
      Templates/Empty/game/shaders/common/lighting/advanced/vectorLightP.hlsl
  16. 61 2
      Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui
  17. 3 3
      Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs
  18. 1 1
      Templates/Full/game/shaders/common/lighting/advanced/gl/pointLightP.glsl
  19. 1 1
      Templates/Full/game/shaders/common/lighting/advanced/gl/spotLightP.glsl
  20. 1 1
      Templates/Full/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl
  21. 1 1
      Templates/Full/game/shaders/common/lighting/advanced/pointLightP.hlsl
  22. 1 1
      Templates/Full/game/shaders/common/lighting/advanced/spotLightP.hlsl
  23. 1 1
      Templates/Full/game/shaders/common/lighting/advanced/vectorLightP.hlsl
  24. 61 2
      Templates/Full/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui
  25. 2 0
      Templates/Full/game/tools/materialEditor/scripts/materialEditor.ed.cs

+ 2 - 2
Engine/source/lighting/advanced/advancedLightBufferConditioner.cpp

@@ -51,7 +51,7 @@ Var *AdvancedLightBufferConditioner::_conditionOutput( Var *unconditionedOutput,
       if(getBufferFormat() == GFXFormatR16G16B16A16)
          meta->addStatement( new GenOp( "   @ = max(4.0, (float4(lightColor, specular) * NL_att + float4(bufferSample.rgb, 0.0)) / 4.0);\r\n", outputDecl ) );
       else
-         meta->addStatement( new GenOp( "   @ = float4(lightColor, specular) * NL_att + float4(bufferSample.rgb, 0.0);\r\n", outputDecl ) );
+         meta->addStatement( new GenOp( "   @ = float4(lightColor, 0) * NL_att + float4(bufferSample.rgb, specular);\r\n", outputDecl ) );
    }
    else
    {
@@ -80,7 +80,7 @@ Var *AdvancedLightBufferConditioner::_unconditionInput( Var *conditionedInput, M
       meta->addStatement( new GenOp( "   NL_att = @.b;\r\n", conditionedInput ) );
       meta->addStatement( new GenOp( "   lightColor = DecodeLuv(float3(saturate(NL_att), @.rg * 0.62));\r\n", conditionedInput ) );
    }
-   meta->addStatement( new GenOp( "   specular = max(@.a / NL_att, 0.00001f);\r\n", conditionedInput ) );
+   meta->addStatement( new GenOp( "   specular = @.a;\r\n", conditionedInput ) );
 
    return NULL;
 }

+ 8 - 3
Engine/source/lighting/advanced/glsl/advancedLightingFeaturesGLSL.cpp

@@ -517,6 +517,12 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
       specPow->constSortPos = cspPotentialPrimitive;
    }
 
+   Var *specStrength = new Var;
+   specStrength->setType( "float" );
+   specStrength->setName( "specularStrength" );
+   specStrength->uniform = true;
+   specStrength->constSortPos = cspPotentialPrimitive;
+
    Var *constSpecPow = new Var;
    constSpecPow->setType( "float" );
    constSpecPow->setName( "constantSpecularPower" );
@@ -527,7 +533,7 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
    AssertFatal( lightInfoSamp, "Something hosed the deferred features! Can't find lightInfoSample" );
 
    // (a^m)^n = a^(m*n)
-   meta->addStatement( new GenOp( "   @ = pow(d_specular, ceil(@ / @)) * d_NL_Att;\r\n", specDecl, specPow, constSpecPow ) );
+   meta->addStatement( new GenOp( "   @ = pow(d_specular, ceil(@ / @)) * @;\r\n", specDecl, specPow, constSpecPow, specStrength ) );
 
    LangElement *specMul = new GenOp( "@ * @", specCol, specular );
    LangElement *final = specMul;
@@ -539,8 +545,7 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
       final = new GenOp( "@ * @.a", final, bumpSample );
    }
 
-   // add to color
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( final, Material::Add ) ) );
+   // add to color   meta->addStatement( new GenOp( "   @;\r\n", assignColor( final, Material::Add ) ) );
 
    output = meta;
 }

+ 7 - 1
Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp

@@ -465,6 +465,12 @@ void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &component
       specPow->constSortPos = cspPotentialPrimitive;
    }
 
+   Var *specStrength = new Var;
+   specStrength->setType( "float" );
+   specStrength->setName( "specularStrength" );
+   specStrength->uniform = true;
+   specStrength->constSortPos = cspPotentialPrimitive;
+
    Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
    Var *d_specular = (Var*)LangElement::find( "d_specular" );
    Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
@@ -474,7 +480,7 @@ void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &component
 
    // (a^m)^n = a^(m*n)
    meta->addStatement( new GenOp( "   @ = pow( @, ceil(@ / AL_ConstantSpecularPower)) * @;\r\n", 
-      specDecl, d_specular, specPow, d_NL_Att ) );
+      specDecl, d_specular, specPow, specStrength ) );
 
    LangElement *specMul = new GenOp( "float4( @.rgb, 0 ) * @", specCol, specular );
    LangElement *final = specMul;

+ 5 - 1
Engine/source/materials/materialDefinition.cpp

@@ -116,6 +116,7 @@ Material::Material()
       mSpecular[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
 
       mSpecularPower[i] = 8.0f;
+      mSpecularStrength[i] = 1.0f;
       mPixelSpecular[i] = false;
 
       mParallaxScale[i] = 0.0f;
@@ -239,7 +240,10 @@ void Material::initPersistFields()
          "The color of the specular highlight when not using a specularMap." );
 
       addField("specularPower", TypeF32, Offset(mSpecularPower, Material), MAX_STAGES,
-         "The intensity of the specular highlight when not using a specularMap." );
+         "The hardness of the specular highlight when not using a specularMap." );
+
+		addField("specularStrength", TypeF32, Offset(mSpecularStrength, Material), MAX_STAGES,
+         "The strength of the specular highlight when not using a specularMap." );
 
       addField("pixelSpecular", TypeBool, Offset(mPixelSpecular, Material), MAX_STAGES, 
          "This enables per-pixel specular highlights controlled by the alpha channel of the "

+ 1 - 0
Engine/source/materials/materialDefinition.h

@@ -223,6 +223,7 @@ public:
    ColorF mSpecular[MAX_STAGES];
 
    F32 mSpecularPower[MAX_STAGES];
+   F32 mSpecularStrength[MAX_STAGES];
    bool mPixelSpecular[MAX_STAGES];
 
    bool mVertLit[MAX_STAGES];

+ 2 - 0
Engine/source/materials/processedShaderMaterial.cpp

@@ -54,6 +54,7 @@ void ShaderConstHandles::init( GFXShader *shader, CustomMaterial* mat /*=NULL*/
    mToneMapTexSC = shader->getShaderConstHandle(ShaderGenVars::toneMap);
    mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor);
    mSpecularPowerSC = shader->getShaderConstHandle(ShaderGenVars::specularPower);
+   mSpecularStrengthSC = shader->getShaderConstHandle(ShaderGenVars::specularStrength);
    mParallaxInfoSC = shader->getShaderConstHandle("$parallaxInfo");
    mFogDataSC = shader->getShaderConstHandle(ShaderGenVars::fogData);
    mFogColorSC = shader->getShaderConstHandle(ShaderGenVars::fogColor);
@@ -993,6 +994,7 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons
 
    shaderConsts->setSafe(handles->mSpecularColorSC, mMaterial->mSpecular[stageNum]);   
    shaderConsts->setSafe(handles->mSpecularPowerSC, mMaterial->mSpecularPower[stageNum]);
+   shaderConsts->setSafe(handles->mSpecularStrengthSC, mMaterial->mSpecularStrength[stageNum]);
 
    shaderConsts->setSafe(handles->mParallaxInfoSC, mMaterial->mParallaxScale[stageNum]);   
    shaderConsts->setSafe(handles->mMinnaertConstantSC, mMaterial->mMinnaertConstant[stageNum]);

+ 1 - 0
Engine/source/materials/processedShaderMaterial.h

@@ -46,6 +46,7 @@ public:
    GFXShaderConstHandle* mTexMatSC;
    GFXShaderConstHandle* mSpecularColorSC;
    GFXShaderConstHandle* mSpecularPowerSC;
+   GFXShaderConstHandle* mSpecularStrengthSC;
    GFXShaderConstHandle* mParallaxInfoSC;
    GFXShaderConstHandle* mFogDataSC;
    GFXShaderConstHandle* mFogColorSC;   

+ 1 - 0
Engine/source/shaderGen/shaderGenVars.cpp

@@ -65,6 +65,7 @@ const String ShaderGenVars::lightSpotAngle("$inLightSpotAngle");
 const String ShaderGenVars::lightSpotFalloff("$inLightSpotFalloff");
 const String ShaderGenVars::specularColor("$specularColor");
 const String ShaderGenVars::specularPower("$specularPower");
+const String ShaderGenVars::specularStrength("$specularStrength");
 
 // These are ignored by the D3D layers.
 const String ShaderGenVars::fogMap("$fogMap");

+ 1 - 0
Engine/source/shaderGen/shaderGenVars.h

@@ -78,6 +78,7 @@ struct ShaderGenVars
    const static String lightSpotFalloff;
    const static String specularColor;
    const static String specularPower;
+   const static String specularStrength;
    
    // Textures
    const static String fogMap;

+ 1 - 1
Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl

@@ -221,7 +221,7 @@ void main()
                                     normal, 
                                     normalize( -eyeRay ), 
                                     constantSpecularPower, 
-                                    lightColor.a * lightBrightness );
+                                    shadowed * atten * lightBrightness );
     
    // N.L * Attenuation
    float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 );

+ 1 - 1
Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl

@@ -148,7 +148,7 @@ void main()
                                     normal, 
                                     normalize( -eyeRay ), 
                                     constantSpecularPower, 
-                                    lightColor.a * lightBrightness );
+                                    shadowed * atten * lightBrightness );
     
    // N.L * Attenuation
    float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 );

+ 1 - 1
Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl

@@ -196,7 +196,7 @@ void main()
                                     normal, 
                                     normalize(-wsEyeRay), 
                                     constantSpecularPower, 
-                                    lightColor.a * lightBrightness );
+                                    shadowed * lightBrightness );
    
    float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed;
    

+ 1 - 1
Templates/Empty/game/shaders/common/lighting/advanced/pointLightP.hlsl

@@ -213,7 +213,7 @@ float4 main(   ConvexConnectP IN,
    // Specular term
    float specular = AL_CalcSpecular(   lightVec, 
                                        normal, 
-                                       normalize( -eyeRay ) ) * lightColor.a;
+                                       normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
 
    float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
    float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;

+ 1 - 1
Templates/Empty/game/shaders/common/lighting/advanced/spotLightP.hlsl

@@ -141,7 +141,7 @@ float4 main(   ConvexConnectP IN,
    // Specular term
    float specular = AL_CalcSpecular(   -lightToPxlVec, 
                                        normal, 
-                                       normalize( -eyeRay ) ) * lightColor.a;
+                                       normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
 
    float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
    float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;

+ 1 - 1
Templates/Empty/game/shaders/common/lighting/advanced/vectorLightP.hlsl

@@ -198,7 +198,7 @@ float4 main( FarFrustumQuadConnectP IN,
    // Specular term
    float specular = AL_CalcSpecular(   -lightDirection, 
                                        normal, 
-                                       normalize(-IN.vsEyeRay) ) * lightColor.a;
+                                       normalize(-IN.vsEyeRay) ) * lightBrightness * shadowed;
                                     
    float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness;
    float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;

+ 61 - 2
Templates/Empty/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui

@@ -1522,7 +1522,7 @@
                         profile = "ToolsGuiTransparentProfile";
                         isContainer = "1";
                         position = "0 0";
-                        Extent = "185 22";
+                        Extent = "185 44";
                         HorizSizing = "width";
                         
                         new GuiCheckBoxCtrl() {
@@ -1568,6 +1568,14 @@
                            useMouseEvents = "0";
                         };
                         
+                        new GuiTextCtrl() {
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "9 26";
+                           Extent = "72 16";
+                           text = "Spec strength";
+                        };
+
                         new GuiControl() {
                            class = "AggregateControl";
                            position = "91 4";
@@ -1589,7 +1597,7 @@
                               Command = "MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, true);";
                               AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, false);";
                               tooltipprofile = "ToolsGuiDefaultProfile";
-                              ToolTip = "Sets the strength of the Pixel Specular value.";
+                              ToolTip = "Sets the hardness of the Pixel Specular value.";
                               hovertime = "1000";
                               range = "1 128";
                               ticks = "0";
@@ -1618,6 +1626,57 @@
                               maxLength = "3";
                            };
                         };
+
+                        new GuiControl() {
+                           class = "AggregateControl";
+                           position = "91 26";
+                           Extent = "96 20";
+
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "specularStrengthSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "ToolsGuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 1";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "ToolsGuiDefaultProfile";
+                              ToolTip = "Sets the strength of the Pixel Specular value.";
+                              hovertime = "1000";
+                              range = "0 5";
+                              ticks = "0";
+                              value = "1";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "specularStrengthTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "ToolsGuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "1";
+                              maxLength = "3";
+                           };
+                        };
                      };
                      new GuiContainer(){ // glow emissive
                         profile = "ToolsGuiTransparentProfile";

+ 3 - 3
Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs

@@ -894,6 +894,8 @@ function MaterialEditorGui::guiSync( %this, %material )
    
    MaterialEditorPropertiesWindow-->specularPowerTextEdit.setText((%material).specularPower[%layer]);
    MaterialEditorPropertiesWindow-->specularPowerSlider.setValue((%material).specularPower[%layer]);
+   MaterialEditorPropertiesWindow-->specularStrengthTextEdit.setText((%material).specularStrength[%layer]);
+   MaterialEditorPropertiesWindow-->specularStrengthSlider.setValue((%material).specularStrength[%layer]);
    MaterialEditorPropertiesWindow-->pixelSpecularCheckbox.setValue((%material).pixelSpecular[%layer]);
    MaterialEditorPropertiesWindow-->glowCheckbox.setValue((%material).glow[%layer]);
    MaterialEditorPropertiesWindow-->emissiveCheckbox.setValue((%material).emissive[%layer]);
@@ -2142,9 +2144,7 @@ function MaterialEditorGui::changeMaterial(%this, %fromMaterial, %toMaterial)
       
       MaterialEditorGui.currentObject.changeMaterial( %materialTarget, %fromMaterial.getName(), %toMaterial.getName() );
       
-      if( MaterialEditorGui.currentObject.interiorFile !$= "" )
-         %sourcePath = MaterialEditorGui.currentObject.interiorFile;
-      else if( MaterialEditorGui.currentObject.shapeName !$= "" ) 
+      if( MaterialEditorGui.currentObject.shapeName !$= "" ) 
          %sourcePath = MaterialEditorGui.currentObject.shapeName;
       else if( MaterialEditorGui.currentObject.isMethod("getDatablock") )
       {

+ 1 - 1
Templates/Full/game/shaders/common/lighting/advanced/gl/pointLightP.glsl

@@ -221,7 +221,7 @@ void main()
                                     normal, 
                                     normalize( -eyeRay ), 
                                     constantSpecularPower, 
-                                    lightColor.a * lightBrightness );
+                                    shadowed * atten * lightBrightness );
     
    // N.L * Attenuation
    float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 );

+ 1 - 1
Templates/Full/game/shaders/common/lighting/advanced/gl/spotLightP.glsl

@@ -148,7 +148,7 @@ void main()
                                     normal, 
                                     normalize( -eyeRay ), 
                                     constantSpecularPower, 
-                                    lightColor.a * lightBrightness );
+                                    shadowed * atten * lightBrightness );
     
    // N.L * Attenuation
    float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 );

+ 1 - 1
Templates/Full/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl

@@ -196,7 +196,7 @@ void main()
                                     normal, 
                                     normalize(-wsEyeRay), 
                                     constantSpecularPower, 
-                                    lightColor.a * lightBrightness );
+                                    shadowed * lightBrightness );
    
    float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed;
    

+ 1 - 1
Templates/Full/game/shaders/common/lighting/advanced/pointLightP.hlsl

@@ -213,7 +213,7 @@ float4 main(   ConvexConnectP IN,
    // Specular term
    float specular = AL_CalcSpecular(   lightVec, 
                                        normal, 
-                                       normalize( -eyeRay ) ) * lightColor.a;
+                                       normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
 
    float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
    float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;

+ 1 - 1
Templates/Full/game/shaders/common/lighting/advanced/spotLightP.hlsl

@@ -141,7 +141,7 @@ float4 main(   ConvexConnectP IN,
    // Specular term
    float specular = AL_CalcSpecular(   -lightToPxlVec, 
                                        normal, 
-                                       normalize( -eyeRay ) ) * lightColor.a;
+                                       normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
 
    float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
    float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;

+ 1 - 1
Templates/Full/game/shaders/common/lighting/advanced/vectorLightP.hlsl

@@ -198,7 +198,7 @@ float4 main( FarFrustumQuadConnectP IN,
    // Specular term
    float specular = AL_CalcSpecular(   -lightDirection, 
                                        normal, 
-                                       normalize(-IN.vsEyeRay) ) * lightColor.a;
+                                       normalize(-IN.vsEyeRay) ) * lightBrightness * shadowed;
                                     
    float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness;
    float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;

+ 61 - 2
Templates/Full/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui

@@ -1522,7 +1522,7 @@
                         profile = "ToolsGuiTransparentProfile";
                         isContainer = "1";
                         position = "0 0";
-                        Extent = "185 22";
+                        Extent = "185 44";
                         HorizSizing = "width";
                         
                         new GuiCheckBoxCtrl() {
@@ -1568,6 +1568,14 @@
                            useMouseEvents = "0";
                         };
                         
+                        new GuiTextCtrl() {
+                           HorizSizing = "right";
+                           VertSizing = "bottom";
+                           position = "9 26";
+                           Extent = "72 16";
+                           text = "Spec strength";
+                        };
+
                         new GuiControl() {
                            class = "AggregateControl";
                            position = "91 4";
@@ -1589,7 +1597,7 @@
                               Command = "MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, true);";
                               AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, false);";
                               tooltipprofile = "ToolsGuiDefaultProfile";
-                              ToolTip = "Sets the strength of the Pixel Specular value.";
+                              ToolTip = "Sets the hardness of the Pixel Specular value.";
                               hovertime = "1000";
                               range = "1 128";
                               ticks = "0";
@@ -1618,6 +1626,57 @@
                               maxLength = "3";
                            };
                         };
+
+                        new GuiControl() {
+                           class = "AggregateControl";
+                           position = "91 26";
+                           Extent = "96 20";
+
+                           new GuiSliderCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "specularStrengthSlider";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "ToolsGuiSliderProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "0 1";
+                              Extent = "61 14";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);";
+                              AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);";
+                              tooltipprofile = "ToolsGuiDefaultProfile";
+                              ToolTip = "Sets the strength of the Pixel Specular value.";
+                              hovertime = "1000";
+                              range = "0 5";
+                              ticks = "0";
+                              value = "1";
+                           };
+                           new GuiTextEditCtrl() {
+                              canSaveDynamicFields = "0";
+                              internalName = "specularStrengthTextEdit";
+                              Enabled = "1";
+                              isContainer = "0";
+                              Profile = "ToolsGuiTextEditProfile";
+                              HorizSizing = "right";
+                              VertSizing = "bottom";
+                              position = "64 0";
+                              Extent = "29 18";
+                              MinExtent = "8 2";
+                              canSave = "1";
+                              Visible = "1";
+                              Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
+                              hovertime = "1000";
+                              AnchorTop = "1";
+                              AnchorBottom = "0";
+                              AnchorLeft = "1";
+                              AnchorRight = "0";
+                              text = "1";
+                              maxLength = "3";
+                           };
+                        };
                      };
                      new GuiContainer(){ // glow emissive
                         profile = "ToolsGuiTransparentProfile";

+ 2 - 0
Templates/Full/game/tools/materialEditor/scripts/materialEditor.ed.cs

@@ -894,6 +894,8 @@ function MaterialEditorGui::guiSync( %this, %material )
    
    MaterialEditorPropertiesWindow-->specularPowerTextEdit.setText((%material).specularPower[%layer]);
    MaterialEditorPropertiesWindow-->specularPowerSlider.setValue((%material).specularPower[%layer]);
+   MaterialEditorPropertiesWindow-->specularStrengthTextEdit.setText((%material).specularStrength[%layer]);
+   MaterialEditorPropertiesWindow-->specularStrengthSlider.setValue((%material).specularStrength[%layer]);
    MaterialEditorPropertiesWindow-->pixelSpecularCheckbox.setValue((%material).pixelSpecular[%layer]);
    MaterialEditorPropertiesWindow-->glowCheckbox.setValue((%material).glow[%layer]);
    MaterialEditorPropertiesWindow-->emissiveCheckbox.setValue((%material).emissive[%layer]);