The shader thread?

I'm messing with shaders a bit right now.

Right now I am looking specifically at adding control for specular to the existing reflect shader... on Deyan's Murcielago the unified wheel/tyre texturing poses some problems.

I have to control reflection strength with an alpha map, so use the old trick of adding a syntax in the reflection shader so if we define reflection = -1, the baseCol.a is used to control reflection strength.

ambientColor=FresnelMix(ambientColor,envColor.rgb,(Kr>0?Kr:-Kr*baseCol.a),fresnel);


The problem now is that I have no spare texture slot for specular/shininess control.

So I have added this little fragment of code (from the bump speca shader)

Ks=baseCol*Ks;

This now allows the colouring of the outside of the tyre in the diffuse (rgb) channels, to do some work.



However, because the tyre is still dark in the diffuse texture (near black as it is a tyre), it doesn't have much effect on it's own.

I need to somehow increase the brightness of the texture so Racer pumps up the specular we see.

So I added a *5 multiplier to the Ks as you can see in the image attached.

shader_01.gif




Now what I don't understand is why the two images look different.

First case:
Ks in car.shd is 8, while Ks = baseCol * Ks * 5 essentially gives us Ks = baseCol * 40

Second case:
Ks in car.shd is 40, while Ks = baseCol * Ks essentially gives us Ks = baseCol * 40


Now, I don't get why they look different. Ks is meant to control the size of the specular too, but in either case they both calculate out to a peak shininess of 40, because the baseCol lookup isn't changing.
The specular settings remain the same.

It appears that multiplying by 5 in the shader means the specular level is pumped up 5x, while the shininess (size of the specular) is retained at 8 in the car.shd...

That is the effect I wanted to achieve, pumping up the actual output of the specular blob, while keeping it soft at a value of 8, but it seems un-intuitive/wrong because the value that really needs bumping up is the specular value, not shininess? (though the specular being multiplied by 5x (2.5 2.5 2.5) looked awful)

Am I missing something obvious here?




Ideally I'd like to control reflection amount, specular AND shininess using one shader here...

Probably using rgb.a for diffuse.reflection strength, and then another 3 channel texture for spec/shine and leaving another slot free for something else (perhaps transparrency?)

Specular/shininess maps add so much to these kinds of materials, so it is a shame that they haven't really been considered in the default shaders very much. I think they should almost be defaults in all materials that err away from being generally reflective (ie, using the envmap)


Bodging in the code I have for the Lambo works quite nicely in this case, but it's obviously not ideal to use the diffuse channel to control specular in this way.



Hmmmm

Dave
 
I know it sounds silly, but it's just when you plan on making content it's nice to know what is round the corner, or get a good idea.

When I started my last track (still WIP :) ), I remember mentioning to Cam about making shadow planes for ALL my scene stuff, like cones, buildings, trees etc, and also baking in vertex lighting etc. Then CSM came out and the hint of AO, and suddenly the need to do the shadow planes for realism disappears.

I just don't want to invest in doing trees a certain way to have them be the wrong way in 6 months time.



Ie, I'd kinda prefer facing billboard trees that then blend (using alpha vs time since triggered to fade) into a 3d equivalent model where they are trees that will get close enough (ie, trackside/overhanging track)...
The only issues would be needing that cross-fade of the LOD's so they didn't have an obvious change. Maybe an orientation issue too, because if you approach from a different angle, the 3d tree would not cross-fade properly as it'd look different from that angle.

That might not be an issue on a track where you only approach from one direction, but on a street corner with many approach angles it may be that the 3d tree needs to appear orientated towards the camera (using the facing billboard direction as a guide), but then once it's been placed in 3d, it stays set and doesn't rotate (obviously :D )...


Thats what I'd like to do anyway, since it's relatively easy to work that way, and both 2d trees with normal maps at a distance look great, and 3d trees up close look great.




X trees look ok right now, but far from brilliant because of the CSM.

Are there flags we can set so things cast shadows but don't recieve them? This would be more right for X trees now, despite them being still a bit wrong technically :D


Ruud, is there any chance of a page on Racer.nl going through all the depthwrite/sort offset numbering for different shader types, alphafunc/blend/alpha to coverage stuff again. We had a few threads/mini-discussions on here about it but the info is hard to re-find and dispersed.


I think it's quite important that we have written down examples so people use the right shader variables in their content.

Ie, a decal badge on a car is a blendfunc=blend on a standard material with alpha for transparrency, but with depthwrite=0 to turn off shadows, and maybe soft_offset to get it always above the material it is resting just above?!


There is the beginnings of this on Racer.nl, showing the tree shaders, the track shaders etc, and pictures, BUT, it's not comprehensive AND it doesn't have the actual shader fragments as a reference, so you don't realise some might need depthwrite, or alphafunc's etc...

Carlswood and the Lambo are ok reference material, but in plenty of places these are not ideal for others to use as a guide (lots of comments or out-dated techniques etc)


Thanks

Dave
 
Ie, I'd kinda prefer facing billboard trees that then blend (using alpha vs time since triggered to fade) into a 3d equivalent model where they are trees that will get close enough (ie, trackside/overhanging track)...
The only issues would be needing that cross-fade of the LOD's so they didn't have an obvious change. Maybe an orientation issue too, because if you approach from a different angle, the 3d tree would not cross-fade properly as it'd look different from that angle.

What you are describing is called impostors - they are automatically generated billboards of 3d objects. Crysis used them a lot. Basically, the graphics engine generates a billboard of the 3d object (renders it to a texture) when the camera is far away, and uses it instead of the real object. Then when the camera gets closer, the billboard starts to fade away and the real 3d object is displayed. I don't think it is that trivial to implement something like that in the current stage of Racer. Although, personally, I wouldn't prefer to manually generate billboards for trees either.

Are there flags we can set so things cast shadows but don't recieve them? This would be more right for X trees now, despite them being still a bit wrong technically :D

I once already asked this. You can disable objects casting shadows, but not really prevent then from receiving shadows. Most of the shaders include shadow calculation code, so, in order for the trees not to receive shadows, you'd need custom shaders that do not include the shadow algorithms. I actually did this for my track - I created a fragment shader "fs_transparent_noshadow.cg", which didn't include the shadow calculations. But the result wasn't very nice, as treelines for example cast shadows, but didn't receive any and the shadow was darker than the "unlit" side of the treeline (although, it could be that my track setup was wrong).
 
Don't get me started on tree's, they are a one of the most challenging objects to do right.
Basically because they aren't really a solid object, but lots of smaller solid objects, that are bunched together & have interplaying shadows. The amount of average shadowing obviously increases down the tree as the branch & leaf density increases and from the increasing density of the foliage above.
Trying to realistically model them with 4 poly's is asking a bit much; although I note that GT5 has a lot of 'x' trees still.
I've found thru trial & error that 100-250 poly per tree depending on size can create a reasonable tree/bush with passable shadowing on the tree, and great looking shadows cast on othe objects (depending on the split u are currently viewing them thru). This is using curved layers of tree texture combined to roughly form the overall tree shape u are after. I've posted a few pics previously.
 
Yeah, Crysis used SpeedTree, which uses the fading technique.

Technically we can do this now, kind of, using the LOD system iirc. Just the approach angle issue may be a problem, and of course the instant tree swap.

As David has noted though, you can get polygonal trees looking better than X type with not THAT many polygons, so you could easily swap to the polygonal tree sooner than is ideal, but while it is far enough away/obscured to make it so you wouldn't generally notice the swap.


Just I have lots of trees to make and the imposter system is feeling like a viable method to have both nice looking facing billboards, and then move to a nice realistic looking 3d tree up close.
I'm happy to manually build lots of these up, I need to anyway, so it's just having the system there to use them at their best really.

Not trivial, but it'd be cool to have a feeling if this is the way Racer will go, then I will feel happy about investing the time building them up (others can use them then too!)

Some1, that is interesting.

I'll have a look at removing the shadow term from the shader I am using.





Would be really interesting to try some clever stuff out for X trees though, currently I think we are far from getting the best from them, and with some clever shaders I think they could almost be plenty without using full-on 3d trees much of the time...

My logic for those currently is thus:

X tree

Tex0 rgb diffuse alpha specular
Tex1 rgb normal alpha transparrency

standard_bump shader

turn off shadow receipt (probably in shader code), but still allow casting

Use a function that will mean a plane will be 100% opaque when viewed at steep angles (45deg to 90deg), but as the angle becomes shallow, it then begins to fade out, so from say 45 > 35deg it fades out... this means we don't see the nasty X part of the tree that is just hurting the clarity of the one behind it which we can see clearly.
Perhaps a more elegant system would be too dynamically tweak alphafunc=gequal, and choke the mask based on the object tangent (not the adjusted normals obviously)

Also, the self-shadowing is then achieved with the normal information (I've done this and it looks nice, I'll post videos later of a tree this way under TOD light, looks nice through the whole day!)

The only one issue with it will be that it won't receive a shadow, but it will cast and self-shade nicely this way.


If someone can help me develop that shader then I'd be happy using X type trees for now, although a simple planar facing type using this technique for distant trees seems logical too.


The ultimate would be to be able to have an object receive a shadow, and cast one, but not cast one on itself. I'm not sure if that is possible though.


Thanks

Dave
 
I think there is also the question, whether it is worth having more complex trees than simple 'x' types.

One one hand, take a look at the latest Spa screens from iRacing (http://www.virtualr.net/iracing-com-plenty-of-spa-francorchamps-previews/). Although they are using the 'x' trees, you can hardly notice them on the screens, and I believe, even less while driving. It's still pretty much the resolution and lighting of the tree textures that make them look great.

On the other hand, if it is not a racing track that has armco's preventing the player from driving everywhere, the 'x' trees look pretty strange close up. This is where the true 3d trees have an advantage. Test Drive Unlimited had quite a few 3d trees (= a lot!) and a huge world, but I think they also used automatic impostors, and maybe instancing as well.

Maybe I'm too used to the 'x' trees, but I think I prefer them over 3d trees in most cases, unless the 3d trees look realistic and have minimal performance impact.
 
Same here Some1... if I could get them looking like iRacing, I'd be happy.


I'm happy if Ruud says that imposters won't be anything we will see seriously looked at for another year or more at least, then we can basically look at X or * trees and work to get the best from them.


I'm happy to work with either, but clearly Racer is suffering right now because it's X trees can't even work right with the CSM shadows we have now, so it's not got any reasonably nice looking tree solution except the good old tree boundary/wall types around Carlswood. Those trees sat on their own in the circuit stand out with the poor shading/shadowing.



I think my solution above has good potential. I'll work at them and see what they end up looking like. It's just writing the shaders that I struggle with.

iRacing *seems* to have a system of shadowing and shadow receipt, but not self-shadowing on those bigger trees. I think that is the key issue here. Solve that and then suddenly we have a much easier time getting reasonable looking trees.


It's that old issue again of making content and Racer changing. If v0.9 had a reasonable solution for trees I'd be running with it, but it doesn't that is why I'm struggling and want some clarification on what is reasonable or possible.

I'm not 'into' shaders enough to know the answers. If the above concept for X type trees is possible via cg shader language alone, then I'm happy, but if it's going to be Ruud programming it then it's less likely to get done for a long time yet, and I'm not happy using crappy X trees that look like crap because of crappy shaders :D


I'm sure David I shares my pain. He has spent a good while tinkering with trees and doesn't seem to be happy yet, and I think that is a shame if v0.9 is meant to be helping content developers make things they are proud of and want to release!


I'm easy either way we go, I would just like some direction or re-assurance for the future that certain ideas are possible or viable :D


Dave
 
It seems that instancing would be a fairly easy-to-implement solution that would not require the write to texture that imposters would.


As far as x-trees go I think it's more a question of careful placement and knowing when to switch to higher detail 3D models.

Alex Forbin
 
I tried using x-trees as lower lod models & my higher poly ones as lod0's, but the lighting/shadow differences between the two are just too large & it is too noticable. The other reason I modelled my trees the way I did was that I could then use Cg to move the foliage around a bit, while the trees look pretty good static, a small amount of movement makes them look as realistic as needed without going over the top.
X-tree's don't lend themselves to any realistic looking Cg motion, they just look strange & awkward.
X-trees have their place, as far away from camera as possible. Anything reasonably close to camera needs something more than x-trees.

For Treelines, I'm using cut down versions of the 3d trees, 70-150 poly's each, positioned on the treeline billboard. I'm pretty happy with the overall effect tree-wise I have in Mugello now, I need to look at the movement Cg sometime in the future, as it could be tweaked for some more realism, but I've moved onto my next bug-bear with tracks, trying to get decent material overlaps, like from sandtrap to grass, grass to kerb etc, especially when one material's bumpmapped, and the other is another shader like detail.
 
I think Some1's links to the iRacing images shows that X trees can work pretty well.

I will agree, feature trees might need to be 3d.


As for the lod0/1 variance using an X tree > 3d ones, in theory if you use a planar facing tree > 3d one (aligned right in our case because there is no way to sync alignment), then using a normal map as per my method way back up the page, you can match lighting pretty well, since the 2d map is generated from the 3d mesh in the authoring app.

That said, in many cases, you might be able to swap a tree and not even notice because so much is going on. Ie, you might see the tree 200m away, but then it might get occluded by buildings or something, or another tree, and you could swap it at that point (lots of manual LOD distance tweaking!)


Once again, I'm easy any way we go. All these solutions have positives and negatives, it's just which we run with for now... I'm eager to get making trees (and share my library of them), just which way to go with them :D

As Some1 said, and as I've looked more, even my rough X trees at the side of my road look 'ok' from the car driving past and even when near stopped. It's only when the track cam (smaller FOV) is looking at the car past the trees they look a bit limited.
With better shading and stuff, they could probably be fairly acceptable for most stuff.

Current issues:

Imposter system won't work without an elegant way to impose them from 2d > 3d.
X type trees won't work at their best without an elegant shader.

:)

Dave
 
I've moved onto my next bug-bear with tracks, trying to get decent material overlaps, like from sandtrap to grass, grass to kerb etc, especially when one material's bumpmapped, and the other is another shader like detail.

That's a difficult one. There are some world-coordinate shaders that mix 2 textures, but it's hardly the same as mixing 2 materials; it only does diffuse mixing. I guess near border you need an overlapping polygon where the top one overlays the bottom one with alpha determining a nice chaotic mix.

More on trees in a bit.
 
That's a difficult one. There are some world-coordinate shaders that mix 2 textures, but it's hardly the same as mixing 2 materials; it only does diffuse mixing. I guess near border you need an overlapping polygon where the top one overlays the bottom one with alpha determining a nice chaotic mix.

Best solution I've come across so far wrt polys vs. detail, is to have overlapping poly's assigned to different materials, using alpha to control whats drawn.
i.e. sand to grass transition, I've a grass tex and a sand tex, both with same alpha's, and use the sma shaders as the sand & grass shaders respectively.
As each texture is not drawn over the other because of the alpha, u don't get any z-fighting.
Well almost, I've a few missbehaving poly's on kerbs in Mugello, that I can't explain why they do what they do, but I'm remodelling the kerb transitions anyway, hopefully that'll fix it.
The only issue is mipmapping of the alpha, which can cause transparent lines thru the transitions. If u juggle the alpha value u can almost eliminate it.

I'm using this technique for transitions on the version of Mugello u got recently Ruud. I also use a custom shader for grass that is like a detail shader, but the detail map uses world coords instead.
 
On the trees, it seems they add a gradient over the tree texture in the direction of the sun direction. See the attached image.
They then don't do any shadow receiving on the polys themselves. For Dave, this is just replacing this line in standard_tree_f.cg:

float shadow=GetShadowFactor(IN.Position, IN.normal,shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;

to:
float shadow=1

('shadow' really is the amount of light, yikes). This is all doable in Cg shaders, using the texture coordinates; mapping those to world directions and dotting (projecting) with the sun direction. I don't think it requires any programming from my side. Ofcourse v0.9 can have small additions if it really helps. Just like if there are extra controller preset files, I'd update v0.9 to v0.9.1 with added files (same is required probably with some shaders that prove useful generally).

So I think trees that do cast shadows but don't receive them, and are lit in the direction of the sun are already possible with Cg in v0.8.27/28.

On the grass in those iRacing images, what they seem to do is this:
- don't take a photo of the grass from the top, but take it from the side. You get a nice perspective /\ type image
- in Photoshop, correct the perspective so that it becomes a linear image (where you DO look AT the grass parts head on!). So the image is again | |
- Now the Z (distance) of the photo is off, since Z grows non-linearly. This would require a warp that will evenly space out the Z of the grass photo to be useful as a repeatable texture.

It's funny how the iRacing shadows work; the trees don't cast shadows on the guardrails. My guess is they make a Swiss-Stroll type overlay geometry with shadows. However, Swiss Stroll really copied the geometry. With Cg you can just make a flat 2D texture image, and each pixel would grab its shadow state from the 2D shadow map (covering the entire track).
The problem here is texture size; you'd need a megatexture (>2048x2048). Still far off.

As for X-trees and delaying content generation; I intend to do a bit more on physics the next half year, and not focus so much on graphics (there is a nice spherical harmonics article though, but that won't affect content). Imposters are tricky with CSM and such applied correctly (for trees that don't receive shadows it would be simpler, but still). I'd go for the iRacing X-tree (cast, not receive) with 3D trees where they end up close. The gradient for the sun direction should be doable with Cg, or with a small addition of code, which could be coded into v0.9 if need be (it's going to be an SVN branch anyway, so updateable)).
 

Attachments

  • tree_iracing.jpg
    tree_iracing.jpg
    111.7 KB · Views: 299
I note that their shadows are a lot sharper at larger distances than ours are. Those sharpish shadows from the tree's before the far turn make such a difference to the realism.

I've found that moving clouds, 3d trees with a small amount of foliage movement, esp their shadows moving; small things in themselves, but added to the current graphics make a huge amount of difference to the experience.

I've also noticed that fps seems now to be more dictated by the amount of materials/shaders in view at any one time, as opposed to being hugely influenced by texture size or poly count, at least on my hardware.
 
Indeed, I can easily bump the 458 up to over 100k polies and have a negligable performance drop, though that might just be my hardware. Seems the amount of materials loaded (not textures - I believe I have plenty of RAM left on my GPU though I mean to discuss this with you ruud.)

Currently I use a white texture in my texture slot for the 458. The colours are then defined by different ambient, diffuse and specular values defined in the car.shd
I think I'm using an 8x8 texture but surely loading that same texture 10 or so times is bad. If I write a shader that just uses ambient and diffuse can we then include that in the default shaders?
I'm yet to do a test but I'm certain it'll get a fair FPS increase. Surely loading that texture (even if it is 8x8) has a toll.

This then opens up custom car colours etc. though that would probably be something to consider 0.9+
Great to hear you're going to open up an SVN too!!
 
Their shadows don't look though as they would be dynamic (moving), so that may be a plus for Racer. Also, that megatexture shadow I was talking about is preprocessing, no live TOD (although I'm not too fond of leaving all methods that are only valid at 1 TOD).

The FPS and textures: I'm often limited by bandwidth due to using a lot of anti-aliasing. I hope nVidia will come quickly with a working PerfSDK on Win7-64 bits (32-bits apps on 64-bits Win7 isn't supported by PerfSDK). That would give more insight in bottlenecks (which are different for everyone, and depends on your settings).

@Camsinny: that SVN isn't public though. :) We use SVN here to do our source versioning (and also content these days).
Doing a car skin without textures; is that worthwhile? You'd see you need specular mapping at least, and quickly have some decals or baked AO in your diffuse map.
 
Well I've been considering it and with the normal influence, etc. I think it looks fair enough without a baked AO map, these things start to turn bad with varying TOD also.
I just think in some cases it would be advantageous to not have to use a texture lookup.
 
I note that their shadows are a lot sharper at larger distances than ours are. Those sharpish shadows from the tree's before the far turn make such a difference to the realism.

Set blur = 0 on the shadows... :)

The blur gets REALLY aggressive in those situations, shadows become splodges, and essentially useless at representing a shadow :(

Having the 4 splits will help get a nice level of shadow detail at middle distances.


Ruud... how does the fade of the last split work?

Does it simply take the split2/3 values and fade between them?

split0 100%
split1 100%
split2 100%
fading here between these values?
split3 0%

Or is it hard coded somewhere? I couldn't really tell reading the shadowmapping.cg file...

Thanks

Dave
 
Well I've been considering it and with the normal influence, etc. I think it looks fair enough without a baked AO map, these things start to turn bad with varying TOD also.
I just think in some cases it would be advantageous to not have to use a texture lookup.

I was looking at GT5 and I'm sure they use AO, especially on the interiors.

Clearly they use the AO as a base in the shaded "ambient" pass, but the diffuse pass is done as we do ours now.


I'm on the fence with unwrapping the car body etc. It has so many benefits but a few costs too...


As for shaders slowing things down. In theory, you can achieve many many materials with one shader. Most control can come from the texture maps they use. And then atlas the textures so that is one texture load too.

Ie, my old M3 has pretty much a shader per texture right now, and that is all the whole car needs really. You could possibly add a few more, but the bulk of stuff is fairly lightweight.

In theory, the F458 could use an 8x8 texture for the colour (all white), and then the alpha channel could be 2x2 swatches of shades of grey for different reflection strengths, specular strengths etc etc, and you could then cut down lots on shader counts and texture loads.

Just that last step of work to get it as optimal as possible. It's always these jobs that take the time I find :D (read my M3, looked finished in a few months, but the details took another 18 months :D )

Dave
 
They then don't do any shadow receiving on the polys themselves. For Dave, this is just replacing this line in standard_tree_f.cg:

float shadow=GetShadowFactor(IN.Position, IN.normal,shadowArray, smTexMatArray, smSplits, lightDirection)*sunny;

to:
float shadow=1

That sounds cool.

So that will basically light all trees with a gradient from lit to unlit linearly across the tree about the suns direction? I'll have a go tonight.

OK they won't receive shadows, but I'm not entirely sure that is really important... it'd be nice, but I'd prefer trees to look properly lit and natural, than un-naturally lit but technically in shadow at the right times. The former is more important for realism than the latter right now!


Dave
 

Latest News

What brands would you like to see with more engagement in simracing?

  • Ferrari

    Votes: 44 43.1%
  • Porsche

    Votes: 36 35.3%
  • BMW

    Votes: 37 36.3%
  • McLaren

    Votes: 24 23.5%
  • Toyota

    Votes: 39 38.2%
  • Intel

    Votes: 13 12.7%
  • AMD

    Votes: 20 19.6%
  • Gigabyte

    Votes: 9 8.8%
  • IBM

    Votes: 9 8.8%
  • Elgato

    Votes: 10 9.8%
  • Microsoft

    Votes: 22 21.6%
Back
Top