Metallic Paint Shader

It seems to be going a little off-topic in the Jaguar thread so I'm pulling this out here.

Mr. Whippy said:
Either way, I think your shader is great. On my track with a few tweaks as discussed it works intuitively and nicely. I even added the metallic flake to my TVR colour cars (cascadey type look), and it worked fine! From a reading and making sense of it point of view it is implemented as realistically as we could, to copy real life, so I don't think it could be done better with what we have either

I'd like to see a version of it as a default in the global shaders folder, but just have some kind of maths noise rather than the texture perhaps, and have it applied in 3d space rather than 2d mapped, with a scale factor, so then you don't even have to have nice texture mapping coords of a constant scale to make it look right...



I don't have the Aronde mapped yet so a 3d random noise seemed relevant to me. Because actual random number generators take a while I'm just using a random noise texture map here.
arondepaintfleck.jpg

The white spot is the reflection of the sun, not part of specular lighting.
Code:
dyn_reflect_spec_f.cg

 uniform sampler2D   specMap : TEXUNIT2,
[...]
  float3 p=IN.Position;
  float4 spCol1=tex2D(specMap,(p.xy)*5.0f);
  float4 spCol2=tex2D(specMap,(p.yz)*5.0f);
  float4 spCol3=tex2D(specMap,(p.zx)*5.0f);
  float4 specCol=spCol1*N.z+ spCol2*N.x+ spCol3*N.y;
specCol is then fairly random 3d noise, assuming specMap is a noisy texture. Multiply it onto specular as with the metallic shader.


I'm using IN.Position and N here because it's more compatible with existing shaders, really it is better to rewrite _v to pass model coordinates/normal, and use those (which is what the Aronde has). They'll look the same in screenshots, but when you drive around, the speckles move if it's using world coordinates.

This is probably not going to fit into the 64 operations some people are limited to unfortunately. More of the math ends up in _f.


I haven't had a chance to look at Tiberius' metallic flake shader yet (my connection is not good enough to download a 30MB car), I just applied this by multiplying the specular.

These go in carfolder\cg\ to work properly.
speckle_v.cg
Code:
//
// Standard lighting with reflection - dynamic models (modelMatrix)
// RvG, 16-3-09
//

#include "../../../renderer/shaders_hdr/atmosphere.cg"
#include "../../../renderer/shaders_hdr/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;
  float2 tc0            : TEXCOORD0; // zw is pos.xy
  float3 Direction      : TEXCOORD1; // w is pos.z
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float4 FPosition      : TEXCOORD4;    // For fragment shader
  float3 normal         : TEXCOORD5;
  // Interpolate fresnel in PS
  float3 I              : TEXCOORD6;
  //float  fresnel        : TEXCOORD6;
  float3 R              : TEXCOORD7;    // Reflection vector
  float  extinction     : COLOR;        // 0..1
};

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

  // Constants
  uniform float4x4 modelViewProj,
  uniform float4x4 modelMatrix,
  uniform float3   lightDirection,
  uniform float3   eyePosW,
  uniform float3   lightColor,
  // Atmosphere
  uniform float    sunIntensity,
  uniform float    atmosRayleigh,
  uniform float    atmosMie,
  uniform float    extinctionFactor
)
{
  // Transform to clipspace
  OUT.Position=mul(modelViewProj,IN.Position);
  float3 posW=mul(modelMatrix,IN.Position).xyz;

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

  // Extinction factor of regular color
  OUT.extinction=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie,extinctionFactor);
  
  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  
  // put position in
  OUT.normal=IN.normal; //mul((float3x3)modelMatrix, IN.normal);
  //OUT.normal=N;
  OUT.FPosition=IN.Position; //mul(modelMatrix,IN.Position).xyz;
  float3 N=mul((float3x3)modelMatrix,IN.normal);
  // Reflection
  float3 I=posW-eyePosW;
  OUT.R=reflect(I,N);

/*  
  // Fresnel
  const float fresnelBias=0; //0.2;
  const float fresnelScale=1.0; //0.9
  const float fresnelPower=2.0; //4.0;
  I=normalize(I);
  float dotIN=dot(I,N);
  // Avoid sharp edges
//  dotIN=min(dotIN,0.2);
//  dotIN=max(dotIN,-0.2);
  OUT.fresnel=fresnelBias+fresnelScale*pow(1.0+dotIN,fresnelPower);
//OUT.fresnel=pow(1+dotIN,fresnelPower);
//OUT.fresnel=N; //dotIN;
*/

  // Fresnel in pixel shader (pixely effects when done in VS)
  OUT.I=I;
  
/*
  // Reflection (dynamic)
  float3 posW=mul(modelMatrix,IN.Position).xyz;
  float3 I=posW-eyePosW;
  float3 Nwc=mul((float3x3)modelMatrix,IN.normal);
  R=reflect(I,Nwc);
*/
}

speckle_f.cg
Code:
//
// Standard with reflection cubemap
//

#include "../../../renderer/shaders_hdr/atmosphere.cg"
#include "../../../renderer/shaders_hdr/lighting.cg"
#include "../../../renderer/shaders_hdr/fresnel.cg"

// Vertex to pixel shader structure
struct v2p
{
  float  extinction     : COLOR;
  float2 tc0            : TEXCOORD0; // tc0.zw is pos.xy
  float3 Direction      : TEXCOORD1; // Direction.w is pos.z
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float4 Position       : TEXCOORD4;    // For fragment shader
  float3 normal         : TEXCOORD5;
  // Fresnel in pixel shader
  float3 I              : TEXCOORD6;
  //float  fresnel        : TEXCOORD6;
  float3 R              : TEXCOORD7;    // Reflection vector
};

void main(
  // In
  in v2p IN,

  // Out
  out float4 outColor : COLOR,
  
  // Constants
  uniform sampler2D   baseMap : TEXUNIT0,
  uniform samplerCUBE envMap  : TEXUNIT1,
  uniform sampler2D   specMap : TEXUNIT2,
  uniform float4x4 modelMatrix,
  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     Kr,
  uniform float3    shininess,
  uniform float     exposure
)
{
  float3 skyColor;
  float3 posW=mul(modelMatrix,IN.Position).xyz;
  float3 N=normalize(mul((float3x3)modelMatrix,IN.normal));
  float3 N2=normalize(IN.normal);

  // Get sky gradient color
  skyColor.rgb=GetSkyColor(lightDirection,IN.Direction,IN.RayleighColor,IN.MieColor,atmosRayleigh,atmosMie,lightColor,lightAmbient);

  // Get base texture color
  float3 p=IN.Position.xyz;
  float4 spCol1=tex2D(specMap,(p.xy)*5.0f);
  float4 spCol2=tex2D(specMap,(p.yz)*5.0f);
  float4 spCol3=tex2D(specMap,(p.zx)*5.0f);
  float4 specCol=spCol1*N2.z+ spCol2*N2.x+ spCol3*N2.y;

  float4 baseCol=tex2D(baseMap,IN.tc0);

  // Reflection
  //const float Kr=0.5f;
  float4 envColor=texCUBE(envMap,IN.R);

  // Lighting
  float3 ambient,diffuse,specular;
  LightingSun(Ke,Ka,Kd,Ks,shininess,lightDirection,lightColor,lightAmbient,posW,N,eyePosW,
    ambient,diffuse,specular);
  baseCol.rgb=baseCol*(ambient+Ke)+baseCol*diffuse*lightColor+specular*specCol;
  
  // Add reflection with fresnel
  float fresnel=Fresnel(0.15,0.85,2.0,normalize(IN.I),normalize(N));
  baseCol.rgb=FresnelMix(baseCol.rgb,envColor.rgb,(Kr<0?baseCol.a:Kr),fresnel);

  // HDR toning of sky
  //skyColor.rgb=1.0-exp(-exposure*skyColor.rgb);

  // Mix sky with texture color based on atmospheric influence
  outColor.rgb=lerp(skyColor,baseCol,IN.extinction);

  // Blending
  outColor.a=baseCol.a;
}

In car.shd,
Code:
vf_speckle
{
  vertex_shader
  {
    file=cg\speckle_v.cg
  }
  fragment_shader
  {
    file=cg\speckle_f.cg
  }
}

shader_body~vf_speckle
{
  compression=0
  reflect=0.6
  specular=.62 .45 .66 ; purple specular
  shininess=15
  tangents=1
  layer0
  {
    map=stereo_ar_purple.tga ; plain purple image
  }
  layer1
  {
    map=$trackenvmap
  }
  layer2
  {
    map=volumespec.tga ; random noise
  }
}
One minor flaw I saw is that this method is symmetric, left and right side of the car have the exact same mapping and it's somewhat visible along the centerline. Also, if you have a flat surface the texture tends to visibly repeat.
 
Looking good.

Yep, procedural do take time vs look up, so a texture is ideal I guess, but I suppose we need to test to see the difference?!

LOD on the specular for example, you won't even see it at 2m really, so the soft specular splodge will do the trick there, ie, be fast. The only time you really want that specular effect of metallic flakes is up-close and so the cost might not be so bad!?


Liking the 16bit envmap for sun spot reflections on car lacquer or polished surfaces. It gives so much more control really, because if we ever get control over the sun we can make it bigger and duller and softer, or sharper and smaller and brighter, and every combo in between, and the specular on the car will react correctly.

Setting speculars in shaders to 'pretend' to be the sun reflection imo, is pretty poor because they are fixed.

Specular in shaders seem best for the above effect now, metallic flake effects, or bigger softer more satin reflection types (ie, anything not a sharp reflection of the sun)


Cheers

Dave
 
Yep, procedural do take time vs look up, so a texture is ideal I guess, but I suppose we need to test to see the difference?!

The other thing I didn't think of at first, if you use a random number generator the noise will change every frame. With the textures mapped using object coordinates the highlights stay in the same spots, which looks more natural on closeups.

LODs for shaders, hmm... maybe put an if statement that measures the distance to the object and skips the details? IN.extinction is already based on distance to the camera, so it shouldn't require additional information. Extinction could also be useful to speed up rendering distant objects - if the extinction value is 100% skyColor, then it can skip rendering the object's textures/reflections entirely. Maybe even cut off reflections at 80% or something.
 
All that code is nice but wouldn't it be better to post a .zip or .7z file so that members of the community wouldn't have to work so hard to get this geat shader to work?

A better explanation would also help, like what in the world is a random 3D noise?

This would help those of us that are cg challenged, thank you!
 
Tiberius explained this on RSC, so well that even I understood it.

It's a bit like a depth map, the whiter bits of the map are elevated relative to their plane, and the darker bits are the opposite. Making a depth map that resembles the fuzzy black/white static screen you see when you de-tune your television means that you can have a very granular depth map, to simulate the grains in metallic paint. Then somehow it's coloured, and a shiny smooth clear-coat finish is given, using something else in the shader.

I think that's it.
 
A better explanation would also help, like what in the world is a random 3D noise?

3d noise is something you would be more familiar with in 3ds Max or 3d rendering apps. It's a procedural (maths generated) texture basically, and in this instance rather than make a noise map in Photoshop with a fixed seed (so it doesn't animate and change frame to frame), you can make a '3d' map, so the noise is actually the same through the object too.
This means that if the object is a ball, rather than having a noise map applied to the surface with stretched circular dots as the circle bends away, the texture is always nicely applied because the dots are actually spheres in 3d space, so retain their nice shape.

It's not a HUGE drain vs a lookup table (image), BUT, it will be a drain. It has benefits and downsides. I think 3d texture noise is best because this is more a special effect of metallics only seen up-close, and thus not essential for gameplay or gameplay FPS. It's just a nice feature for photo mode type stuff, or up-close where the FPS might not be essential.

Hmmmm

Dave
 
All that code is nice but wouldn't it be better to post a .zip or .7z file so that members of the community wouldn't have to work so hard to get this geat shader to work?

Right now I'd prefer to wait for comments, and hopefully have it working smoothly and accurately before posting a .zip people can just copy to their car without thinking too much about it. By itself the 3d noise is just a proof of concept, and the way it affects specular is only to make it visible.

For example, instead of applying the noise directly to the specular, it can be added to the normal vector, so what's calculated is actually a paint fleck at a slight angle to the surface, which is more theoretically sound. This changes the character of the specular highlight, instead of fairly uniform falloff, the bright pixels just get more uncommon farther from the centre.
Right now I have a feeling it needs adjustment in specular terms (way too bright and possibly spreading too much - I can only make uniform noise in the GIMP and I would like Gaussian) but is an improvement over the first post.
arondenoise2.jpg


That Perlin noise is interesting, but I think for this purpose it's essentially the same as my code other than a better interpolator. I'm just relying on tex2D's interpolating the texture, they use an octahedron of lookups to a static texture (6 1D lookups rather than my 3 2D) around the centre pixel and interpolate them with what I guess is a better 3D method.
 
  • Tiberius

Boomer: Think procedural textures like those in Blender (noise, clouds, marble etc). Same idea, as Whippy says most modelling apps use them.

Stereo: Here's the code from the X-Type, should be fine to use it with dyn_standard_bump_reflect_v.cg:

Code:
//
// Standard with cubemap+bumpmap (3 textures); HDR
// 26-03-09, RvG
// Racer's bump reflect shader, modified for reflection and specular controlled by texture alpha, also metallic fleck effect
//
#include "../../../renderer/shaders_hdr/atmosphere.cg"
#include "../../../renderer/shaders_hdr/lighting.cg"
#include "../../../renderer/shaders_hdr/fresnel.cg"

// Vertex to pixel shader structure
struct v2p
{
  float4 tc0            : TEXCOORD0;    // tc0.zw=I.xy
  float4 Direction      : TEXCOORD1;    // Direction.w = I.z
  float3 RayleighColor  : TEXCOORD2;
  float3 MieColor              : TEXCOORD3;
  float3 Position            : TEXCOORD4;
  float  extinction        : COLOR;        // Only 0..1
  float3 lightDirTS     : TEXCOORD7;    // Light direction in texture space
  float3 eyePosTS       : TEXCOORD5;    // Eye position in texture space
  // Reflections
  float3 R              : TEXCOORD6;
  //float3 I              : ATTR9;      // Passed in tc0.zw and Direction.w
};

float3 expand(float3 v)
// From a bump RGB color (0..1) to normal (-1..1)
{
  return (v-0.5)*2.0;
}

void main(
  // In
  in v2p IN,

  // Out
  out float4 outColor : COLOR,
  
  // Constants
  uniform sampler2D baseMap   : TEXUNIT0,
  uniform sampler2D normalMap : TEXUNIT1,
  uniform samplerCUBE envMap  : TEXUNIT2,
  uniform sampler2D   noiseMap : TEXUNIT3, //loads metallic noise texture
  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 float3    Kr,
  uniform float3    shininess,
  uniform float     exposure
)
{
  float3 I;         // Incident
  float3 skyColor;

  // Reconstruct 'I'
  I.xy=IN.tc0.zw;
  I.z=IN.Direction.w;

  // Get sky gradient color
  skyColor.rgb=GetSkyColor(lightDirection,IN.Direction.xyz,IN.RayleighColor,IN.MieColor,atmosRayleigh,atmosMie,lightColor,lightAmbient);

  // Get base texture color
  float4 baseCol=tex2D(baseMap,IN.tc0.xy);
  
  // Get metallic noise texture
  float4 noiseCol=tex2D(noiseMap,IN.tc0.xy*24); //multiplies texture to tile 32x

  // Reflection
  float4 envColor=texCUBE(envMap,IN.R);
  
  // Bumpmap (delta from original normal)
  // Assume its normalized
  float3 N=expand(tex2D(normalMap,IN.tc0.xy).xyz);

  // Compute diffuse term (in tangent space)
  float3 L=IN.lightDirTS;

  // Lighting (in tangent space!)
  float3 ambient,diffuse,specular;
  LightingSun(Ke,Ka,Kd,Ks,shininess,L,lightColor,lightAmbient,IN.Position,N,IN.eyePosTS,
    ambient,diffuse,specular);
    
  float3 specular2=baseCol.a*(specular*noiseCol); //specular controlled by baseCol alpha channel, also metallic effect

  baseCol.rgb=baseCol*(ambient+Ke)+baseCol*diffuse*lightColor+specular2;

  // Add reflection with fresnel
  float fresnel=Fresnel(0.15,0.85,2.0,normalize(I),N);
  float fresnel2=fresnel*baseCol.a; //dark parts of texture alpha don't reflect
  baseCol.rgb=FresnelMix(baseCol.rgb,envColor.rgb,Kr,fresnel2);

  // Mix sky with texture color based on atmospheric influence
  //outColor.rgb=lerp(skyColor,baseCol,IN.extinction); //original version
  outColor.rgb=lerp(skyColor,baseCol,IN.extinction);

  // Blending
  outColor.a=baseCol.a;
}
Usage is the same as the dyn bump reflect, except you'll need the noise map on layer3. Set specular globally, you'll need a lot (I had specular=1.8 0.4 0.6 for the red on the X). also a mipmap lod bias of -1 on the noise layer helps the noise stay in focus slightly longer. Also bear in mind I've got reflect and specular controlled by the base texture alpha channel, because the body lines and door handles were textured and picked up too much light otherwise. There's several ways I'd like to improve it, really it's quite a balancing act to get each colour to look good at the moment.

I'll check out the shader you posted :smile:
 
I guess I should post the change I made in previous post:

Code:
  // Lighting
  float3 ambient,diffuse,specular;
N2 = normalize(N + Ks.r*expand(specCol)); // specCol is the random noise
  LightingSun(Ke,Ka,Kd,Ks,shininess,lightDirection,lightColor,lightAmbient,posW,N2,eyePosW,
    ambient,diffuse,specular);
  baseCol.rgb=baseCol*(ambient+Ke)+baseCol*diffuse*lightColor+specular;
Also uses the 'expand' function from bumpmaps, so that needs to be added before main:
Code:
float3 expand(float3 v)
// From a bump RGB color (0..1) to normal (-1..1)
{
  return (v-0.5)*2.0;
}
This is to calculate the specular (and diffuse) with noise added. I found fairly low settings worked well (specular=0.3 0.3 0.3 for white - previous post has specular=.62 .45 .66 for pink, which is somewhat too intense). The same method could probably apply to your shader using the noisemap.

And the noise texture I'm using is uncorrelated rgb. If it's black & white it ends up looking strange.
 
  • Tiberius

Tried it. Only on metallic black so far, but it's definitely better than my version. What's nice is that it doesn't stretch over the UVs. No matter how well you map the UVs, you'll get some stretch somewhere - any UV stretching looked really bad on my version.

I am getting some very slight stretching on an old car mesh I tried (old low poly 050 era model, not one of mine), really just on a couple of corners where the normals are less than perfect. I presume this is just a normals issue?

Also tried it on Suzanne, main reason was because I wanted a complex shape but one which wasn't mapped properly. I mapped the mesh from the side, so the entire front/rear would have been stretched to hell using the UV coords, as you can see the metallic tiles perfectly in those places. The metallic might need scaling up slightly for the texture I'm using, but it seems to work well.

I was trying to get reflect mapping working too, looking at the shot you posted with the frosted Lambo, I suppose you've worked that out too? :smile:
 

Attachments

  • suzanne.jpg
    suzanne.jpg
    60.5 KB · Views: 414
I am getting some very slight stretching on an old car mesh I tried (old low poly 050 era model, not one of mine), really just on a couple of corners where the normals are less than perfect. I presume this is just a normals issue?
I was trying to get reflect mapping working too, looking at the shot you posted with the frosted Lambo, I suppose you've worked that out too? :smile:

Yeah, this method assumes the normals are pretty much pointing straight out from the poly. If not it'll stretch a bit, worst case would be normals perpendicular to the poly they're on (which shouldn't happen unless there's a 180 degree bend).

Reflect is fairly simple modification to the bumpmap, move
R = reflect(I,N);
from _v to _f (after the N is taken from the bump texture). You can actually save a variable by doing this - no need to pass R from _v anymore. I would guess Ruud avoided doing this on the default bumpmap shader because the Lamborghini's bumpmap is horribly noisy and it pretty much ruins the reflections. I had a much cleaner bumpmap on my RX-7 and reflection mapping works fairly well.

Changing the mapping scale is just a matter of editing the numbers on these lines:
float4 spCol1=tex2D(specMap,(p.xy)*5.0f);
I was using a 128x128 noise map, so if you made it much larger you'd probably want to decrease this correspondingly. I didn't play with values at all so I'm not sure what works best.

I threw in the if switches to fade to normal specular at a distance of about 10 metres, when I get a chance I'll post a .zip. Gives me a couple extra fps when I zoom out from the car, nothing major (probably more useful with a whole fleet of cars going round the track).
Just leaves the minor matter of figuring out good specular/shininess values for different colours. Suzanne's looks pretty good.
 
  • Tiberius

Yep, it works fine on a higher poly mesh, not a problem.

I tried dozens of colours in the time since I started trying metallic shaders, really it all depends on the colour. Seems better to keep the shininess pretty low so that the specular 'flakes' are lit over a nice wide area, specular colour vs. the base colour texture is really the difficult thing to get right - at least for me. Most of the time I ended up using the colour picker on photos or colour charts and going from there, then just adjusting things by eye. Much harder on dark colours because of reflections.

Really, the only colours I can't get right now are really dark solid (non metallic) colours like black. Tried dozens of different fresnel setups but can't get it to look good. Metallic black or dark grey is fine, because there's at least some surface there once the specular is on. but solid black, just can't get that to look right, either picks up too much reflection making it look mainly sky colour, or otherwise looks too matte and reflects nothing.

Nice work though, thanks for sharing it.
 
Ok, here's a usable one. Put the 2 cg files in car folder\cg\, the texture is just a small example of what the random noise can look like.

car.shd goes something like:
Code:
vf_speckle
{
  vertex_shader
  {
    file=cg\speckle_v.cg
  }
  fragment_shader
  {
    file=cg\speckle_f.cg
  }
}
shader_body~vf_speckle
{
  compression=0
  reflect=0.6
  specular=.24 .10 .3
  shininess=8
  layer0
  {
    map=body.tga
  }
  layer1
  {
    map=$trackenvmap
  }
  layer2
  {
    map=volumespec2.tga
  }
}

Fixed a bit of a bug from what's posted earlier, also hopefully sped it up by removing redundancies and unused variables.

I also commented a couple lines of _f with "experimental" - they add reflection scattering, which may or may not be something you want, just uncomment the line following each //experimental.
 

Attachments

  • metallicpaint.rar
    57.6 KB · Views: 198
  • Tiberius

Reflect is fairly simple modification to the bumpmap, move
R = reflect(I,N);
from _v to _f (after the N is taken from the bump texture). You can actually save a variable by doing this - no need to pass R from _v anymore. I would guess Ruud avoided doing this on the default bumpmap shader because the Lamborghini's bumpmap is horribly noisy and it pretty much ruins the reflections. I had a much cleaner bumpmap on my RX-7 and reflection mapping works fairly well.

Yep, you were right, after moving things around I've certainly got reflect mapping. However, it seems to react badly at UV seams, and it's distorting the normals for some reason - env map on the left side of the car renders fine but the top of the car is reflecting the side of the track where the left should be, right side is reflecting totally upside down. Eventually traced it to the way I and N are calculated in Racer's shaders (model matrix calculations?), I rebuilt most of my shader..and although I can get both model and bump map normals passed, I seem to have effectively invented a CG invisibility cloak, reflections pass straight through the car :frown:

Seems like it really needs the bump map normal adding to the model's normal, I'll have another try tonight but a gentle nudge in the right direction would be welcome :).
 
Yep, you were right, after moving things around I've certainly got reflect mapping. However, it seems to react badly at UV seams, and it's distorting the normals for some reason - env map on the left side of the car renders fine but the top of the car is reflecting the side of the track where the left should be, right side is reflecting totally upside down. Eventually traced it to the way I and N are calculated in Racer's shaders (model matrix calculations?),
Seems like it really needs the bump map normal adding to the model's normal, I'll have another try tonight but a gentle nudge in the right direction would be welcome :).

Yeah, when I actually looked at the reflections I noticed it's at a right angle to where it should be, but I didn't get a chance to track down what's doing that yet. Maybe this weekend...
 
  • Tiberius

Thanks Stereo, at least I know I've done things right this end. Apart from the distorted reflections, it seems to work well, but I'm beginning to realize why Ruud didn't include the reflect mapping in the bump shaders - it really shows up noise and aliasing in the bump textures - especially where the HDR sun reflections are. On the X-Type I was using a 2048x2048 bump tex for the body, I admit that it could be improved (the door handle and creaseline texture were from a photo, my old Paint Shop Pro can't create realistic gradients like that), but I did try a lot of noise removal around those areas. Guess I need to make another bump texture, heh :)

Really, I'm thinking about effects like orange peel, textured glass etc, really just arty stuff to see how it all renders in 3D.

Also, I managed to get your 3D texture working for bump maps, makes my bump mapped engine and interior textures look so much better, takes away the bump texture stretching completely..I owe you big time for that idea.

Sorry to hijack your thread BTW :smile:
 
  • Tiberius

Hmmm, distorted reflection, this reminds me of the rain drop effect on car body from PGR4, maybe u can try it out~

Hmm, that would be ace. I did manage to get some bump map blending going on (not quite right yet but no reason it can't be done, surely?), really just to see if it could be done. The more we get into it, the more possibilities there are :smile:

Refraction would be good too, haven't tried that yet but the shaders are in the cg handbook..

This needs another new thread :tongue:
 

Latest News

Online or Offline racing?

  • 100% online racing

    Votes: 74 7.3%
  • 75% online 25% offline

    Votes: 104 10.3%
  • 50% online 50% offline

    Votes: 146 14.4%
  • 25% online 75% offline

    Votes: 278 27.5%
  • 100% offline racing

    Votes: 405 40.1%
  • Something else, explain in comment

    Votes: 4 0.4%
Back
Top