Urho3D Wiki
Advertisement

Customize materials per code & different materials per model

Normally you assign materials like this:

StaticModel* boxObject=boxNode_->CreateComponent<StaticModel>();
boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));

You can also load materials, copy them, and/or change parameters:

Material* mat1=cache->GetResource<Material>("Materials/Stone.xml");
auto mat2=mat1->Clone();    // copy material
// change the ciffuse color
mat2->SetShaderParameter("MatDiffColor",Color(0.1,0.4,0.9));
boxObject->SetMaterial(mat2);

You can use this to make every model unique by randomizing colors or color models in a team color. You can also pass custom parameters to control things like current weather or different (localized) lighting scenes.

An example of 400 uniquely colored cubes:

Copy material

Expand default terrain material to 4 textures using alpha channel

Add another texture to the terrain material "Data/Materials/Terrain.xml" like:

<material>
<technique name="Techniques/TerrainBlend.xml" />
<texture unit="0" name="Textures/TerrainWeights.png" />
<texture unit="1" name="Textures/TerrainDetail1.dds" />
<texture unit="2" name="Textures/TerrainDetail2.dds" />
<texture unit="3" name="Textures/TerrainDetail3.dds" />
<texture unit="4" name="Textures/StoneDiffuse.dds" />
<parameter name="MatSpecColor" value="0.5 0.5 0.5 16" />
<parameter name="DetailTiling" value="16 16" />
</material>

For OpenGL: Change the "CoreData/Shaders/GLSL/TerrainBlend.glsl" to additionally use the alpha channel:

...
uniform sampler2D sWeightMap0;
uniform sampler2D sDetailMap1;
uniform sampler2D sDetailMap2;
uniform sampler2D sDetailMap3;
uniform sampler2D sDetailMap4; // <- added ... void PS()
{
// Get material diffuse albedo
vec4 weights = texture2D(sWeightMap0, vTexCoord).rgba; // <- changed
weights.a=1.0-weights.a; // <- added. Alpha should be weight in reverse (easier editing) // with 0 (fully transparent) being full weight.
float sumWeights = weights.r + weights.g + weights.b + weights.a; // <- changed
weights /= sumWeights;
vec4 diffColor = cMatDiffColor * (
weights.r * texture2D(sDetailMap1, vDetailTexCoord) +
weights.g * texture2D(sDetailMap2, vDetailTexCoord) +
weights.b * texture2D(sDetailMap3, vDetailTexCoord) + // <- changed
weights.a * texture2D(sDetailMap4, vDetailTexCoord) // <- added
); ...

If you want to use DirectX, also change the HLSL accordingly.

Use another splatting image (watch out for high red/green/blue values inside the alpha, it should be black with high alpha). My texture weight image and the result look like this:

Rgba terrain
Advertisement