Unity Community


Page 1 of 6 123 ... LastLast
Results 1 to 20 of 113

Thread: Fur Shader


  1. Location
    Minnesota, USA
    Posts
    1,713

    Fur Shader

    I made a 20 pass two directional light + ambient fur shader for a game I'm working on. I'm sharing it in hopes that someone will help optimize it, since this is my first Cg program.

    It should run on anything that supports vertex programs. It runs really slowly on a GMA 950 as it is vertex bound, but taking out a light and making it 10 passes can make it acceptable for that card. Not much else to do about it.

    The crummy thing is that it doesn't use Unity's lighting system, so I have a script that passes two directional lights of your choice to the shader that you stick on the furry object. I don't know how to make it use Unity's lighting system.

    It uses shells and not fins, but you can fade out the shells along the edges with one of the parameters if you want to add some fins with another material / triangle list.

    Cheers,
    -Jon
    Attached Images  
    Attached Files


  2. Location
    Minnesota, USA
    Posts
    1,713
    If only all the soldiers in Global Conflicts Palestine looked like this.

    -Jon
    Attached Images  

  3. Unity Graphics Developer

    Location
    Unity Technologies, basement
    Posts
    3,974
    Your Cg is quite good in fact! Two things I changed:

    I changed the way you do extrusion. I just add normal to the object space position, and then transform that by regular MVP matrix. This produces different result than extrusion you did (which was some sort of extrusion in post-perspective space), but it saves a couple of instructions; and possibly some shader constants because less parameters are used.

    Then I removed support for texture scale&offset. So that's a loss of flexibility, but a save of matrix multiplication in the vertex shader.

    So now the vertex shader is 28 instructions, down from 34. That could make some difference on GMA950; hard to guess how much exactly.

    I've also moved some more code into the helper .cginc file, so the shader file itself is now shorter.

    Other interesting things to try (no for GMA950 though... I think): do a proper anisotropic lighting on the fur. Now it treats fur normals the same as surface normals; whereas in real fur the normals point to all directions orthogonal to surface normal.
    Attached Files


  4. Location
    Minnesota, USA
    Posts
    1,713
    Quote Originally Posted by Aras Pranckevicius
    I changed the way you do extrusion. I just add normal to the object space position, and then transform that by regular MVP matrix. This produces different result than extrusion you did (which was some sort of extrusion in post-perspective space), but it saves a couple of instructions; and possibly some shader constants because less parameters are used.
    Yeah, I'm not sure what was going on with that. I tried something like you've done first but couldn't get it working for some reason. Thanks!
    Quote Originally Posted by Aras Pranckevicius
    Then I removed support for texture scale&offset. So that's a loss of flexibility, but a save of matrix multiplication in the vertex shader.
    Yeah, don't need this for a real character.
    Quote Originally Posted by Aras Pranckevicius
    So now the vertex shader is 28 instructions, down from 34. That could make some difference on GMA950; hard to guess how much exactly.
    It did! In a test scene it went from 17 fps to 25 fps. Now with a 10 pass 1 light version it is even more acceptable. Of course it still runs hundreds of FPS even on a lowly Radeon 9600...
    Quote Originally Posted by Aras Pranckevicius
    I've also moved some more code into the helper .cginc file, so the shader file itself is now shorter.
    Ahh, clever. Thanks
    Quote Originally Posted by Aras Pranckevicius
    Other interesting things to try (no for GMA950 though... I think): do a proper anisotropic lighting on the fur. Now it treats fur normals the same as surface normals; whereas in real fur the normals point to all directions orthogonal to surface normal.
    Yeah, there seems to be a ton more to be done with this, but I think it may be good/slow enough for our purposes for now. Nicholas pointed me to these cool slides with way better fur. He also helped idea wise with the shader, so thanks Nicholas.
    http://ati.amd.com/developer/SIGGRAP...ur_Isidoro.pdf

    -Jon


  5. Location
    Capitol City New Zealand
    Posts
    3,191
    Jon-Aras,
    You guys are fantastic-seriously. Is there anything you cant do?

    This takes things to a new level. I cant believe how quickly you can whip stuff up like this. Mega cred 2 u guys.
    AC


  6. Posts
    5,283
    The soldier looks nice. :O)

    One question: Do the shells result into real polys in the end like if you just would clone a modell, enlarge it and reduce the alpha value of the texture step by step?


  7. Unity Graphics Developer

    Location
    Unity Technologies, basement
    Posts
    3,974
    Quote Originally Posted by taumel
    One question: Do the shells result into real polys in the end like if you just would clone a modell, enlarge it and reduce the alpha value of the texture step by step?
    Yes. In essence this draws the model 20 times, extruded more and more each time. So it's almost the same as creating 20 shells manually (the vertex shader also does some fading out at the edges).


  8. Location
    Tucson, AZ
    Posts
    848
    Taumel: That would be rather cool as a sun with a wreath of flame.


  9. Posts
    5,283
    @Aras

    Is a shader version theoretically any faster because for instance it spares this or that mathematical transformation compared to a grouped object where i just rotate the parent?

    The sw3d example is overall under 50 lines of code and also runs on really old shaderless hardware. A shaderversion for sure is more flexible and the better way to go if you make it more complex.

    By the way is there a good tutorial around (a crash course) for working with shaders in unity? I only did four really simple things and i guess there's much more to explore...


  10. Posts
    5,283
    @Marble
    I'm not sure, i guess there are better ways to fake a sun. I think i would more go for a particel solution then...

  11. Administrator
    Location
    Copenhagen
    Posts
    1,586
    Does the shaderless version simply scale the object up? That only works for very simple geometry as you want to extrude each vertex along the normal. For a sphere that's fine, but not for anthing real.

    You can use the mesh interface to do pretty much the same in Unity at loadtime. Performance should be about the same.

    The shader one is faster once you begin skinning the objects.
    Mathematicians that only do calculations that we already know about and are comfortable with? They're called accountants, and they have no friends.


  12. Posts
    5,283
    Yep, it only clones (same ressource) and scales a sphere but it would be enough for a marble game or even a fur-pacman... ;O)

  13. Unity Graphics Developer

    Location
    Unity Technologies, basement
    Posts
    3,974
    I managed to shave off two more instructions from the vertex shader. Replace FurVertexPass in my previous package's Fur/Support/FurHelpers.cginc with this:
    Code:  
    1. void FurVertexPass(float multiplier, appdata_base v, float furLength,
    2.     out float4 pos, out float fog, out float4 color, out float4 uv)
    3. {
    4.     // extrude position
    5.     float4 wpos = v.vertex;
    6.     wpos.xyz += v.normal * furLength * multiplier;
    7.     pos = mul(glstate.matrix.mvp, wpos);    
    8.  
    9.     // fog
    10.     fog = pos.w;
    11.    
    12.     // UV (pass through to save instr - loses tiling/offset though)
    13.     uv = v.texcoord;
    14.    
    15.     // edge fade out
    16.     float alpha = 1 - (multiplier * multiplier);
    17.     // transform normal into eye space and use Z component
    18.     // to control the fade
    19.     float3 eyeNormal = mul((float3x3)glstate.matrix.modelview[0],
    20.         v.normal);
    21.     alpha += saturate(eyeNormal.z) - _EdgeFade;
    22.    
    23.     // lighting
    24.     float3 normalWorld = mul ((float3x3)_Object2World, v.normal);
    25.    
    26.     float light0 = clamp(dot(normalWorld, _LightDirection0.xyz),
    27.         _MyLightColor0.w, 1);
    28.     float light1 = clamp(dot(normalWorld, _LightDirection1.xyz),
    29.         _MyLightColor1.w, 1);
    30.  
    31.     color = float4((light0 * _MyLightColor0).xyz +
    32.         (light1 * _MyLightColor1).xyz,alpha);
    33. }

    I changed the part that calculates the alpha - instead of calculating view direction (which involves a costly normalize), I just transform normal into view space and use it's Z component to do the fade.


  14. Posts
    5,283
    Works...

    Any idea on a shader crash course?

  15. Administrator
    Location
    Copenhagen
    Posts
    1,586
    Here's how I learnt it:

    I started out by playing with texture combiners - like trying to do nice glass with fresnel falloff (which can be made to run on anything).

    Next I would make them run on more modern combiners. IIRC, you have a Mac mini with a radeon9000 GFX card. That means moving the shaders to the ATIFS1 assembly language (which is simpler than the name implies). There are a bunch of examples at the bottom of the ATI_TEXT_FRAGMENT_SHADER spec.

    ATI has a lot of Radeon85000-based articles online from ShaderX1 - they are made for DirectX, so the format is bit different from the OpenGL one used in Unity. Moving these over gets you going - basically you get in the habit of "thinking like a pixel".

    Ignore lighting at first - it's quite complex, a major hassle & not very fun. Just focus on doing fun effects (gems, ligtning, water, etc).
    Mathematicians that only do calculations that we already know about and are comfortable with? They're called accountants, and they have no friends.


  16. Posts
    5,283
    @Nicholas
    Okay, thanks

    @Aras
    Could you alter your one so that the tiling is back?

  17. Unity Graphics Developer

    Location
    Unity Technologies, basement
    Posts
    3,974
    Quote Originally Posted by taumel
    Could you alter your one so that the tiling is back?
    Just insert matrix multiplication where UV is computed in the vertex shader; just like it was in the first Jon's package.


  18. Posts
    5,283
    Which then try to overwrite yours in unity...couldn't you cut&paste the relevant lines here and say where to insert?


  19. Posts
    1,640
    Quote Originally Posted by Targos
    Jon-Aras,
    You guys are fantastic-seriously. Is there anything you cant do?

    This takes things to a new level. I cant believe how quickly you can whip stuff up like this. Mega cred 2 u guys.
    AC
    ditto! cool as... fur!

Page 1 of 6 123 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •