Sand and grass mixing.

Nice.

So does a tool make that texture for you?

That is the bit I struggle with the most... scattering UVW's is probably the easiest bit, as said, with manual control built in where you need it :D

That said, being able to do it over a low density mesh is nice!

Dave
 
Hmm. I think this is the right way to create an index texture. This one's for a 4x4 tiling like the flowers texture (two edge types).
http://dl.dropbox.com/u/20733494/wangindex.ppm
I'm not 100% sure I have the y axis correct because they weren't entirely specific in the chapter. Could take a vertical mirror to correct.
Code written in R cause I'm more familiar with it... I can generate more like it fairly easily if it's correct.

I guess once I have the shader implemented, I'll see if it works right... :p


Edit: Modified texture so I could see what was happening. Numbered from the bottom left (0) across, then the next row up, and so on, to 15.
bnjuE.jpg


The column scramble is working, anyway - you can see it goes fairly randomly. But row scramble, not so great (thus 12-15 are pretty much all in the same row, as are 8-11, 4-7, 0-3). I believe this is due to a bug in my index texture, cause when I use the x-coord both ways, it looks much more scrambled.

I'm also having trouble with
mode=linear
Within the track.shd. The .tga has only 4 brightnesses: 0%, 33%, 66%, 100%. And yet this is producing weird in between results...

& number free result, which looks more random since the tiles aren't all marked:
yKJvu.jpg


Wow I think that looks pretty good Stereo. Thanks for testing. What does the shader cg lok like?


Nice.

So does a tool make that texture for you?

That is the bit I struggle with the most... scattering UVW's is probably the easiest bit, as said, with manual control built in where you need it :D

That said, being able to do it over a low density mesh is nice!

Dave

Yes the matlab script tiles.m did it all. And Octave was, in this case, a drop-in replacement for matlab. I simply re-compiled the mex files with mkoctfile
 
Nice.

So does a tool make that texture for you?

I think the MATLAB script is supposed to, haven't tried it out yet to see how it performs.

I think it'll be a big help on high quality textures, where you can actually see details - the Carlswood default grass looks ok because it's basically just a noisy green texture, there's nothing like actual plants on it.



My shader work is very messy atm cause I've been struggling with passing the index file in correctly. Either Racer is compressing it or I have the settings way off.

Basically you need to give it another texture input. Apparently texRECT doesn't currently work (always returns 0) so I had to kludge it a little. Way too many constants in there for now.
Code:
 // stick this line up near the baseMap
uniform sampler2D indexMap : TEXUNIT1,


 // this is where the modifications go.  Making this the wang tiling version of standard.
  // number of output tiles (what does this mean?)
// should replace one of these with scale input
  float2 mappingScale1 = float2((1.0f/8.0f),(1.0f/8.0f));
  float2 mappingScale2 = float2((128.0f),(128.0f));
  float2 mappingAddress = IN.tc0 * mappingScale1;
  float4 whichTile = tex2D(indexMap, float2(0.5f,0.5f)/mappingScale2 + floor(mappingAddress*mappingScale2)/mappingScale2);
  whichTile = floor(whichTile*float4(3.0f,3.0f,3.0f,1.0f) + 0.25f)/4.0f;
  // number of input tiles (should be 4?)
  float2 tileScale = float2(4,4);
  // get correct mipmapping?
  float2 tileScaledTex = IN.tc0 * float2(4/4,4/4);
  float4 baseCol=tex2D(baseMap,whichTile.rg + frac(mappingAddress)*float2(32,32), ddx(tileScaledTex),ddy(tileScaledTex));
  
  // this all replaces the following line:
  //baseCol=tex2D(baseMap,IN.tc0);
Just replace baseCol=tex2D(baseMap,IN.tc0) with code as above (except first line, which goes in the header)

Right now, I only know it works on
- texture: 512x512, 16 tiles (arranged 4x4) -> this goes in layer0
- index: 128x128, red/green channels in use -> this goes in layer1, with mode=linear enabled
 
Go, go Stereo! I've been stalled on account of my frustrations with trying to make tile-able grass that didn't have that readily perceptible grid-look to it.

Here is a link to Mr. Wei's paper. It looks like a more or less refined version of the GPU Gems 2 chapter.
 
Hmm. I think this is the right way to create an index texture. This one's for a 4x4 tiling like the flowers texture (two edge types).
http://dl.dropbox.com/u/20733494/wangindex.ppm
I'm not 100% sure I have the y axis correct because they weren't entirely specific in the chapter. Could take a vertical mirror to correct.
Code written in R cause I'm more familiar with it... I can generate more like it fairly easily if it's correct.
----------8<---------------------

Stereo,
Will you please elaborate on the creation of the index texture? I've read the Ken Perlin material including the "Improving Noise" paper and Demo
referenced in the "Tile-Based Texture Mapping on Graphics Hardware" paper but my background is lacking. You made a reference to coding something in R. Is the index creation then a procedural thing?

Basically you need to give it another texture input. Apparently texRECT doesn't currently work (always returns 0) so I had to kludge it a little. Way too many constants in there for now.

An issue of texture binding? ..GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D..
 
To create the index texture, I generate random matrices of edge types (0 or 1). Then I use the code as described in GPUGems2 to convert each pair of edges (left/right, or top/bottom) into an index offset, and write those to the texture in red/green. R is just the programming language I'm most comfortable doing this in (particularly texture writes).

With the red and blue channels not working for this purpose though, I may have to find an alternative there in order to get everything functional. Either do it in green/alpha, if possible, or maybe do it in green channel on 2 textures? That would just be to demonstrate that the technique works, though.



Texture binding issue seems right. I don't think in writing the shader I have the option to modify those, so it'd have to wait for a new Racer version that supports loading textures that way (gl_texture_rectangle, gl_nearest).
 
Code:
 // stick this line up near the baseMap
uniform sampler2D indexMap : TEXUNIT1,


  // this is where the modifications go.  Making this the wang tiling version of standard.
  // number of output tiles (what does this mean?)
  // should replace one of these with scale input
  float2 mappingScale1 = float2((1.0f/8.0f),(1.0f/8.0f));
  float2 mappingScale2 = float2((128.0f),(128.0f));
  float2 mappingAddress = IN.tc0 * mappingScale1;
  float4 whichTile = tex2D(indexMap, float2(0.5f,0.5f)/mappingScale2 +    floor(mappingAddress*mappingScale2)/mappingScale2);
  whichTile = floor(whichTile*float4(3.0f,3.0f,3.0f,1.0f) + 0.25f)/4.0f;
  // number of input tiles (should be 4?)
  float2 tileScale = float2(4,4);
  // get correct mipmapping?
  float2 tileScaledTex = IN.tc0 * float2(4/4,4/4);
  float4 baseCol=tex2D(baseMap,whichTile.rg + frac(mappingAddress)*float2(32,32), ddx(tileScaledTex),ddy(tileScaledTex));
  
  // this all replaces the following line:
  //baseCol=tex2D(baseMap,IN.tc0);

Thx Stereo for providing some testing code, I'm actually experiencing some 'profile issue' when testing your Cg work ; apparently my GPU doesn't support the Cg texture function, hmm :

tex2D(sampler2D tex , float2 s , float2 dsdx , float2 dsdy )
2D nonprojective texture query with derivatives
http://http.developer.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html

Sure, needs some more code to be fully functional...
 
Yeah, you could drop the dsdx and dsdy from that, I only copied them across cause the original used them. I wish GPU profiles were a lot more consistent in the code they can run...

Code:
float4 baseCol=tex2D(baseMap,whichTile.rg + frac(mappingAddress)*float2(32,32));
 
Stereo/radome, I was thinking yesterday, to avoid that headache with the edge 'detecting' color code for now, why not just 'randomly' position the tiles on the map...As you might know, taking a simple texture & process it thru PS (Photoshop) 'Texturizer' filter in both X/Y directions, you get a good start to mix the tiles....

It could be useful, to texture brick walls for example, still for terrain that wouldn't look good...maybe for paving stone.
 
Can u draw me a diagram of how the wang tile is laid out in your examle? I don't quite follow how the edges work. I've had a go at making a grass wang tile, but wasn't that successful
 
In line with the tutorial you linked, I believe the tiles are laid out like this. It has twice as many tiles as that tutorial to fit them on a square map, but they're generated in much the same way - I suppose it just adds the 8 3-colour tiles to the 4 2-colour (B, C, F, G) and 4 4-colour (A, D, E, H).
wangtut.png
 
Thankyou, I get it now.
I made some bricks:
screenshot001.jpg

If anyone wants the wangtile get it from here
Because the bricks aren't square, I modified wangtile_f.cg line 80 from
float2 mappingScale1 = float2(1.0f,1.0f)/scale;
to
float2 mappingScale1 = float2(1.0f,2.0f)/scale;
so it makes the bricks 2/1 width vs height
(it'd be good if we could feed it a scale and aspect ratio values, then it'd be near perfect)
Now, how would you add bumpmapping to it?
 
The other thing that's easy enough to change is to make it use UV mapping. I just had it on global coords cause Carlswood's mapped kinda badly in a lot of places.
Code:
float2 mappingAddress = IN.tc0 * mappingScale1;
On carlswood this makes it about 20 times larger so scale= has to be reduced in the .shd.

The bricks look good though, nice not seeing that repetition that's so common.

Writing a bumpmap version... hrm. I'll take a look at standard_bump sometime. Not sure when.
 
I chose bricks to play aroud with first cause it was easy to make the edges tile, well I cheated they actually ALL have the same tiled cement edges, only the actual bricks vary.
Grass is another matter entirely...

While I do agree with Mr Whippy to some extent, breaking in detail or using decals has its place, this wang tiling ALSO has a lot of valid uses. Great for adding variation to different large surfaces that don't justify lots extra poly's, like roofing, tin & iron surfaces, grass, dirt, cement & concrete. Anything where tiling is needed but tiling seams aren't.
If I get time & come up with something that bumpmaps as well I'll post it.
 
Well I guess I may as well post the method I'm using in here...

Basically it's good for terrain use (can't do bricks like David posted).
You have 4 or so different textures:
A Blendmask (this is the main guts of the thing, a whole heap of stuff goes into it)
Grass
Grass > Dirt
Dirt
Tarmac/Gravel
Aerial Photo

There is a version where you can add in the fifth and sixth texture but currently I have no need for that (and it requires depth in the shader which I can't be bothered figuring out how to implement) so I'm not using them.

blendmask_f.cg
(in a subdirectory of the track folder)
Code:
#include "../../../renderer/shaders/atmosphere.cg"
#include "../../../renderer/shaders/lighting.cg"
#include "../../../renderer/shaders/shadowmapping.cg"
 
// Vertex to pixel shader structure
struct v2p
{
  float4 Position      : TEXCOORD4; //POSITION;
  float3 normal        : TEXCOORD5;
  float3 RayleighColor: TEXCOORD2;
  float3 MieColor      : TEXCOORD3;
  float2 tc0            : TEXCOORD0;
  float3 Direction      : TEXCOORD1;
  float  extinction    : TEXCOORD6;
  float2 color        : COLOR;
  //float2 vpos          : VPOS;
};
 
void main(
 
  // In
  in v2p IN,
 
  // Out
  out float4 outColor  : COLOR0,
#ifdef CSM_MRT
  out float4 outShadow  : COLOR1,
#endif
 
  // Constants
  uniform sampler2D baseMap : TEXUNIT0,
  uniform sampler2D Mapa : TEXUNIT1,
  uniform sampler2D Mapb : TEXUNIT2,
  uniform sampler2D Mapc : TEXUNIT3,
  uniform sampler2D Mapd : TEXUNIT4,
  uniform float3    lightDirection,
  uniform float3    lightColor,
  uniform float3    lightAmbient,
  uniform float3    eyePosW,
  uniform float    atmosRayleigh,
  uniform float    atmosMie,
  uniform float3    Ke,
  uniform float3    Ka,
  uniform float3    Kd,
  uniform float3    Ks,
  uniform float    shininess,
#ifdef CSM
uniform sampler2D    shadowArray  : TEXUNIT7,
  uniform float4x4    smTexMatArray[SM_MAX_SPLITS], 
  uniform float smSplits,
#endif
  uniform float    sunny,
  uniform float    exposure,
  uniform floatscale
)
{ 
  float3 skyColor;
 
  float4 mixa, mixb;
  float pi=3.141592654;
 
  float2 RotationMatrix = float2(cos(0.25*pi),-sin(0.25*pi));
 
#ifdef CSM
  float shadow;
  // Output shadowing and normals
  shadow=GetShadowFactor(IN.Position, IN.normal,shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;
#else
  const float shadow=sunny;
#endif
 
  // Get sky gradient color
  skyColor.rgb=GetSkyColor(lightDirection,IN.Direction,IN.RayleighColor,IN.MieColor,atmosRayleigh,atmosMie,lightColor,lightAmbient);
 
  // Get base texture color
  float4 baseCol=tex2D(baseMap,IN.tc0);
 
  float2 tc=float2(IN.Position.x,IN.Position.z)*scale;
 
  float4 Cola=tex2D(Mapa,tc.xy);
  float4 Colb=tex2D(Mapb,tc.xy);
  float4 Colc=tex2D(Mapc,tc.xy);
 
  float4 Colarot=tex2D(Mapa,(tc*RotationMatrix));
  float4 Colbrot=tex2D(Mapb,((tc*RotationMatrix)*RotationMatrix));
  float4 Colcrot=tex2D(Mapc,(((tc*RotationMatrix)*RotationMatrix)*RotationMatrix));
float4 mixmapsa, mixmapsb, mixmapsc;
 
 
if (((baseCol.g-1)*2) >0)
mixmapsa=Cola;
else
mixmapsa=Colarot;
if (((baseCol.g-1)*2) >0)
mixmapsb=Colb;
else
mixmapsb=Colbrot;
if (((baseCol.g-1)*2) >0)
mixmapsc=Colc;
else
mixmapsc=Colcrot;
 
 
mixa = lerp(mixmapsa, mixmapsb, baseCol.a);
mixb = lerp(mixmapsb, mixmapsc, baseCol.a);
  float4 diffusecol=lerp(mixa, mixb, baseCol.a);
 
  //float4 baseCol=tex2D(baseMap,IN.tc0*RotationMatrix);
 
  // Lighting
  float3 ambient,diffuse,specular;
  LightingSun(Ke,Ka,Kd,Ks,shininess,lightDirection,lightColor,lightAmbient,IN.Position.xyz,IN.normal,eyePosW,
    ambient,diffuse,specular);
 
  // Store shadowed color in COLOR0, lit color additions (spec+diff) in COLOR1
  float3 sdColor=diffusecol*(diffuse*baseCol.r)+specular*diffusecol.a;
  float3 ambientColor=diffusecol*((ambient*baseCol.r)+Ke);
 
  // HDR toning of sky (for LDR shaders)
  //skyColor.rgb=1.0-exp(-exposure*skyColor.rgb);
 
 
 
 
#ifdef CSM_MRT
  // Mix sky with texture color based on atmospheric influence
  outColor.rgb=lerp(skyColor,ambientColor,IN.extinction);
  //outShadow.rgb=lerp(skyColor*(IN.extinction),sdColor,IN.extinction);
  outShadow.rgb=sdColor*IN.extinction;
  outShadow.a=shadow;
//outColor.rgb=outShadow.a;
//outShadow.rgba=0;
 
  // Blending
  outColor.a=1; //baseCol.a;
  //outShadow.a=1; //baseCol.a;
#else
 
 
  // Mix sky with texture color based on atmospheric influence
  outColor.rgb=lerp(skyColor,ambientColor+sdColor*shadow,IN.extinction);
  // Blending
  outColor.a=1;
#endif
}
Sorry if there's some superfluous stuff in there...
Basically what it does is blend between the 3 different textures you set in layers 1, 2 and 3 of your racer.shd with a master "blendmask" (on layer 0)
The blendmask is a texture that covers your whole terrain (so obviously bigger is better - more res = nicer and more detailed transitions)
In the red channel of the texture you have your AO map, here you can render out the entire terrain inside of max using mental ray's AO bake and plonk it into the red slot. Now your buildings and trees have nice ambient shadows underneath them. No more flat, lifeless terrain.
Green channel has the random noise kinda thing in it. This adds to/aids the effect of the mixing of the textures. Makes things look less tiled.
Blue channel...this one is reserved for the gravel/tarmac. Basically where this is white, there's a road. Not really used currently, could move the alpha to this channel I guess.
Finally the alpha channel.
This is basically the business of the whole thing. Black in the alpha channel represents dirt, middle grey is the dirt/grass mixture and white is full grass.
The best way to achieve this is to grab some imagery from google maps/whatever and place that on your terrain correctly. Go into photoshop and colour select the grass (all the green stuff) make a new layer and fill it with white (keeping your selection)
repeat this for the dirt/grass mixture and copy both of those into the alpha channel. No more boring repeating grass trackside.
Best part of this is the freedom. Change the tiling textures to whatever you want. No grass? make it darker dirt or something.
With the blending done via an alpha channel you can essentially paint in any details you like. Do you think the inside of a corner should have more dirt? paint some in.
I'll post some pictures later, right now I've gotta go out.
I'm sure there's like a thousand optimisations possible. Pointed out a couple already, alpha to blue channel and you could probably atlas the tiling textures somehow. But I just thought I'd throw the method I'm using in there. It works really well for real world based/copied tracks because you can get some of the nuances of the track down through this method.
Hopefully I'll be releasing a track soon that utilises it. Though with HLSL coming through I don't know what we're going to do about all these custom shaders we're making...

Sorry for the massive dump. I'll sort it out nicer later.
 
While I do agree with Mr Whippy to some extent, breaking in detail or using decals has its place, this wang tiling ALSO has a lot of valid uses. Great for adding variation to different large surfaces that don't justify lots extra poly's, like roofing, tin & iron surfaces, grass, dirt, cement & concrete. Anything where tiling is needed but tiling seams aren't.

Yep, they are great examples!

In my case I want the extra geometry but in those cases you don't need the extra geometry.

Hmmm, this should really be a shader that goes into Racer for those kinds of things as it does add some extra interest and quality! We'd just need a decent guide on where to use it and why, and how... it's certainly got things that it works very well for and your example is one of them :D

Now, how to easily create the wang tiles haha!

Dave
 
Can u draw me a diagram of how the wang tile is laid out in your examle? I don't quite follow how the edges work. I've had a go at making a grass wang tile, but wasn't that successful

tiles.m_session_mini.png

Here is a screen grab of a session with the tiles.m matlab program from http://www.liyiwei.org/. Click the Research link and go 25 items down the page to RT Tile-based Texture Mapping on Graphics Hardware.
You'll find the link to the zipped source code there.

After the program runs it opens Figure 1 showing the packed tiles and figure 2 showing the tiles spread-out. For this example I started with a 640x480 cropping of the foreground in the shot of a soccer pitch. You edit tiles.m to point at your image. If you don't have matlab, gnu octave will work just fine. (see previous post in this thread)

Stereo,
Could you please apply this tilepack to your work and show us how it looks on carlswood?
 
The dark patches look a little oddly square, I'm not sure how it decided to place them.

It does tile fine though, for the most part (there's one corner, I think in the top right of 2nd row, 3rd column, that does stand out)
SK6dI.jpg


edit: after looking through my own photos of grass, I feel a lot better about this... except that one corner that's pretty bad.
 
Thanks Stereo,
Yes... The foreground of the photo was a little darker. Like it was under an awning or other cover. Plus my cropping had near the top, two ends of a dark-blue dashed line that was on the field. Looks like the synthesizer -or whatever the magic is- really exaggerated it. But it was easy. I'll try again with a better photo.
 

Latest News

How long have you been simracing

  • < 1 year

    Votes: 92 12.8%
  • < 2 years

    Votes: 67 9.3%
  • < 3 years

    Votes: 73 10.1%
  • < 4 years

    Votes: 45 6.2%
  • < 5 years

    Votes: 100 13.9%
  • < 10 years

    Votes: 99 13.7%
  • < 15 years

    Votes: 61 8.5%
  • < 20 years

    Votes: 40 5.5%
  • < 25 years

    Votes: 37 5.1%
  • Ok, I am a dinosaur

    Votes: 107 14.8%
Back
Top