diff --git a/Engine/source/terrain/glsl/terrFeatureGLSL.cpp b/Engine/source/terrain/glsl/terrFeatureGLSL.cpp index 63bc8cb60..d5da419ef 100644 --- a/Engine/source/terrain/glsl/terrFeatureGLSL.cpp +++ b/Engine/source/terrain/glsl/terrFeatureGLSL.cpp @@ -379,6 +379,9 @@ void TerrainDetailMapFeatGLSL::processPix( Vector &component const U32 detailIndex = getProcessIndex(); Var *inTex = getVertTexCoord( "texCoord" ); + // new terrain + bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex); + MultiLine *meta = new MultiLine; // We need the negative tangent space view vector @@ -447,6 +450,95 @@ void TerrainDetailMapFeatGLSL::processPix( Vector &component meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n", new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) ); + // New terrain + + Var *lerpBlend = (Var*)LangElement::find("lerpBlend"); + if (!lerpBlend) + { + lerpBlend = new Var; + lerpBlend->setType("float"); + lerpBlend->setName("lerpBlend"); + lerpBlend->uniform = true; + lerpBlend->constSortPos = cspPrimitive; + } + + + Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex)); + if (!blendDepth) + { + blendDepth = new Var; + blendDepth->setType("float"); + blendDepth->setName(String::ToString("blendDepth%d", detailIndex)); + blendDepth->uniform = true; + blendDepth->constSortPos = cspPrimitive; + } + + Var *baseColor = (Var*)LangElement::find("baseColor"); + Var *outColor = (Var*)LangElement::find(getOutputTargetVarName(DefaultTarget)); + + if (!outColor) + { + // create color var + outColor = new Var; + outColor->setType("float4"); + outColor->setName("col"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(outColor))); + //outColor->setStructName("OUT"); + } + + Var *detailColor = (Var*)LangElement::find("detailColor"); + if (!detailColor) + { + detailColor = new Var; + detailColor->setType("float4"); + detailColor->setName("detailColor"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(detailColor))); + } + + // Get the detail texture. + Var *detailMap = new Var; + detailMap->setType("sampler2D"); + detailMap->setName(String::ToString("detailMap%d", detailIndex)); + detailMap->uniform = true; + detailMap->sampler = true; + detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here + + // Get the normal map texture. + Var *normalMap = _getNormalMapTex(); + + // Issue happens somewhere here ----- + + // Sample the normal map. + // + // We take two normal samples and lerp between them for + // side projection layers... else a single sample. + LangElement *texOp; + + // Note that we're doing the standard greyscale detail + // map technique here which can darken and lighten the + // diffuse texture. + // + // We take two color samples and lerp between them for + // side projection layers... else a single sample. + // + if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex)) + { + meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", + detailColor, detailMap, inDet, detailMap, inDet, inTex)); + + texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )", + normalMap, inDet, normalMap, inDet, inTex); + } + else + { + meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", + detailColor, detailMap, inDet)); + + texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet); + } + + // New terrain + // Get a var and accumulate the blend amount. Var *blendTotal = (Var*)LangElement::find( "blendTotal" ); if ( !blendTotal ) @@ -460,6 +552,95 @@ void TerrainDetailMapFeatGLSL::processPix( Vector &component // Add to the blend total. meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) ); + // New terrain + Var *bumpNorm = (Var*)LangElement::find("bumpNormal"); + Var *invBlend = (Var*)LangElement::find("invBlend"); + Var *currentAlpha = (Var*)LangElement::find("currentAlpha"); + Var *ma = (Var*)LangElement::find("ma"); + Var *b1 = (Var*)LangElement::find("b1"); + Var *b2 = (Var*)LangElement::find("b2"); + + // Get a var and accumulate the blend amount. + if (!currentAlpha) + { + currentAlpha = new Var; + currentAlpha->setName("currentAlpha"); + currentAlpha->setType("float"); + meta->addStatement(new GenOp(" @ = 0;\r\n", new DecOp(currentAlpha))); + } + + if (hasNormal) + { + // create bump normal + bool bumpNormWasDefined = bumpNorm ? true : false; + LangElement *bumpNormDecl = bumpNorm; + + if (!bumpNormWasDefined) + { + bumpNorm = new Var; + bumpNorm->setName("bumpNormal"); + bumpNorm->setType("float4"); + bumpNormDecl = new DecOp(bumpNorm); + } + meta->addStatement(new GenOp(" @ = @;\r\n", bumpNormDecl, texOp)); + meta->addStatement(new GenOp(" @.a = max(@.a, 0.000001);\r\n", bumpNorm, bumpNorm)); + + // ----- + + // Get a var and accumulate the blend amount. + if (!invBlend) + { + invBlend = new Var; + invBlend->setName("invBlend"); + invBlend->setType("float"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(invBlend))); + } + + // Get a var and accumulate the blend amount. + if (!ma) + { + ma = new Var; + ma->setName("ma"); + ma->setType("float"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(ma))); + } + + // Get a var and accumulate the blend amount. + if (!b1) + { + b1 = new Var; + b1->setName("b1"); + b1->setType("float"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(b1))); + } + // Get a var and accumulate the blend amount. + if (!b2) + { + b2 = new Var; + b2->setName("b2"); + b2->setType("float"); + meta->addStatement(new GenOp(" @;\r\n", new DecOp(b2))); + } + + meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n { \r\n", lerpBlend)); + + meta->addStatement(new GenOp(" @ = 1-@;\r\n", invBlend, detailBlend)); + + meta->addStatement(new GenOp(" @ = max(@.a + @, @ + @) - @;\r\n", ma, bumpNorm, detailBlend, currentAlpha, invBlend, blendDepth)); + + meta->addStatement(new GenOp(" @ = max(@.a + @ - @, 0);\r\n", b1, bumpNorm, detailBlend, ma)); + + meta->addStatement(new GenOp(" @ = max(@ + @ - @, 0);\r\n", b2, currentAlpha, invBlend, ma)); + + meta->addStatement(new GenOp(" }\r\n")); + } + else + { + meta->addStatement(new GenOp(" @ = max(@,@);\r\n", currentAlpha, currentAlpha, detailBlend)); + } + + // New terrain + // If we had a parallax feature... then factor in the parallax // amount so that it fades out with the layer blending. if ( fd.features.hasFeature( MFT_TerrainParallaxMap, detailIndex ) ) @@ -495,58 +676,36 @@ void TerrainDetailMapFeatGLSL::processPix( Vector &component return; } - Var *detailColor = (Var*)LangElement::find( "detailColor" ); - if ( !detailColor ) - { - detailColor = new Var; - detailColor->setType( "vec4" ); - detailColor->setName( "detailColor" ); - meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) ); - } - - // Get the detail texture. - Var *detailMap = new Var; - detailMap->setType( "sampler2D" ); - detailMap->setName( String::ToString( "detailMap%d", detailIndex ) ); - detailMap->uniform = true; - detailMap->sampler = true; - detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here + // used as texture unit num here // If we're using SM 3.0 then take advantage of // dynamic branching to skip layers per-pixel. - if ( GFX->getPixelShaderVersion() >= 3.0f ) meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); meta->addStatement( new GenOp( " {\r\n" ) ); - // Note that we're doing the standard greyscale detail - // map technique here which can darken and lighten the - // diffuse texture. - // - // We take two color samples and lerp between them for - // side projection layers... else a single sample. - // - if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) ) - { - meta->addStatement( new GenOp( " @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", - detailColor, detailMap, inDet, detailMap, inDet, inTex ) ); - } - else - { - meta->addStatement( new GenOp( " @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", - detailColor, detailMap, inDet ) ); - } meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", detailColor, detailInfo, inDet ) ); - Var *baseColor = (Var*)LangElement::find( "baseColor" ); - Var *outColor = (Var*)LangElement::find( "col" ); + // New terrain + if (hasNormal) + { + meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend)); + meta->addStatement(new GenOp(" @.rgb = ((@ + @).rgb * @ + @.rgb * @) / (@ + @);\r\n", outColor, baseColor, detailColor, b1, outColor, b2, b1, b2)); + meta->addStatement(new GenOp(" else\r\n")); + } - meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n", - outColor, outColor, baseColor, detailColor, detailBlend ) ); + meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend)); + + // New terrain + if (hasNormal) + { + meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend)); + meta->addStatement(new GenOp(" @ = (@.a * @ + @ * @) / (@ + @);\r\n", currentAlpha, bumpNorm, b1, currentAlpha, b2, b1, b2)); + } meta->addStatement( new GenOp( " }\r\n" ) ); @@ -812,13 +971,9 @@ void TerrainMacroMapFeatGLSL::processPix( Vector &componentL meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", detailColor, detailInfo, inDet ) ); - Var *baseColor = (Var*)LangElement::find( "baseColor" ); Var *outColor = (Var*)LangElement::find( "col" ); - meta->addStatement( new GenOp( " @ = lerp( @, @ + @, @ );\r\n", - outColor, outColor, outColor, detailColor, detailBlend ) ); - //outColor, outColor, baseColor, detailColor, detailBlend ) ); - + meta->addStatement(new GenOp(" @ += @ * @;\r\n", outColor, detailColor, detailBlend)); meta->addStatement( new GenOp( " }\r\n" ) ); output = meta; @@ -920,15 +1075,36 @@ void TerrainNormalMapFeatGLSL::processPix( Vector &component texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet ); // create bump normal - Var *bumpNorm = new Var; - bumpNorm->setName( "bumpNormal" ); - bumpNorm->setType( "vec4" ); + // New terrain + Var *bumpNorm = (Var*)LangElement::find("bumpNormal"); + bool bumpNormWasDefined = bumpNorm ? true : false; + LangElement *bumpNormDecl = bumpNorm; + + if (!bumpNormWasDefined) + { + bumpNorm = new Var; + bumpNorm->setName("bumpNormal"); + bumpNorm->setType("float4"); + bumpNormDecl = new DecOp(bumpNorm); + } - LangElement *bumpNormDecl = new DecOp( bumpNorm ); meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) ); + // New terrain + Var *lerpBlend = (Var*)LangElement::find("lerpBlend"); + AssertFatal(lerpBlend, "The lerpBlend is missing!"); + Var *b1 = (Var*)LangElement::find("b1"); + AssertFatal(b1, "The b1 is missing!"); + Var *b2 = (Var*)LangElement::find("b2"); + AssertFatal(b2, "The b2 is missing!"); + // Normalize is done later... // Note: The reverse mul order is intentional. Affine matrix. + + // New terrain + meta->addStatement(new GenOp(" if( @ <= 0 ) \r\n", lerpBlend)); + meta->addStatement(new GenOp(" @ = (tMul( @.xyz, @ ).rgb * @ + @.rgb * @) / (@ + @);\r\n", gbNormal, bumpNorm, viewToTangent, b1, gbNormal, b2, b1, b2)); + meta->addStatement(new GenOp(" else\r\n")); meta->addStatement( new GenOp( " @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n", gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) ); diff --git a/Engine/source/terrain/terrCellMaterial.cpp b/Engine/source/terrain/terrCellMaterial.cpp index 101c21f0c..186a68d70 100644 --- a/Engine/source/terrain/terrCellMaterial.cpp +++ b/Engine/source/terrain/terrCellMaterial.cpp @@ -574,6 +574,10 @@ bool TerrainCellMaterial::_createPass( Vector *materials, matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) ); matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) ); + // New blending + matInfo->lerpBlend = pass->shader->getShaderConstHandle("$lerpBlend"); + matInfo->blendDepth = pass->shader->getShaderConstHandle(avar("$blendDepth%d", i)); + matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) ); if ( matInfo->detailTexConst->isValid() ) { @@ -711,6 +715,11 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass ) pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade ); pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax ); + // New blending + bool lerpBlend = Con::getBoolVariable("$Pref::Terrain::LerpBlend", true); + pass->consts->setSafe(matInfo->lerpBlend, lerpBlend ? 1.0f : 0.0f); + pass->consts->setSafe(matInfo->blendDepth, matInfo->mat->getBlendDepth()); + // macro texture info F32 macroSize = matInfo->mat->getMacroSize(); diff --git a/Engine/source/terrain/terrCellMaterial.h b/Engine/source/terrain/terrCellMaterial.h index 0784bc192..3d5b7d438 100644 --- a/Engine/source/terrain/terrCellMaterial.h +++ b/Engine/source/terrain/terrCellMaterial.h @@ -80,6 +80,10 @@ protected: GFXShaderConstHandle *detailInfoVConst; GFXShaderConstHandle *detailInfoPConst; + // New blending + GFXShaderConstHandle *lerpBlend; + GFXShaderConstHandle *blendDepth; + GFXShaderConstHandle *macroInfoVConst; GFXShaderConstHandle *macroInfoPConst; }; diff --git a/Engine/source/terrain/terrMaterial.cpp b/Engine/source/terrain/terrMaterial.cpp index 9f3a5c76b..51fd464f7 100644 --- a/Engine/source/terrain/terrMaterial.cpp +++ b/Engine/source/terrain/terrMaterial.cpp @@ -65,7 +65,8 @@ TerrainMaterial::TerrainMaterial() mMacroSize( 200.0f ), mMacroStrength( 0.7f ), mMacroDistance( 500.0f ), - mParallaxScale( 0.0f ) + mParallaxScale(0.0f), + mBlendDepth(0.4f) { } @@ -97,6 +98,9 @@ void TerrainMaterial::initPersistFields() addField( "parallaxScale", TypeF32, Offset( mParallaxScale, TerrainMaterial ), "Used to scale the height from the normal map to give some self " "occlusion effect (aka parallax) to the terrain material" ); + addField("blendDepth", TypeF32, Offset(mBlendDepth, TerrainMaterial), "Depth for blending the textures using the new blending method by Lukas Joergensen." + "Higher numbers = larger blend radius."); + Parent::initPersistFields(); // Gotta call this at least once or it won't get created! diff --git a/Engine/source/terrain/terrMaterial.h b/Engine/source/terrain/terrMaterial.h index de2cb47d1..386d08076 100644 --- a/Engine/source/terrain/terrMaterial.h +++ b/Engine/source/terrain/terrMaterial.h @@ -74,6 +74,11 @@ protected: /// F32 mParallaxScale; + /// Depth for blending the textures using the new + /// blending method. Higher numbers = larger blend + /// radius. + F32 mBlendDepth; + public: TerrainMaterial(); @@ -119,6 +124,8 @@ public: F32 getParallaxScale() const { return mParallaxScale; } + F32 getBlendDepth() const { return mBlendDepth; } + }; #endif // _TERRMATERIAL_H_ diff --git a/Templates/Empty/game/art/terrains/Example/dirt_grass_n.png b/Templates/Empty/game/art/terrains/Example/dirt_grass_n.png new file mode 100644 index 000000000..ba68973d6 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/dirt_grass_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/grass1_dry.jpg b/Templates/Empty/game/art/terrains/Example/grass1_dry.jpg new file mode 100644 index 000000000..331d1c667 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/grass1_dry.jpg differ diff --git a/Templates/Empty/game/art/terrains/Example/grass1_dry_d.png b/Templates/Empty/game/art/terrains/Example/grass1_dry_d.png new file mode 100644 index 000000000..9499a591a Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/grass1_dry_d.png differ diff --git a/Templates/Empty/game/art/terrains/Example/grass1_dry_n.png b/Templates/Empty/game/art/terrains/Example/grass1_dry_n.png new file mode 100644 index 000000000..c6bd8d748 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/grass1_dry_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/grass1_n.png b/Templates/Empty/game/art/terrains/Example/grass1_n.png new file mode 100644 index 000000000..2e355dbf2 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/grass1_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/grass2_n.png b/Templates/Empty/game/art/terrains/Example/grass2_n.png new file mode 100644 index 000000000..1dbb11b2b Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/grass2_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/road_n.png b/Templates/Empty/game/art/terrains/Example/road_n.png new file mode 100644 index 000000000..7ddfa28b0 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/road_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/rocks1_n.png b/Templates/Empty/game/art/terrains/Example/rocks1_n.png new file mode 100644 index 000000000..3fcbd446c Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/rocks1_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/rocktest_n.png b/Templates/Empty/game/art/terrains/Example/rocktest_n.png new file mode 100644 index 000000000..99b51d5c6 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/rocktest_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/sand_n.png b/Templates/Empty/game/art/terrains/Example/sand_n.png new file mode 100644 index 000000000..8be0de18b Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/sand_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/snowtop_n.png b/Templates/Empty/game/art/terrains/Example/snowtop_n.png new file mode 100644 index 000000000..d299b5fd0 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/snowtop_n.png differ diff --git a/Templates/Empty/game/art/terrains/Example/stone_n.png b/Templates/Empty/game/art/terrains/Example/stone_n.png new file mode 100644 index 000000000..7a924e241 Binary files /dev/null and b/Templates/Empty/game/art/terrains/Example/stone_n.png differ diff --git a/Templates/Empty/game/art/terrains/materials.cs b/Templates/Empty/game/art/terrains/materials.cs index e99d2e537..ac7b59b35 100644 --- a/Templates/Empty/game/art/terrains/materials.cs +++ b/Templates/Empty/game/art/terrains/materials.cs @@ -20,3 +20,228 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// Sample grass +// ---------------------------------------------------------------------------- + +singleton Material(TerrainFX_grass1) +{ + mapTo = "grass1"; + footstepSoundId = 0; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + effectColor[0] = "0.42 0.42 0 1"; + effectColor[1] = "0.42 0.42 0 1"; + impactSoundId = "0"; +}; + +new TerrainMaterial() +{ + internalName = "grass1"; + diffuseMap = "art/terrains/Example/grass1"; + detailMap = "art/terrains/Example/grass1_d"; + detailSize = "10"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "200"; + normalMap = "art/terrains/Example/grass1_n"; + detailDistance = "1000"; +}; + +singleton Material(TerrainFX_grass2) +{ + mapTo = "grass2"; + footstepSoundId = 0; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + effectColor[0] = "0.42 0.42 0 1"; + effectColor[1] = "0.42 0.42 0 1"; + impactSoundId = "0"; +}; + +new TerrainMaterial() +{ + internalName = "grass2"; + diffuseMap = "art/terrains/Example/grass2"; + detailMap = "art/terrains/Example/grass2_d"; + detailSize = "10"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "200"; +}; + +singleton Material(TerrainFX_grass1dry) +{ + mapTo = "grass1_dry"; + footstepSoundId = 0; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + effectColor[0] = "0.63 0.55 0 1"; +}; + +new TerrainMaterial() +{ + internalName = "grass1_dry"; + diffuseMap = "art/terrains/Example/grass1_dry"; + detailMap = "art/terrains/Example/grass1_dry_d"; + detailSize = "10"; + detailDistance = "100"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "250"; + detailStrength = "2"; + normalMap = "art/terrains/Example/grass1_dry_n"; +}; + +singleton Material(TerrainFX_dirt_grass) +{ + mapTo = "dirt_grass"; + footstepSoundId = 0; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + effectColor[0] = "0.63 0.55 0 1"; + diffuseMap = "art/terrains/Example/dirt_grass"; + diffuseSize = "200"; + normalMap = "art/terrains/Example/dirt_grass_n"; + detailMap = "art/terrains/Example/dirt_grass_d"; + detailDistance = "100"; + internalName = "dirt_grass"; + isManaged = "1"; + detailBrightness = "1"; + enabled = "1"; +}; + +new TerrainMaterial() +{ + internalName = "dirt_grass"; + diffuseMap = "art/terrains/Example/dirt_grass"; + detailMap = "art/terrains/Example/dirt_grass_d"; + detailSize = "5"; + detailDistance = "100"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "200"; +}; + +// ---------------------------------------------------------------------------- +// Sample rock +// ---------------------------------------------------------------------------- + +singleton Material(TerrainFX_rocktest) +{ + mapTo = "rocktest"; + footstepSoundId = "1"; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + impactSoundId = "1"; + effectColor[0] = "0.25 0.25 0.25 1"; + effectColor[1] = "0.25 0.25 0.25 0"; + diffuseMap = "art/terrains/Example/rocktest"; + diffuseSize = "400"; + normalMap = "art/terrains/Example/rocktest_n"; + detailMap = "art/terrains/Example/rocktest_d"; + detailSize = "10"; + detailDistance = "100"; + internalName = "rocktest"; + isManaged = "1"; + detailBrightness = "1"; + enabled = "1"; +}; + +new TerrainMaterial() +{ + internalName = "rocktest"; + diffuseMap = "art/terrains/Example/rocktest"; + detailMap = "art/terrains/Example/rocktest_d"; + detailSize = "10"; + detailDistance = "100"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "400"; +}; + +// ---------------------------------------------------------------------------- +// Sample rock +// ---------------------------------------------------------------------------- + +singleton Material(TerrainFX_stone) +{ + mapTo = "stone"; + footstepSoundId = "1"; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + impactSoundId = "1"; + effectColor[0] = "0.25 0.25 0.25 1"; + effectColor[1] = "0.25 0.25 0.25 0"; + diffuseMap = "art/terrains/Example/stone"; + diffuseSize = "400"; + normalMap = "art/terrains/Example/stone_n"; + detailMap = "art/terrains/Example/stone_d"; + detailSize = "10"; + detailDistance = "100"; + internalName = "stone"; + isManaged = "1"; + detailBrightness = "1"; + enabled = "1"; +}; + +new TerrainMaterial() +{ + internalName = "stone"; + diffuseMap = "art/terrains/Example/stone"; + detailMap = "art/terrains/Example/stone_d"; + detailSize = "10"; + detailDistance = "100"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "400"; + useSideProjection = "0"; +}; +// ---------------------------------------------------------------------------- +// Sample sand +// ---------------------------------------------------------------------------- + +singleton Material(TerrainFX_sand) +{ + mapTo = "sand"; + footstepSoundId = "3"; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + specularPower[0] = "1"; + effectColor[0] = "0.84 0.71 0.5 1"; + effectColor[1] = "0.84 0.71 0.5 0.349"; +}; + +new TerrainMaterial() +{ + internalName = "sand"; + diffuseMap = "art/terrains/Example/sand"; + detailMap = "art/terrains/Example/sand_d"; + detailSize = "10"; + detailDistance = "100"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "200"; + normalMap = "art/terrains/Example/sand_n"; +}; diff --git a/Templates/Empty/game/shaders/common/terrain/terrain.glsl b/Templates/Empty/game/shaders/common/terrain/terrain.glsl index 1fe7a483e..414c5de24 100644 --- a/Templates/Empty/game/shaders/common/terrain/terrain.glsl +++ b/Templates/Empty/game/shaders/common/terrain/terrain.glsl @@ -32,10 +32,12 @@ float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 ); float noBlend = float(any( bvec4(1 - diff) )); - // Use step to see if any of the layer samples // match the current texture id. - vec4 factors = step( texId, layerSample ); - + vec4 factors = vec4(0); + for(int i = 0; i < 4; i++) + if(layerSample[i] == texId) + factors[i] = 1; + // This is a custom bilinear filter. vec2 uv = layerCoord * layerSize; diff --git a/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui index 8cdba481d..6d42ed834 100644 --- a/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui +++ b/Templates/Empty/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui @@ -210,7 +210,7 @@ new GuiBitmapCtrl() { Enabled = "1"; Profile = "ToolsGuiDefaultProfile"; - position = "270 3"; + position = "250 3"; Extent = "2 26"; MinExtent = "1 1"; bitmap = "tools/gui/images/separator-h.png"; @@ -222,7 +222,7 @@ Profile = "ToolsGuiDefaultProfile"; HorizSizing = "right"; VertSizing = "bottom"; - Position = "262 5"; + Position = "242 5"; Extent = "256 50"; MinExtent = "8 2"; canSave = "1"; @@ -370,7 +370,7 @@ new GuiBitmapCtrl() { Enabled = "1"; Profile = "ToolsGuiDefaultProfile"; - position = "525 3"; + position = "495 3"; Extent = "2 26"; MinExtent = "1 1"; bitmap = "tools/gui/images/separator-h.png"; @@ -382,7 +382,7 @@ Profile = "ToolsGuiTransparentProfile"; HorizSizing = "right"; VertSizing = "bottom"; - position = "540 5"; + position = "510 5"; Extent = "120 50"; MinExtent = "8 2"; canSave = "1"; @@ -454,6 +454,53 @@ bitmap = "tools/gui/images/dropslider"; }; }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "618 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(LerpBlendCheckButtonContainer,EditorGuiGroup) { + position = "628 5"; + extent = "70 50"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTransparentProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + text = " LerpBlend"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "0 2"; + extent = "140 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + command = "ETerrainEditor.toggleBlendType($ThisControl);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "LerpBlendCheckBox"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; }; }; //--- OBJECT WRITE END --- @@ -634,4 +681,3 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) { value = "0"; }; }; - diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui index 547dab6fa..47fdb1952 100644 --- a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui +++ b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -20,8 +20,8 @@ HorizSizing = "center"; VertSizing = "center"; position = "221 151"; - Extent = "394 432"; - MinExtent = "358 432"; + Extent = "394 452"; + MinExtent = "358 452"; canSave = "1"; Visible = "1"; tooltipprofile = "ToolsGuiToolTipProfile"; @@ -106,7 +106,7 @@ HorizSizing = "left"; VertSizing = "height"; position = "202 26"; - Extent = "185 363"; + Extent = "185 383"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -439,7 +439,7 @@ HorizSizing = "width"; VertSizing = "bottom"; position = "6 295"; - Extent = "185 50"; + Extent = "185 80"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -621,6 +621,78 @@ sinkAllKeyEvents = "0"; passwordMask = "*"; }; + new GuiSliderCtrl(TerrainMaterialDlgBlendDepthSlider) { + range = "0.01 0.99"; + ticks = "0"; + snap = "0"; + value = "0.5"; + position = "39 61"; + extent = "70 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "blendDepthSliderCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Blend Depth"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "115 61"; + extent = "58 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(TerrainMaterialDlgBlendDepthTextEdit) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0.3"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "1 59"; + extent = "35 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "blendDepthTextEditCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; new GuiBitmapCtrl() { @@ -1260,7 +1332,7 @@ HorizSizing = "width"; VertSizing = "height"; position = "6 42"; - Extent = "189 373"; + Extent = "189 393"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -1274,7 +1346,7 @@ HorizSizing = "width"; VertSizing = "height"; position = "0 0"; - Extent = "189 374"; + Extent = "189 394"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -1333,7 +1405,7 @@ Profile = "ToolsGuiButtonProfile"; HorizSizing = "left"; VertSizing = "top"; - position = "202 394"; + position = "202 414"; Extent = "98 22"; MinExtent = "8 2"; canSave = "1"; @@ -1352,7 +1424,7 @@ Profile = "ToolsGuiButtonProfile"; HorizSizing = "left"; VertSizing = "top"; - position = "307 394"; + position = "307 414"; Extent = "80 22"; MinExtent = "8 2"; canSave = "1"; @@ -1372,7 +1444,7 @@ HorizSizing = "left"; VertSizing = "height"; position = "199 23"; - Extent = "190 267"; + Extent = "190 287"; isContainer = true; Visible = false; bitmap = "tools/gui/images/inactive-overlay"; @@ -1389,4 +1461,4 @@ }; }; }; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs index 63d185541..131ca4acd 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs @@ -222,6 +222,8 @@ function EPainter::setup( %this, %matIndex ) ETerrainEditor.setAction( ETerrainEditor.currentAction ); EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc); ETerrainEditor.renderVertexSelection = true; + + EWTerrainPainterToolbar-->LerpBlendCheckBox.setValue($Pref::Terrain::LerpBlend); } function onNeedRelight() @@ -257,6 +259,11 @@ function TerrainEditor::toggleBrushType( %this, %brush ) %this.setBrushType( %brush.internalName ); } +function TerrainEditor::toggleBlendType( %this, %check ) +{ + $Pref::Terrain::LerpBlend = %check.getValue(); +} + function TerrainEditor::offsetBrush(%this, %x, %y) { %curPos = %this.getBrushPos(); diff --git a/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs index a83ddfb8a..29d8b1474 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs @@ -401,6 +401,9 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) %this-->detDistanceCtrl.setText( %mat.detailDistance ); %this-->sideProjectionCtrl.setValue( %mat.useSideProjection ); %this-->parallaxScaleCtrl.setText( %mat.parallaxScale ); + %blendDepth = mFloor(%mat.blendDepth * 1000)/1000; + %this-->blendDepthTextEditCtrl.setText( %blendDepth ); + %this-->blendDepthSliderCtrl.setValue( %mat.blendDepth ); %this-->macroSizeCtrl.setText( %mat.macroSize ); %this-->macroStrengthCtrl.setText( %mat.macroStrength ); @@ -454,6 +457,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %detailDistance = %this-->detDistanceCtrl.getText(); %useSideProjection = %this-->sideProjectionCtrl.getValue(); %parallaxScale = %this-->parallaxScaleCtrl.getText(); + %blendDepth = %this-->blendDepthTextEditCtrl.getText(); %macroSize = %this-->macroSizeCtrl.getText(); %macroStrength = %this-->macroStrengthCtrl.getText(); @@ -475,7 +479,8 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.macroSize == %macroSize && %mat.macroStrength == %macroStrength && %mat.macroDistance == %macroDistance && - %mat.parallaxScale == %parallaxScale ) + %mat.parallaxScale == %parallaxScale && + %mat.blendDepth == %blendDepth) return; // Make sure the material name is unique. @@ -509,6 +514,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.macroDistance = %macroDistance; %mat.useSideProjection = %useSideProjection; %mat.parallaxScale = %parallaxScale; + %mat.blendDepth = %blendDepth; // Mark the material as dirty and needing saving. @@ -554,6 +560,7 @@ function TerrainMaterialDlg::snapshotMaterials( %this ) macroDistance = %mat.macroDistance; useSideProjection = %mat.useSideProjection; parallaxScale = %mat.parallaxScale; + blendDepth = %mat.blendDepth; }; } } @@ -588,6 +595,7 @@ function TerrainMaterialDlg::restoreMaterials( %this ) %mat.macroDistance = %obj.macroDistance; %mat.useSideProjection = %obj.useSideProjection; %mat.parallaxScale = %obj.parallaxScale; + %mat.blendDepth = %obj.blendDepth; } } @@ -623,3 +631,17 @@ function TerrainMaterialDlg::_selectTextureFileDialog( %this, %defaultFileName ) return %file; } + +function TerrainMaterialDlgBlendDepthSlider::onMouseDragged(%this) +{ + %value = mFloor(%this.value * 1000)/1000; + TerrainMaterialDlgBlendDepthTextEdit.setText(%value); + TerrainMaterialDlg.activeMat.blendDepth = %this.value; + +} + +function TerrainMaterialDlgBlendDepthTextEdit::onValidate(%this) +{ + TerrainMaterialDlgBlendDepthSlider.setValue(%this.getText()); + TerrainMaterialDlg.activeMat.blendDepth = %this.getText(); +} \ No newline at end of file diff --git a/Templates/Full/game/art/terrains/Example/dirt_grass_n.png b/Templates/Full/game/art/terrains/Example/dirt_grass_n.png new file mode 100644 index 000000000..ba68973d6 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/dirt_grass_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/grass1_dry_n.png b/Templates/Full/game/art/terrains/Example/grass1_dry_n.png new file mode 100644 index 000000000..c6bd8d748 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/grass1_dry_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/grass1_n.png b/Templates/Full/game/art/terrains/Example/grass1_n.png new file mode 100644 index 000000000..2e355dbf2 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/grass1_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/grass2_n.png b/Templates/Full/game/art/terrains/Example/grass2_n.png new file mode 100644 index 000000000..1dbb11b2b Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/grass2_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/road_n.png b/Templates/Full/game/art/terrains/Example/road_n.png new file mode 100644 index 000000000..7ddfa28b0 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/road_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/rocks1_n.png b/Templates/Full/game/art/terrains/Example/rocks1_n.png new file mode 100644 index 000000000..3fcbd446c Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/rocks1_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/rocktest_n.png b/Templates/Full/game/art/terrains/Example/rocktest_n.png new file mode 100644 index 000000000..99b51d5c6 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/rocktest_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/sand_n.png b/Templates/Full/game/art/terrains/Example/sand_n.png new file mode 100644 index 000000000..8be0de18b Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/sand_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/snowtop_n.png b/Templates/Full/game/art/terrains/Example/snowtop_n.png new file mode 100644 index 000000000..d299b5fd0 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/snowtop_n.png differ diff --git a/Templates/Full/game/art/terrains/Example/stone_n.png b/Templates/Full/game/art/terrains/Example/stone_n.png new file mode 100644 index 000000000..7a924e241 Binary files /dev/null and b/Templates/Full/game/art/terrains/Example/stone_n.png differ diff --git a/Templates/Full/game/art/terrains/materials.cs b/Templates/Full/game/art/terrains/materials.cs index c13ab564f..ac7b59b35 100644 --- a/Templates/Full/game/art/terrains/materials.cs +++ b/Templates/Full/game/art/terrains/materials.cs @@ -47,6 +47,8 @@ new TerrainMaterial() detailBrightness = "1"; Enabled = "1"; diffuseSize = "200"; + normalMap = "art/terrains/Example/grass1_n"; + detailDistance = "1000"; }; singleton Material(TerrainFX_grass2) @@ -97,6 +99,7 @@ new TerrainMaterial() Enabled = "1"; diffuseSize = "250"; detailStrength = "2"; + normalMap = "art/terrains/Example/grass1_dry_n"; }; singleton Material(TerrainFX_dirt_grass) @@ -108,6 +111,15 @@ singleton Material(TerrainFX_dirt_grass) showFootprints = "1"; materialTag0 = "Terrain"; effectColor[0] = "0.63 0.55 0 1"; + diffuseMap = "art/terrains/Example/dirt_grass"; + diffuseSize = "200"; + normalMap = "art/terrains/Example/dirt_grass_n"; + detailMap = "art/terrains/Example/dirt_grass_d"; + detailDistance = "100"; + internalName = "dirt_grass"; + isManaged = "1"; + detailBrightness = "1"; + enabled = "1"; }; new TerrainMaterial() @@ -138,6 +150,16 @@ singleton Material(TerrainFX_rocktest) impactSoundId = "1"; effectColor[0] = "0.25 0.25 0.25 1"; effectColor[1] = "0.25 0.25 0.25 0"; + diffuseMap = "art/terrains/Example/rocktest"; + diffuseSize = "400"; + normalMap = "art/terrains/Example/rocktest_n"; + detailMap = "art/terrains/Example/rocktest_d"; + detailSize = "10"; + detailDistance = "100"; + internalName = "rocktest"; + isManaged = "1"; + detailBrightness = "1"; + enabled = "1"; }; new TerrainMaterial() @@ -168,6 +190,16 @@ singleton Material(TerrainFX_stone) impactSoundId = "1"; effectColor[0] = "0.25 0.25 0.25 1"; effectColor[1] = "0.25 0.25 0.25 0"; + diffuseMap = "art/terrains/Example/stone"; + diffuseSize = "400"; + normalMap = "art/terrains/Example/stone_n"; + detailMap = "art/terrains/Example/stone_d"; + detailSize = "10"; + detailDistance = "100"; + internalName = "stone"; + isManaged = "1"; + detailBrightness = "1"; + enabled = "1"; }; new TerrainMaterial() @@ -211,4 +243,5 @@ new TerrainMaterial() detailBrightness = "1"; Enabled = "1"; diffuseSize = "200"; + normalMap = "art/terrains/Example/sand_n"; }; diff --git a/Templates/Full/game/shaders/common/terrain/terrain.glsl b/Templates/Full/game/shaders/common/terrain/terrain.glsl index 1fe7a483e..414c5de24 100644 --- a/Templates/Full/game/shaders/common/terrain/terrain.glsl +++ b/Templates/Full/game/shaders/common/terrain/terrain.glsl @@ -32,10 +32,12 @@ float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 ); float noBlend = float(any( bvec4(1 - diff) )); - // Use step to see if any of the layer samples // match the current texture id. - vec4 factors = step( texId, layerSample ); - + vec4 factors = vec4(0); + for(int i = 0; i < 4; i++) + if(layerSample[i] == texId) + factors[i] = 1; + // This is a custom bilinear filter. vec2 uv = layerCoord * layerSize; diff --git a/Templates/Full/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui b/Templates/Full/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui index 8cdba481d..6d42ed834 100644 --- a/Templates/Full/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui +++ b/Templates/Full/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui @@ -210,7 +210,7 @@ new GuiBitmapCtrl() { Enabled = "1"; Profile = "ToolsGuiDefaultProfile"; - position = "270 3"; + position = "250 3"; Extent = "2 26"; MinExtent = "1 1"; bitmap = "tools/gui/images/separator-h.png"; @@ -222,7 +222,7 @@ Profile = "ToolsGuiDefaultProfile"; HorizSizing = "right"; VertSizing = "bottom"; - Position = "262 5"; + Position = "242 5"; Extent = "256 50"; MinExtent = "8 2"; canSave = "1"; @@ -370,7 +370,7 @@ new GuiBitmapCtrl() { Enabled = "1"; Profile = "ToolsGuiDefaultProfile"; - position = "525 3"; + position = "495 3"; Extent = "2 26"; MinExtent = "1 1"; bitmap = "tools/gui/images/separator-h.png"; @@ -382,7 +382,7 @@ Profile = "ToolsGuiTransparentProfile"; HorizSizing = "right"; VertSizing = "bottom"; - position = "540 5"; + position = "510 5"; Extent = "120 50"; MinExtent = "8 2"; canSave = "1"; @@ -454,6 +454,53 @@ bitmap = "tools/gui/images/dropslider"; }; }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "618 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(LerpBlendCheckButtonContainer,EditorGuiGroup) { + position = "628 5"; + extent = "70 50"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTransparentProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + text = " LerpBlend"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "0 2"; + extent = "140 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + command = "ETerrainEditor.toggleBlendType($ThisControl);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "LerpBlendCheckBox"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; }; }; //--- OBJECT WRITE END --- @@ -634,4 +681,3 @@ new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) { value = "0"; }; }; - diff --git a/Templates/Full/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/Full/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui index 547dab6fa..47fdb1952 100644 --- a/Templates/Full/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui +++ b/Templates/Full/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -20,8 +20,8 @@ HorizSizing = "center"; VertSizing = "center"; position = "221 151"; - Extent = "394 432"; - MinExtent = "358 432"; + Extent = "394 452"; + MinExtent = "358 452"; canSave = "1"; Visible = "1"; tooltipprofile = "ToolsGuiToolTipProfile"; @@ -106,7 +106,7 @@ HorizSizing = "left"; VertSizing = "height"; position = "202 26"; - Extent = "185 363"; + Extent = "185 383"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -439,7 +439,7 @@ HorizSizing = "width"; VertSizing = "bottom"; position = "6 295"; - Extent = "185 50"; + Extent = "185 80"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -621,6 +621,78 @@ sinkAllKeyEvents = "0"; passwordMask = "*"; }; + new GuiSliderCtrl(TerrainMaterialDlgBlendDepthSlider) { + range = "0.01 0.99"; + ticks = "0"; + snap = "0"; + value = "0.5"; + position = "39 61"; + extent = "70 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "blendDepthSliderCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Blend Depth"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "115 61"; + extent = "58 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(TerrainMaterialDlgBlendDepthTextEdit) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0.3"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "1 59"; + extent = "35 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "blendDepthTextEditCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; new GuiBitmapCtrl() { @@ -1260,7 +1332,7 @@ HorizSizing = "width"; VertSizing = "height"; position = "6 42"; - Extent = "189 373"; + Extent = "189 393"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -1274,7 +1346,7 @@ HorizSizing = "width"; VertSizing = "height"; position = "0 0"; - Extent = "189 374"; + Extent = "189 394"; MinExtent = "8 2"; canSave = "1"; Visible = "1"; @@ -1333,7 +1405,7 @@ Profile = "ToolsGuiButtonProfile"; HorizSizing = "left"; VertSizing = "top"; - position = "202 394"; + position = "202 414"; Extent = "98 22"; MinExtent = "8 2"; canSave = "1"; @@ -1352,7 +1424,7 @@ Profile = "ToolsGuiButtonProfile"; HorizSizing = "left"; VertSizing = "top"; - position = "307 394"; + position = "307 414"; Extent = "80 22"; MinExtent = "8 2"; canSave = "1"; @@ -1372,7 +1444,7 @@ HorizSizing = "left"; VertSizing = "height"; position = "199 23"; - Extent = "190 267"; + Extent = "190 287"; isContainer = true; Visible = false; bitmap = "tools/gui/images/inactive-overlay"; @@ -1389,4 +1461,4 @@ }; }; }; -//--- OBJECT WRITE END --- +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Full/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs index 63d185541..131ca4acd 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs @@ -222,6 +222,8 @@ function EPainter::setup( %this, %matIndex ) ETerrainEditor.setAction( ETerrainEditor.currentAction ); EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc); ETerrainEditor.renderVertexSelection = true; + + EWTerrainPainterToolbar-->LerpBlendCheckBox.setValue($Pref::Terrain::LerpBlend); } function onNeedRelight() @@ -257,6 +259,11 @@ function TerrainEditor::toggleBrushType( %this, %brush ) %this.setBrushType( %brush.internalName ); } +function TerrainEditor::toggleBlendType( %this, %check ) +{ + $Pref::Terrain::LerpBlend = %check.getValue(); +} + function TerrainEditor::offsetBrush(%this, %x, %y) { %curPos = %this.getBrushPos(); diff --git a/Templates/Full/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs index a83ddfb8a..29d8b1474 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs @@ -401,6 +401,9 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) %this-->detDistanceCtrl.setText( %mat.detailDistance ); %this-->sideProjectionCtrl.setValue( %mat.useSideProjection ); %this-->parallaxScaleCtrl.setText( %mat.parallaxScale ); + %blendDepth = mFloor(%mat.blendDepth * 1000)/1000; + %this-->blendDepthTextEditCtrl.setText( %blendDepth ); + %this-->blendDepthSliderCtrl.setValue( %mat.blendDepth ); %this-->macroSizeCtrl.setText( %mat.macroSize ); %this-->macroStrengthCtrl.setText( %mat.macroStrength ); @@ -454,6 +457,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %detailDistance = %this-->detDistanceCtrl.getText(); %useSideProjection = %this-->sideProjectionCtrl.getValue(); %parallaxScale = %this-->parallaxScaleCtrl.getText(); + %blendDepth = %this-->blendDepthTextEditCtrl.getText(); %macroSize = %this-->macroSizeCtrl.getText(); %macroStrength = %this-->macroStrengthCtrl.getText(); @@ -475,7 +479,8 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.macroSize == %macroSize && %mat.macroStrength == %macroStrength && %mat.macroDistance == %macroDistance && - %mat.parallaxScale == %parallaxScale ) + %mat.parallaxScale == %parallaxScale && + %mat.blendDepth == %blendDepth) return; // Make sure the material name is unique. @@ -509,6 +514,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.macroDistance = %macroDistance; %mat.useSideProjection = %useSideProjection; %mat.parallaxScale = %parallaxScale; + %mat.blendDepth = %blendDepth; // Mark the material as dirty and needing saving. @@ -554,6 +560,7 @@ function TerrainMaterialDlg::snapshotMaterials( %this ) macroDistance = %mat.macroDistance; useSideProjection = %mat.useSideProjection; parallaxScale = %mat.parallaxScale; + blendDepth = %mat.blendDepth; }; } } @@ -588,6 +595,7 @@ function TerrainMaterialDlg::restoreMaterials( %this ) %mat.macroDistance = %obj.macroDistance; %mat.useSideProjection = %obj.useSideProjection; %mat.parallaxScale = %obj.parallaxScale; + %mat.blendDepth = %obj.blendDepth; } } @@ -623,3 +631,17 @@ function TerrainMaterialDlg::_selectTextureFileDialog( %this, %defaultFileName ) return %file; } + +function TerrainMaterialDlgBlendDepthSlider::onMouseDragged(%this) +{ + %value = mFloor(%this.value * 1000)/1000; + TerrainMaterialDlgBlendDepthTextEdit.setText(%value); + TerrainMaterialDlg.activeMat.blendDepth = %this.value; + +} + +function TerrainMaterialDlgBlendDepthTextEdit::onValidate(%this) +{ + TerrainMaterialDlgBlendDepthSlider.setValue(%this.getText()); + TerrainMaterialDlg.activeMat.blendDepth = %this.getText(); +} \ No newline at end of file