Scaling textures by SplattingShader

Dibalo

14-06-2007 13:45:20

My current problem is caused by textures. When I use splattingShader as my TextureFormat, every textures are scaled too big when using big maps like 2k x 2k. I tried to search a bit and I found that only way to adjust the tiling is to change hard coded values in shader. My problem is this: which values do I have to change?? :? I know nothing about shaders. I have tried to adjust many variables but texture scaling is still constant.. I would be thankful if someone could advice me a bit... :)

Thank you!

Jon

14-06-2007 16:29:48

I'm curious as to what the real answer is. In my shader I scale the UV coords (allowing them to wrap).

Look for the tex2d, and multiply the coordinates passed into it by some value.

Paulo

14-06-2007 16:43:20

This is from SplatShader.cg

// Vertex program for automatic terrain texture generation
void main_vp
(
float4 iPosition : POSITION,
float2 iTexcoord : TEXCOORD0,

out float4 oPosition : POSITION,
out float2 oCoverage : TEXCOORD0,
out float2 oScaled0 : TEXCOORD1,
out float2 oScaled1 : TEXCOORD2,
out float2 oScaled2 : TEXCOORD3,
out float2 oScaled3 : TEXCOORD4,

uniform float4x4 worldViewProj,
uniform float4 lightDirection,
uniform float4 ambientLight,

uniform float4 fogSettings,
uniform float4 fogColour
)
{
// Transform the current vertex from object space to clip space, since OpenGL isn't doing it for us
// as long we're using a vertex shader
oPosition = mul(worldViewProj, iPosition);

//float fog = saturate(( oPosition.z - fogSettings[0] ) / (fogSettings[1] - fogSettings[0])) * fogSettings[2];
//oFog = fogColour * fog;

oCoverage = iTexcoord;
oScaled0 = oCoverage*20.0f; <--------- CHANGE THE 20.0f as required
oScaled1 = oScaled0;
oScaled2 = oScaled0;
oScaled3 = oScaled0;
}

Dibalo

15-06-2007 09:25:41

Strange.. I sure changed that value in the beginning but nothing happened... Hmmmm... Maybe I´ll test it again... :shock:

bleubleu

20-07-2007 15:01:10

Hi!

It's an old post, but if you want to change the scale of the splatting shader dynamically, you can add a new a new uniform parameter to the Cg fragment shader. Let's call it "scales".


void main_vp
(
float4 iPosition : POSITION,
float2 iTexcoord : TEXCOORD0,

out float4 oPosition : POSITION,
out float2 oCoverage : TEXCOORD0,
out float2 oScaled0 : TEXCOORD1,
out float2 oScaled1 : TEXCOORD2,
out float2 oScaled2 : TEXCOORD3,
out float2 oScaled3 : TEXCOORD4,

uniform float4x4 worldViewProj,
uniform float4 lightDirection,
uniform float4 ambientLight,

uniform float4 fogSettings,
uniform float4 fogColour,

uniform float4 scales
)
{
// Transform the current vertex from object space to clip space, since OpenGL isn't doing it for us
// as long we're using a vertex shader
oPosition = mul(worldViewProj, iPosition);

//float fog = saturate(( oPosition.z - fogSettings[0] ) / (fogSettings[1] - fogSettings[0])) * fogSettings[2];
//oFog = fogColour * fog;

oCoverage = iTexcoord;
oScaled0 = iTexcoord * scales.x;
oScaled1 = iTexcoord * scales.y;
oScaled2 = iTexcoord * scales.z;
oScaled3 = iTexcoord * scales.w;
}


Then in your code, you can set the scales by directly modifying the tile materials. The code is in C# with Mogre, but you should be able to convert it in 2 minutes. (m_sm is my scene manager).


public void SetSplattingScale(uint px, uint py, Vector4 scales)
{
string map;
string format;

m_sm.GetOption("CurrentMap", out map);
m_sm.GetOption("CurrentTextureFormat", out format);

string matName = format + "." + px + "." + py + "." + map;

MaterialPtr mat = MaterialManager.Singleton.GetByName(matName);

if (mat != null)
mat.GetTechnique(0).GetPass(0).GetVertexProgramParameters(
).SetNamedConstant("scales", scales); ;
}

public void SetSplattingScales(Vector4 scales)
{
int w, h;

m_sm.GetOption("Width", out w);
m_sm.GetOption("Height", out h);

for (uint i = 0; i < w; i++)
for (uint j = 0; j < h; j++)
SetSplattingScale(i, j, scales);
}


This will work in real time so you can even changeg the scales from frame to frame.

Dont forget, you have to wait until a page is loaded to set the scales otherwise the material will not be loaded or will not exist. The best is to register to add a tile load listener and do it in the callback function.

You could also use something like the "getMaterialPageName" option to retrieve the material names instead of rebuilding it. Probably safer for future versions.

Have fun!

Mat