1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Sand and grass mixing.

Discussion in 'Racer Physics and Technical' started by radome, Mar 2, 2011.

  1. Mr Whippy

    Mr Whippy

    Messages:
    2,998
    Ratings:
    +463
    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
     
  2. QuadCoreMax

    QuadCoreMax

    Messages:
    767
    Ratings:
    +71
    Doesn't look that bad for your first testings, there could be even more randomness in the tiles imo.
     
  3. radome

    radome

    Messages:
    170
    Ratings:
    +24

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


    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
     
  4. Stereo

    Stereo

    Messages:
    2,582
    Ratings:
    +1,613
    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
     
  5. radome

    radome

    Messages:
    170
    Ratings:
    +24
    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.
     
  6. radome

    radome

    Messages:
    170
    Ratings:
    +24
    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?

    An issue of texture binding? ..GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D..
     
  7. Stereo

    Stereo

    Messages:
    2,582
    Ratings:
    +1,613
    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).
     
  8. QuadCoreMax

    QuadCoreMax

    Messages:
    767
    Ratings:
    +71
    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...
     
  9. Stereo

    Stereo

    Messages:
    2,582
    Ratings:
    +1,613
    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));
     
  10. QuadCoreMax

    QuadCoreMax

    Messages:
    767
    Ratings:
    +71
    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.
     
  11. DavidI

    DavidI

    Messages:
    461
    Ratings:
    +54
    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
     
  12. Stereo

    Stereo

    Messages:
    2,582
    Ratings:
    +1,613
    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).
    [​IMG]
     
  13. DavidI

    DavidI

    Messages:
    461
    Ratings:
    +54
    Thankyou, I get it now.
    I made some bricks:
    [​IMG]
    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?
     
  14. Stereo

    Stereo

    Messages:
    2,582
    Ratings:
    +1,613
    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.
     
  15. DavidI

    DavidI

    Messages:
    461
    Ratings:
    +54
    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.
     
  16. camsinny

    camsinny

    Messages:
    479
    Ratings:
    +21
    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.
     
  17. Mr Whippy

    Mr Whippy

    Messages:
    2,998
    Ratings:
    +463
    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
     
  18. radome

    radome

    Messages:
    170
    Ratings:
    +24
    [​IMG]
    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?
     
  19. Stereo

    Stereo

    Messages:
    2,582
    Ratings:
    +1,613
    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)
    [​IMG]

    edit: after looking through my own photos of grass, I feel a lot better about this... except that one corner that's pretty bad.
     
  20. radome

    radome

    Messages:
    170
    Ratings:
    +24
    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.