Jump to content
  • Advertisement
Sign in to follow this  
Shael

Questions on Terrain Rendering

This topic is 3431 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Heya Is it wise to scale the terrain vertices? or if creating a 256x256 heightmap it should stay that size? I thought maybe scaling it could create the illusion of a larger terrain but I'm thinking perhaps its better to leave the scale 1:1. In regards to texturing how do most people implement splatting? I'm creating a world editor and I want to be able to have different forms of "brushes" that the user can use to paint the terrain with. My initial thoughts was to have a base texture which is stretched over the terrain and an mask texture also stretched over. The user would then paint on this mask using the brushes. There would be a max of 4 splat layers and each layers weighting/influence corresponds to an RGBA channel in the mask. That's all well and good but it looks crap because it is stretched over the whole terrain, and because each layer uses only one channel the layers can't have proper alpha blending, only solid colours to determine where the layer has influence. Whats the general consensus on these topics? Cheers!

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Shael
Is it wise to scale the terrain vertices? or if creating a 256x256 heightmap it should stay that size? I thought maybe scaling it could create the illusion of a larger terrain but I'm thinking perhaps its better to leave the scale 1:1.
You mean a 256 pixel heightmap should cover 256 units in the game world?

How big is "1 unit" in your game?
In some engines it's an inch, some it's a centimetre, some it's a metre...

Share this post


Link to post
Share on other sites
The size of your heightmap has nothing to do with the 'physical' size of your terrain - except that you usually need a higher resolution heightmap for large terrains. But again, this only applies if you need to view the terrain 'close'.

It's perfectly up to you to decide if one pixel should translate into 1.0u, 0.1u or even 100.0u - in your 3D world.
It makes no difference whether you scale your terrain up, or scale everything else down.
I typically work with 1:1 scale with meters though.

If your textures look bad when stretched over the entire terrain, then you either need to make your texture higher resolution, or use several textures for the terrain.
I don't see why you can't have proper alpha blending though. You should have 8 bits for each channel, which should do just fine. Or am I missing your point?
I assume you're using a pixel shader for this?

Share this post


Link to post
Share on other sites
Yes, it can be 512x512 or higher. I was just using 256 as an example.

I thought that having it 1:1 would mean less stretching on the texture because if the texture was the same size as the terrain it would map exactly pixel to pixel. I'd be working in metres also, so I guess if I were to go 1:1 then 1 pixel would be 1 meter? and I'd just have to scale down all the velocities, etc to match.

I am using a pixel shader for this and I just realised I can simply tile the splats instead of stretching them too which gives more detail for the splats.

There is 8 bits per channel but for some reason if I paint on my mask in photoshop with a red brush with say 50% opacity, then the splat assigned to the red channel shows on the terrain as if i painted with 100% solid colour. It has no fade out or anything, every pixel which had some transparency in photoshop, shows up solid on the terrain.

Cheers!

Share this post


Link to post
Share on other sites
Shael - are you using blending or alpha-testing to display your masked textures.

Alpha testing is simply on/off based on a threshold value whereas blending will give you the gradual 'everything in between' look you are after.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shael
I thought that having it 1:1 would mean less stretching on the texture because if the texture was the same size as the terrain it would map exactly pixel to pixel.
You convert your height-map pixels to vertexes though, and then groups of vertices create lots of pixels on the screen. So if you stretch a 256 texture over a 256 height-map, you've got 1 pixel : 1 vertex ;)
And if your verts are spaced apart by 1 metre, then that's a resolution of 1 pixel per meter.
Quote:
I am using a pixel shader for this and I just realised I can simply tile the splats instead of stretching them too which gives more detail for the splats.
Yeah, you should stretch your "splat selection" texture, then tile the actual textures. 1px/meter should be ok for the selection one, but is bad for the detailed ones.
Quote:
for some reason if I paint on my mask in photoshop with a red brush with say 50% opacity, then the splat assigned to the red channel shows on the terrain as if i painted with 100% solid colour. It has no fade out or anything
We can help you debug your shader if you like.

Share this post


Link to post
Share on other sites
Sounds like a plan :)

This is what it looks like when rendered, as you can see its blocky and not transparent.. the base texture should be fading through:

http://illusionaldesign.net/terrain.jpg

And this is the mask:

http://illusionaldesign.net/mask1.png

Theres some other problems Im seeing too which is the base texture only draws if there is black painted on the mask, and whatever is left transparent in the mask is display as the last splat texture, which in this case is the snow.


shared float4x4 g_mWorldViewProj : WORLD_VIEW_PROJ;

texture BaseTex;
texture MaskTex;
texture Splat1;
texture Splat2;
texture Splat3;
texture Splat4;

sampler BaseSampler = sampler_state
{
Texture = (BaseTex);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

sampler MaskSampler = sampler_state
{
Texture = (MaskTex);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

sampler RSampler = sampler_state
{
Texture = (Splat1);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

sampler GSampler = sampler_state
{
Texture = (Splat2);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

sampler BSampler = sampler_state
{
Texture = (Splat3);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

sampler ASampler = sampler_state
{
Texture = (Splat4);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};


struct VS_INPUT
{
float4 Position : POSITION0;
float2 TexCoord0 : TEXCOORD0;
};

struct PS_INPUT
{
float4 Color : COLOR0;
};


VS_INPUT TerrainVS (VS_INPUT In)
{
VS_INPUT Out;

Out.Position = mul(In.Position, g_mWorldViewProj);
Out.TexCoord0 = In.TexCoord0;

return Out;
}

PS_INPUT TerrainSimplePS (VS_INPUT In)
{
PS_INPUT Out;

Out.Color = tex2D(BaseSampler, In.TexCoord0);

return Out;
}

PS_INPUT TerrainSplatPS (VS_INPUT In)
{
PS_INPUT Out;

vector blender = tex2D(MaskSampler, In.TexCoord0);

float RWeight = blender.r;
float GWeight = blender.g;
float BWeight = blender.b;
float AWeight = blender.a;

vector BaseColour = tex2D(BaseSampler, In.TexCoord0);
vector RColour = tex2D(RSampler, In.TexCoord0 * 4);
vector GColour = tex2D(GSampler, In.TexCoord0 * 4);
vector BColour = tex2D(BSampler, In.TexCoord0 * 4);
vector AColour = tex2D(ASampler, In.TexCoord0 * 4);

// combine texel colors
float4 oneminusr = 1.0 - RWeight;
float4 oneminusg = 1.0 - GWeight;
float4 oneminusb = 1.0 - BWeight;

vector l = RWeight * RColour + oneminusr * BaseColour;
vector m = GWeight * GColour + oneminusg * l;
vector n = BWeight * BColour + oneminusb * m;

Out.Color = n;

return Out;
}


//--------------------------------------------------------------------------------------
// Techniques
//--------------------------------------------------------------------------------------
technique TerrainSimple
{
pass pass0
{
VertexShader = compile vs_2_0 TerrainVS();
PixelShader = compile ps_2_0 TerrainSimplePS();
}
}

technique TerrainSplat
{
pass pass0
{
VertexShader = compile vs_2_0 TerrainVS();
PixelShader = compile ps_2_0 TerrainSplatPS();
}
}

Share this post


Link to post
Share on other sites
Try to following in your pixel shader, assuming you want the base texture to fade through everything. (Note: Un-tested, but should be correct)

PS_INPUT Out;
{
float4 texWeights = tex2D(MaskSampler, In.TexCoord0);
float totalWeight = 1 + texWeights.x + texWeights.y + texWeights.z + texWeights.w;
texWeights /= totalWeight;

float4 BaseColour = tex2D(BaseSampler, In.TexCoord0);
float4 RColour = tex2D(RSampler, In.TexCoord0 * 4);
float4 GColour = tex2D(GSampler, In.TexCoord0 * 4);
float4 BColour = tex2D(BSampler, In.TexCoord0 * 4);
float4 AColour = tex2D(ASampler, In.TexCoord0 * 4);

// combine texel colors
BaseColour = BaseColour * (1.0f / totalWeight) + RColour * texWeights.x + GColour * texWeights.y + BColour * texWeights.z + AColour * texWeights.w;

Out.Color = BaseColour;

return Out;
}

Share this post


Link to post
Share on other sites
Alrighty I tried what you suggested and this was the result:

http://illusionaldesign.net/terrain2.jpg

Still doesn't seem quite right and the edges still don't blend, its all blocky no fading.

Hmm.. other ideas?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!