Racer v0.8.36 released

Ruud

RACER Developer
A good date for an update. ;-)

Racer v0.8.36 is at http://www.mediafire.com/?i6rnbmthb5sr3dh (52Mb)

I'm going to investigate the cameras; the location wasn't right when we modified them relative to the nullpoint, but I seem to have some trouble getting them right in the Lambo. I'm away for a week first though...

The changes:
- Bugfix: script parentheses could cause confusion: 'paint sin($a*0.8)+10 at float[2]{ 50,50 };'
would give numbers between -1..1 instead of 9..11 (priority conflict).
- Bugfix: the camera locations not relative to the nullpoint. This does mean
you should move your camera positions!
- Added 'terminal' console command; this opens an output window. Also added dev.terminal in racer.ini to open it at startup.
See also http://www.racer.nl/tutorial/development.htm . Useful for content development as well; seeing warnings quickly.
- Entering of console commands is now also possible in the menu screen (although not many commands work here).
- Added 'debug <path>' to show a subtree's values live, much like the Ctrl-1 to 9 screens.
- data/cars/default/car.ini contained a differential tree which was not used; now split into 'differential' and 'differentials' (the latter is preferred)
- FMOD upgraded to v4.36.5 (fmodex.dll)
- Added 'reload globalviews' console command to reload data/gui/globalviews.ini
- Added damage parameters to default/car.ini (damage is still very alpha functionality)
- Added views.ini type 'clip' (for example for a filling bar) - currently it stretches the image though
- If a car's view0 was empty, Ctrl-9's second subpage could crash
- Added 'get focus car' script command to retrieve the car in focus (unlike 'get local car' for example)
- 'doc scriptfuncs' now opens the file after creation.
- Pacejka player could not edit 'a0' in Pac96 mode.
- Pressing Ctrl-0 twice would crash
- racer.ini's collision.report_car_track_collision now shows collisions between objects in the console
- DOF_Fix had an endless OpenGL error loop
- Endless roads possible by defining endless.min.x/y/z and endless.max.x/y/z in a track's special.ini
See http://www.racer.nl/tutorial/endless_track.htm
- Newton upgraded to v2.34 (newton.dll)
- Movables initial state is now no longer to freeze; this to fix framerate issues (although it's a little slow at the first few frames).
- Added generic model align_axis property, to fix one of the axes of a generic model (to prevent rotations; only 2 endpoints are defined).
This was done for Boomer's IMP car, to keep a suspension model from rotating when moving.
- Added susp<n>.susp_y_change_per_rad (around 0.01 to 0.1) to dynamically move the suspension attachment point for geometric effects.
- Ini.exe would crash when adding a non-existing key
- Added 'show lidar' and 'hide lidar'. High-end laser scanned tracks only (alpha development).
- Added 'lidar movex <v>' plus movey and movez commands to translate Lidar data to match the track.
- Gearwhine sample now also uses jitter (similar to the engine).

Enjoy!
 
The only way I've found so far to animate trees is to have them as seperate dof's so each objects's centre position is known. This then creates a problem for me.
Maybe Ruud could comment on the future, is this likely to change, do I have to drop my tree animation & group my trees into dof's?
Mixing animated & non animated can look ok, but only with even amounts or more of animated versus static, so I still end up with a reasonable amount of dof's. I can glob all my tree trunks together into a few dof's, as I don't animate them.

Yeah, it won't work so well if your shader is using dof centre coords for animation.

There is probably a way to get animation some other way though? Maybe via geob vert numbers (if you make sure they follow some certain rules?)


Irrespective of that, the old 'wave' uvw transforms seem ample for X trees at a given distance from the track/road side, and it animates fast too here (I applied it to my thousands of trees and there was little to no speed cost that I could see)
My only issue is that I use an atlas for the trees (xtree scale shader), and I need to 'scale' the UVW waving down as well (taken from the flag waving shader). I have no idea how to do that... :D


For 'hero' trees that need to be 3D and you can get really close to, then I guess there isn't a huge issue having them per DOF anyway. You can quickly swap them for an imposter X tree after 200m or so anyway!?
It's fairly rare a tree gets that close on race tracks that you need it to be 3D. For those that do, I think a hero tree or bunch of trees will do the job perfectly well :D

I need to continue with my 2D X-tree tree texture atlases so we can all use them, they are just so time consuming to generate :D

Dave
 
Movables initial state fix is great !

Testing the traffic cars via console, I get a constant message : Car not found
Does anyone have success ?

Also, wrapping a car to waypoints is a good idea, but there's no sound nor particles no wheel moving ? attached to the car when the script is triggered...Any suggestions on how to manage the whole traffic/waypoints network so it looks realistic enough when driving with them ?
 
The only minor hiccup in using the wave shaders for trees is that it already uses the scale parameter to say how 'big' the waves are, so it can't really be used again to indicate the number of trees on the texture atlas.

So a combination of the two would need to drop one of those features.

standard_xtree_wave_v.cg
Code:
//
// Standard lighting for X type trees
// Specifically for trees and grass - strips normals and uses up (0,1,0) instead
// to get a more even lighting that still listens to sun conditions.
// Single texture
//

#include "atmosphere.cg"
#include "lighting.cg"

// App to vertex
struct a2v
{
  float4 Position : POSITION;
  float3 normal   : NORMAL;
  float2 tc0      : TEXCOORD0;
};

// Vertex to pixel shader structure
struct v2p
{
  float4 Position       : POSITION;
  float3 FPosition			: TEXCOORD4;    // For fragment shader
  //float3 Color 			: COLOR;
  float3 normal         : TEXCOORD5;
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float2 tc0            : TEXCOORD0;
  float3 Direction		  : TEXCOORD1;
  float  extinction		  : TEXCOORD6;
};

float3 Wave(float time,float3 pos,float2 uv)
// Returns world offset based on time and texture coordinates
{
  float3 off;
  float sinOff=pos.x+pos.y+pos.z;
  float t=-time*0.6;
  float sin1=sin(t*1.45+sinOff);
  float sin2=sin(t*3.12+sinOff);
  float sin3=sin(t*2.2+sinOff);
  float fx=uv.x*uv.x;
  float fy=uv.x*uv.y;

  off.x=sin1*fx*0.5;
  off.y=sin2*fx*0.5-fy*0.9;
  off.z=sin3*fx*0.5;

  return off;
}

void main(
  // a2v
  in  a2v IN,
  out v2p OUT,

  // Constants
  uniform float    time,
  uniform float4x4 modelViewProj,
  uniform float3   lightDirection,
  uniform float3   eyePosW,
  uniform float    scale,
  // Atmosphere
  uniform float    sunIntensity,
  uniform float    atmosRayleigh,
  uniform float    atmosMie,
  uniform float    extinctionFactor
)
{
  // Wave
  float4 posWC = IN.Position;
  posWC.xyz+=Wave(time,posWC,fmod(scale*IN.tc0,1));
  // Transform to clipspace
  OUT.Position=mul(modelViewProj,posWC);

  // Atmosphere
  CalculateAtmosphere(atmosRayleigh,atmosMie,sunIntensity,eyePosW,posWC,lightDirection,
    OUT.RayleighColor,OUT.MieColor,OUT.Direction);

  // Extinction factor of regular color
  OUT.extinction=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie,extinctionFactor);

  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  OUT.normal=IN.normal; //mul((float3x3)modelMatrix, IN.normal);
  //OUT.FPosition=mul(modelMatrix,IN.Position).xyz;
  OUT.FPosition=posWC.xyz;
}

This is assuming that scale=2 means 4 trees on the texture, in a 2x2 grid, and so on.
Default standard_xtree_scale_f.cg is using the scale parameter the same way, so you'd use standard_xtree_wave_v + standard_xtree_scale_f.

I have only tested this on Carlswood, not sure the wave scale works everywhere. If not, the line starting posWC.xyz+=Wave() should be posWC.xyz+=scale*Wave() using some float value of scale (like 0.3) Also, the speed of the waves depends on float t=-time*0.6; - lower number means slower moving trees.

Really, both of those should be a function of the current wind speed - but I'm not sure how to get that info into a shader yet.

Also, note: the upper UV coordinates need to be slightly less than the top edge of the texture. Carlswood's trees are at exactly 1.0, which means the scaling function sees them as the same as 0.0 on the next repetition of the texture - so the quads don't actually move at all.

The actual functions involved changing x,y,z coordinates should probably be tweaked, this is just to get an idea of how to implement the wave into xtree scale shader.
 
Hmmm, I'm struggling with that shader. It's working when I remove the scale property from the wave part at the end. I've had something working myself, but the UV's were not scaled, so trees from the top run of the atlas were really wobbling around :D

When yours worked a bit, it looked quite nice to be honest. When stopped watching them at maybe 30m away they 'felt' much like a SpeedTree tree waving in the wind before they finally turn into a polygonal tree.


Which part specifically scales the 'wave' so it works on multiples of the UV, rather than just 0>1?

Indeed, the wrap-over of 0/1 is a pain too. So in theory are we best mapping from 0.01 > 0.99 u/v for example? (or multiples thereof?)




Yes, using scale twice is a pain.

I'm not sure which way is best. Maybe it's best to simply have xtree1,2,4,8_v/f, then you can simply choose from a single, double (4), quadruple (16), or octuple (64)...

Then you can use the scale variable to control wave magnitude and perhaps speed (assuming bigger waves go slower, you just divide by scale for the speed)

That would seem fairly easy to maintain.

I'm currently thinking of using probably 4 atlases for my trees/shrubbery/grasses etc...

One 2048x2048 (16 trees) (4x4)
One 1024x2048 (16 taller thinner trees) (4x4)
One 2048x2048 (64 shrubs/saplings and other such bits and bobs) (8x8)

One 2048x2048 (not using xtree shader for this, just used for grass strips/hedges/forest/treeline facias etc)


So for me, I'd probably be happier to just have the xtree scale shader be replaced with a xtree 4/8 shader :D

Then scale can be used for waving of the trees instead.

Also probably worth adding the wave to the non xtree shader too (I've done this in the past for treelines and grass strips so flowers/long grasses blow in the wind a bit)


Anyway, I'm just testing here for now, but it'd be cool to check this logic out and determine the actual impact on FPS.


Stereo, if you care to help me out, feel free to mod the xtree scale shader to a fixed 4x4 (16 total trees), and then allow scale to be passed for the waviness.
I can then try UVW map in the range 0.01 > 0.99 range (so thats 0.01 > 0.255, 0.255 > 0.5, 0.5 > 0.745, 0.745 > 0.99 ?? )
My aim is to have the bases of the trees not wave at all, and then the top of the tree be waving the most. Right now I'm still getting wavy bottoms a bit :D


I'll try post some videos of the trees when they get working a bit better... hopefully I'll get the time over this Christmas break to finish at least my big/medium/tall tree varieties and then populate my atlases as required, then get down to the long task of painting them onto my terrain :D

Dave
 
When yours worked a bit, it looked quite nice to be honest. When stopped watching them at maybe 30m away they 'felt' much like a SpeedTree tree waving in the wind before they finally turn into a polygonal tree.


Which part specifically scales the 'wave' so it works on multiples of the UV, rather than just 0>1?
It should be this line.
fmod(scale*IN.tc0,1)
fmod is the floating point modulus, this is the same as the scaling xtree shader uses for lighting.

The only trick is, as mentioned, need to do 0.01>0.99 - otherwise, if you have them at exactly 0, 0.5, 1 then there's no way for the vertex fragment to tell if it's the bottom of one UV map or the top of the next, since it considers single vertices, and it's supposed to behave differently depending which case it's looking at. For the textures/lighting it doesn't matter because the edge is transparent anyway.

I got around to running it as written on Carlswood, with the following replacing vf_xtree:
Code:
vf_xtree
{
  ; Tree fake their normals pointing up
  vertex_shader
  {
    ;file=dyn_standard_v.cg
    file=standard_xtree_wave_v.cg
    ;file=standard_wave_v.cg
  }
  fragment_shader
  {
    ;file=standard_f.cg
    file=standard_xtree_f.cg
    ; UV coordinates are bad (see http://www.racer.nl/tutorial/xtrees.htm)
    ;file=standard_xtree_scale_f.cg
    ;file=standard_wave_f.cg
  }
  scale=0.9
}
scale=0.9 takes care of the problem with UV mapping going to 1.0, obviously won't work when there is actual scaling of textures.

For scale to control the amount of waviness - also, I tweaked this one so there's no vertical motion, and the bottom of the tree is stationary.
Code:
//
// Standard lighting for X type trees
// with waving, 4x4 texture
// Specifically for trees and grass - strips normals and uses up (0,1,0) instead
// to get a more even lighting that still listens to sun conditions.
// Single texture
//

#include "atmosphere.cg"
#include "lighting.cg"

// App to vertex
struct a2v
{
  float4 Position : POSITION;
  float3 normal   : NORMAL;
  float2 tc0      : TEXCOORD0;
};

// Vertex to pixel shader structure
struct v2p
{
  float4 Position       : POSITION;
  float3 FPosition			: TEXCOORD4;    // For fragment shader
  //float3 Color 			: COLOR;
  float3 normal         : TEXCOORD5;
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float2 tc0            : TEXCOORD0;
  float3 Direction		  : TEXCOORD1;
  float  extinction		  : TEXCOORD6;
};

float3 Wave(float time,float3 pos,float2 uv)
// Returns world offset based on time and texture coordinates
{
  float3 off;
  float sinOff=pos.x+pos.y+pos.z;
  float t=-time*0.6;
  float sin1=sin(t*1.45+sinOff);
  float sin2=sin(t*3.12+sinOff);
  float sin3=sin(t*2.2+sinOff);
  float fx=uv.x*uv.y;

  off.x=sin1*fx*0.5;
  off.y=0.0;
  off.z=sin3*fx*0.5;

  return off;
}

void main(
  // a2v
  in  a2v IN,
  out v2p OUT,

  // Constants
  uniform float    time,
  uniform float4x4 modelViewProj,
  uniform float3   lightDirection,
  uniform float3   eyePosW,
  uniform float    scale,
  // Atmosphere
  uniform float    sunIntensity,
  uniform float    atmosRayleigh,
  uniform float    atmosMie,
  uniform float    extinctionFactor
)
{
  // Wave
  float4 posWC = IN.Position;
  posWC.xyz+=scale*Wave(time,posWC,fmod(4.0*IN.tc0,1));
  // Transform to clipspace
  OUT.Position=mul(modelViewProj,posWC);

  // Atmosphere
  CalculateAtmosphere(atmosRayleigh,atmosMie,sunIntensity,eyePosW,posWC,lightDirection,
    OUT.RayleighColor,OUT.MieColor,OUT.Direction);

  // Extinction factor of regular color
  OUT.extinction=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie,extinctionFactor);

  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  OUT.normal=IN.normal; //mul((float3x3)modelMatrix, IN.normal);
  //OUT.FPosition=mul(modelMatrix,IN.Position).xyz;
  OUT.FPosition=posWC.xyz;
}
 
Use vert colours for scaling (isn't that all the position is used for in the shader? So the bottom of the tree doesn't move but the branches/top does?)
Then you can batch up all your trees and still have proper movement.
 
Tree branches move more at their ends, so I was making vertexes move based on their distance from the centre of the object, and also height from the base plus an offset. I then move them around in all axis based on time and the preveius distance value calculated.
Trees in batch dof's on slopes could also be an issue for animation.
There was good reasons I split them into individual tree dofs, it was the best way until now to make them work realistically. Well the best to date.
 
Sorry, to clarify: use vert colours to scale the movement, not "scaling"
Just make the shader use vert colours. Multiply the wave var by the object's vert colours, then where there's black vert colours (i.e. trunk) there'll be no movement, but where there's white vert colours, there's full movement (i.e. branches/leaves)

I'll make up a shader for it when I have a good tree to use. Trust me, it works lol
 
That sounds like a good plan Cam :D

Thanks for the shader Stereo, I'll try get round to testing it today... Currently fighting with MSN messenger again, never wants to logon due to an 8000494 fault which won't fix... Microsoft are so damn lame. The whole rest of the internet works except their bloated crap-ware!

Dave
 
Hmm, Stereo,

I'm struggling to get that shader working here :D

My UVW's along the top row are 0.995, and along the bottom 0.005

I've used scale=0.995 in the shader you provided above for the vert shader.

Not much is happening here...


Tinkered around a bit with bits and pieces of your vert shader...

Scale is set at 4 still, for the fragment shader, which is just default xtree_scale_f shader.

Then vert one is adjusted from the ones above:


//
// Standard lighting for X type trees
// Specifically for trees and grass - strips normals and uses up (0,1,0) instead
// to get a more even lighting that still listens to sun conditions.
// Single texture
//

#include "atmosphere.cg"
#include "lighting.cg"

// App to vertex
struct a2v
{
float4 Position : POSITION;
float3 normal : NORMAL;
float2 tc0 : TEXCOORD0;
};

// Vertex to pixel shader structure
struct v2p
{
float4 Position : POSITION;
float3 FPosition: TEXCOORD4; // For fragment shader
//float3 Color: COLOR;
float3 normal : TEXCOORD5;
float4 RayleighColor : TEXCOORD2;
float4 MieColor : TEXCOORD3;
float2 tc0 : TEXCOORD0;
float3 Direction : TEXCOORD1;
float extinction : TEXCOORD6;
};

float3 Wave(float time,float3 pos,float2 uv)
// Returns world offset based on time and texture coordinates
{
float3 off;
float sinOff=pos.x+pos.y+pos.z;
float t=-time*0.6;
float sin1=sin(t*1.45+sinOff);
float sin2=sin(t*3.12+sinOff);
float sin3=sin(t*2.2+sinOff);
float fx=uv.x*uv.x;
float fy=uv.x*uv.y;

off.x=sin1*fx*0.5;
off.y=sin2*fx*0.5-fy*0.9;
off.z=sin3*fx*0.5;

return off;
}

void main(
// a2v
in a2v IN,
out v2p OUT,

// Constants
uniform float time,
uniform float4x4 modelViewProj,
uniform float3 lightDirection,
uniform float3 eyePosW,
// Atmosphere
uniform float sunIntensity,
uniform float atmosRayleigh,
uniform float atmosMie,
uniform float extinctionFactor
)
{
// Wave
float4 posWC = IN.Position;
posWC.xyz+=16*Wave(time,posWC,fmod(0.25*IN.tc0,1));
// Transform to clipspace
OUT.Position=mul(modelViewProj,posWC);

// Atmosphere
CalculateAtmosphere(atmosRayleigh,atmosMie,sunIntensity,eyePosW,posWC,lightDirection,
OUT.RayleighColor,OUT.MieColor,OUT.Direction);

// Extinction factor of regular color
OUT.extinction=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie,extinctionFactor);

// Pass texcoords and such
OUT.tc0=IN.tc0;
OUT.normal=IN.normal; //mul((float3x3)modelMatrix, IN.normal);
//OUT.FPosition=mul(modelMatrix,IN.Position).xyz;
OUT.FPosition=posWC.xyz;
}

I'm not sure if that is right or not, but I've changed the scale variable down to 0.25, from 4 (which did nothing)...

Then just added a variable at the start to scale it all up a bit.

I've got my rows of UV's offset by 0.005, so 0.005 bottom, 0.995 top... (not adjusted the intermediates yet, ie, 0.25 0.5 0.75)

Seems ok, not perfect, but that is probably the intermediate values been off a little bit...

Hmmm


Best bit is zero to very very little FPS hit here, even with thousands of trees visible, it's maybe 0 > 0.5% slower...

Dave
 
Might be a bit excessive but maybe the maps could be packed differently, with alternating rows of upright and upside down trees? That would get rid of UV problems, but then it might be harder to randomize the trees - I'm not sure how that part's accomplished. Anyway, a wave shader that worked on UV maps packed like this would be easy.
nHBzH.png

Like this but with less fake looking trees :p

I'm not really sure what's going wrong, a small test track with some trees to look at could help, I don't have anything that uses the xtree scale shader.
 
I'll try get a beta of my track out soon then you can have a proper look/play.

That array of textures is easy really, just flipping the layers in photoshop.

I guess the scale thingy for the shading also works fine there as it generates a normal 'sphere' so the orientation is irrelevant too :D

A weird looking but sensible solution to the problem there, nice one :D


Now, back to generating my different tree species... I've decided upon the following split for my track on the main 4x4 array.

2 oak, 3 ash, 3 sycamore, 1 horse chesnut, 2 beech, 2 birch, 2 scots pine, 1 alder

What I'm thinking though is that my array may not suit other tracks or other users needs, so I'll probably make 4 of each species, and also another 4 adolescent tree textures for each breed above (on an 8x8 array possibly, since they can be smaller)...

Then if you have more of certain trees you can add more variety to the array...

I was just thinking about how I'd make an atlas generator, which could populate automatically what a user wanted, and also do the flipping too now you have shown it :)


I'll post a video shortly...

Cheers

Dave
 

Latest News

Are you buying car setups?

  • Yes

  • No


Results are only viewable after voting.
Back
Top