Announcement

Collapse
No announcement yet.

OSL goodness in Vray

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • OSL goodness in Vray

    I thought it would be cool to share OSL shaders that folks have been writing for Vray. So in the spirit of the thread of the same name for a certain other software that uses OSL, I thought I'd start one here for Vray. I'll kick it off by sharing an OSL fabric shader I wrote:

    fabric.osl

    This is an artist friendly fabric shader. It's basically an anisotropic Blinn with added sheen and tint terms to capture how the tiny fibers of fabric pick up light at incident angles, and how the specular color of fabrics are often tinted by the diffuse color. The sheen color can also be used to darken the sheen as some fabrics (for example black nylon) are darker at the edges, rather than brighter.

    I'd love to hear feedback on the shader, and things that could be done to make it better.

    Note that with the current implementation of OSL in Vray the diffuse color slider defaults to black. So you need to change it to be able to see the diffuse contribution. Also since OSL widgets are not implemented yet, the dropdown menu for ramp_type does not work and you need to manually choose one of the 6 options. These options are explained in the comments within the shader code below.



    Code:
    /*
     *
     * fabric.osl shader by Derek Flood (c)2015
     * from http://sharktacos.com/Forums/misc.php?action=help&hid=66
     *
     */
    
    float fresnelReflectionFactor(normal bumped_normal, float ior)
    {
        float c = abs(dot(I, bumped_normal));
        float g = ior * ior - 1.0 + c * c;
    
        if (g > 0.0) {
            g = sqrt (g);
            float A = (g - c) / (g + c);
            float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0);
            return 0.5 * A * A * (1.0 + B * B);
        }
       
        return 1.0;
    }
    
    
    
    normal getBumpedNormal(color centerColor, color uColor, color vColor, float inverseBumpAmount)
    {
        vector worldTangent = normalize(dPdu);
        vector worldBitangent = normalize(dPdv);
        vector worldNormal = normalize(N);
       
        vector average = vector(0.3333333);
        float center = dot (average, vector(centerColor));
        float ddu = center - dot(average, vector(uColor));
        float ddv = center - dot(average, vector(vColor));
       
        return normalize(ddu * worldTangent + ddv * worldBitangent + inverseBumpAmount * worldNormal);
    }
    
    
    surface fabric
        [[ string description = "artist based fabric material" ]]
    (
        /* Diffuse section */   
        color Sheen_color = color(1.0, 1.0, 1.0),     //This color can be black for nylon sheen.
        float Sheen_opacity = 1.0,           // Determines amount of sheen effect as fibres pick up light at incident angle.
        float Sheen_tint = 0.5,             // Tints both the sheen and specular.
        string Diffuse_color = "",
        float Diffuse_weight = 0.8,
        float Roughness = 0.4,
        int ramp_type = 3              // Six types of interpolation for sheen. 1-3 are sharper, 4-6 are softer.
            [[ string widget = "mapper",
            string options = "linear:1|exponential:2|Smooth:3|Sigmoid:4|Square_root:5|Fresnel:6" ]],
    
        /* Spec section */
        color Spec_color = 1.0,
        float Spec_amount = 0.5,
        float Glossiness = 0.6,
        float IOR = 1.33,              // Fabric generally has low frontal reflections.
        int Subdivs = 8,
        int Trace_reflections = 1
            [[ string widget = "checkBox" ]],
        int Fresnel = 1
            [[ string widget = "checkBox" ]],
       
        /* Anisotropy section */
        float Anisotropy = 0.25,         // Fabric is anisotropic due to weave.
        float Aniso_rotation = 0,
       
        /* Bump section */
        string Bump_texture = "bump.png",
        float Bump_amount = 1.0,
    
        output color result = 1 )
    
    
    {
        /* Define Bump */
        normal bumped_normal = N;
        if (Bump_amount > 0.0)
        {
            float delta = 0.004;
            color center = texture(Bump_texture, u, v);
            color uColor = texture(Bump_texture, u + delta, v);
            color vColor = texture(Bump_texture, u, v + delta);
       
            bumped_normal = getBumpedNormal(center, uColor, vColor, 1.0 / Bump_amount);
       
        }
       
    
        /* Define Main color */
            color MainColor = texture (Diffuse_color, u, v, "missingcolor", color(1,0,0));
            MainColor = pow (MainColor, 2.2);
           
        /* Define Edge color */
            color TintBoost = transformc("hsl", MainColor);
            TintBoost[2] = pow (TintBoost[2], 0.2);
            TintBoost[2] = clamp(TintBoost[2],0,1);
            TintBoost = transformc("hsl","rgb", TintBoost);
             
            color EdgeColor =  Sheen_color / 10;
            color TintEdge = EdgeColor * TintBoost;
            EdgeColor = mix (EdgeColor, TintEdge, Sheen_tint);
            EdgeColor = clamp (EdgeColor, 0, 1);
           
        /* Define Spec color */
            color SpecColor = Spec_color;
            color TintedSpec = SpecColor * TintBoost;
            SpecColor = mix (SpecColor, TintedSpec, Sheen_tint);
      
        /* Define Ramp */
       
            float facingRatio = 1 - abs(dot(I, bumped_normal));
           
            if( ramp_type == 1) // linear             
                {facingRatio = facingRatio; }
    
            if( ramp_type == 2) // exponential (Down) 
                { facingRatio *= facingRatio;  }  
    
            if( ramp_type == 3) // smooth      
                { facingRatio = smoothstep (0,1, facingRatio ); }
               
            if( ramp_type == 4) // sigmoid S-curve
                {
                float Sigmoid = facingRatio / (1 + abs(facingRatio));
                facingRatio = clamp( 2 * Sigmoid, 0, 1);
                }
            if( ramp_type == 5) //  square root   
                { facingRatio = sqrt (facingRatio); }
               
            if( ramp_type == 6) // fresnel          
                { facingRatio = 2 * fresnelReflectionFactor(bumped_normal, IOR);  }
       
       
        /* Fresnel */
            if (Fresnel)
            { SpecColor *= fresnelReflectionFactor(bumped_normal, IOR); }
            if (Trace_reflections)
            { MainColor *= (1.0 - SpecColor); }
           
        /* BRDF Mixes*/
            color SheenMix = EdgeColor * facingRatio * Sheen_opacity;
            color EdgeMask = mix(1, Sheen_color, (facingRatio * Sheen_opacity) );
            MainColor *= EdgeMask;
            MainColor *= (1.0 - SheenMix);       
               
            closure color sheen_component = SheenMix * diffuse(bumped_normal, "roughness", Roughness);
            closure color diffuse_component =  MainColor * Diffuse_weight * diffuse(bumped_normal, "roughness", Roughness);
            closure color specular_component = Spec_amount * SpecColor *       
                vray_blinn (bumped_normal, Glossiness, Anisotropy, Aniso_rotation,       
                "subdivs", Subdivs, "trace_reflections", Trace_reflections);       
                   
            closure color reflect_component = SpecColor * reflection(bumped_normal, IOR);
    
            Ci = diffuse_component + specular_component + reflect_component + sheen_component;
       
    }
    Last edited by sharktacos; 11-07-2015, 03:59 PM.

  • #2
    Nice! Can I add this to the repository of OSL shaders here?
    http://docs.chaosgroup.com/display/O...+Shaders+Home#

    Best regards,
    Vlado
    I only act like I know everything, Rogers.

    Comment


    • #3
      Originally posted by vlado View Post
      Nice! Can I add this to the repository of OSL shaders here?
      http://docs.chaosgroup.com/display/O...+Shaders+Home#

      Best regards,
      Vlado
      Absolutely!

      Comment


      • #4
        Ok, I will just add some tooltips for the parameters.

        Best regards,
        Vlado
        I only act like I know everything, Rogers.

        Comment


        • #5
          Thanks for the shader

          Comment


          • #6
            Here I've added tooltips to some parameters and renamed others to be perhaps a bit clearer:
            https://confluence.chaosgroup.com/di...Fabric+shader#

            @Derek: do you want me to add some additional information to the page (like a link to your website)?

            Best regards,
            Vlado
            I only act like I know everything, Rogers.

            Comment


            • #7
              Hello,

              I tried to use the Frabic file from OSLShaders in the V-Ray for Maya 2015 SP6, Win 8.1 (version 3.05.04, revision 25954 from Jun 29 2015) But once I load the file I get fatal error. Is there any other step that I did not understand?

              Thanks for OSL and attention!

              Comment


              • #8
                There is a bug in the OSL library that manifests itself on Windows 8.1; we've fixed this and submitted a patch, but for the moment you will need a nightly build to get it working. You can email support@chaosgroup.com to get that.

                Best regards,
                Vlado
                I only act like I know everything, Rogers.

                Comment


                • #9
                  Originally posted by vlado View Post
                  Here I've added tooltips to some parameters and renamed others to be perhaps a bit clearer:
                  https://confluence.chaosgroup.com/di...Fabric+shader#

                  @Derek: do you want me to add some additional information to the page (like a link to your website)?

                  Best regards,
                  Vlado
                  Looks great. It makes sense to rename things more explicitly as you have (Spec_glossiness instead of Glossiness etc). Hopefully once widgets are implemented in OSL one can use the "page" widget to organize the sliders the way a VrayMtl is (diffuse section, spec section, and so on).

                  The pic would look better if it were lit by a directional light (it looks like it has HDRI lighting on it now), and was on a model of draped cloth like this: http://i.ytimg.com/vi/hmPHq0WTt-k/maxresdefault.jpg

                  I'll see if I can render something, and email it to you along with the Maya scene.

                  Comment


                  • #10
                    Let me also mention that the bump map behavior is not the same as a VrayMtl. It looks to me like it is off by a factor of around 100, so to get the same bump as a vrayMtl with a bump value of 1.0 the OSL needs a bump value of 100. A quick and dirty workaround is just to add a multiplication like this:
                    Code:
                    float Bump_amount = Bump_amount * 100;
                    but I thought I'd mention it as I'm sure there must be a more elegant/accurate way to address it in the code so it matches the behavior of a VrayMtl more precisely.

                    Comment


                    • #11
                      Here's another OSL shader I thought was cool. It was originally posted in the Max forums here: http://forums.chaosgroup.com/showthr...light=gold+osl.

                      It uses the complex fresnel equation for metals, but to make it more artist friendly it remaps the refractive index (n) and extinction coefficient (k) to the more intuitive reflectivity (r) and edge tint (g) which are input as RGB colors. You use it just like the complex_IOR.osl (i.e. in a VrayOSLTex mapped to the reflection with Fresnel off).

                      I tweaked it so it would work in Maya, and hard-coded in the gamma correction:

                      Code:
                      //--Artist Friendly Metallic Fresnel--
                          // BY Ole Gulbrandsen - Framestore
                          //olegul@hotmail.com
                          //http://jcgt.org/published/0003/04/03/
                          //OSL version by JayCMiller
                          //jcmiller.web@gmail.com
                          
                      
                      float n_min( float r )
                      { return (1-r )/(1+ r ); }
                      
                      
                      float n_max( float r )
                      { return (1+ sqrt ( r ))/(1- sqrt ( r )); }
                      
                      float get_n ( float r , float g)
                      { return n_min( r )*g + (1-g)*n_max( r ); }
                      
                      
                      float get_k2 ( float r , float n)
                      { 
                      float nr = (n+1)*(n+1)*r-(n-1)*(n-1);
                      return nr/(1-r );
                      }
                      
                      float get_r ( float n, float k)
                      { return ((n-1)*(n-1)+k*k )/(( n+1)*(n+1)+k*k);  }
                      
                      float get_g ( float n, float k)
                      {
                      float r = get_r (n,k);
                      return (n_max( r)-n )/( n_max( r)-n_min( r ));
                      }
                      
                      float AFMF ( float r , float g, float theta )
                      {
                      //clamp parameters
                      float _r = clamp(r ,0 ,0.99);
                      
                      //compute n and k
                      float n = get_n (_r ,g);
                      float k2 = get_k2 (_r ,n);
                      float c = cos ( theta );
                      float rs_num = n*n + k2 - 2*n*c + c*c;
                      float rs_den = n*n + k2 + 2*n*c + c*c;
                      float rs = rs_num/ rs_den ;
                      float rp_num = (n*n + k2)*c*c - 2*n*c + 1;
                      float rp_den = (n*n + k2)*c*c + 2*n*c + 1;
                      float rp = rp_num/ rp_den ;
                      
                      return 0.5*( rs+rp );
                      }
                      
                      shader AFMFresnelTex
                      (
                      
                      color Reflectivity = color(0.9451,0.7294,0.3725),
                      color Edgetint = color(0.9961,0.9725,0.7333),
                      //float Color_Gamma = 0.4545,
                      
                      output color result = color(0.5)
                      )
                      
                      {
                      float thetaB = acos(dot(-I,N));
                      float RCH = AFMF(Reflectivity[0],Edgetint[0],thetaB);
                      float GCH = AFMF(Reflectivity[1],Edgetint[1],thetaB);
                      float BCH = AFMF(Reflectivity[2],Edgetint[2],thetaB);
                      
                      
                      //result = pow(color(RCH,GCH,BCH), 1/Color_Gamma);
                      
                      result = pow(color(RCH,GCH,BCH), 2.2);
                      
                      }

                      Comment


                      • #12
                        Joconnell asked elsewhere
                        Actually that's a thing too - your cloth shader looks great, do you have any links for intro to osl stuff or did you just jump in and start messing with other peoples examples?
                        What I basically did was create shader in Maya by connecting a bunch of stuff in the Hypershade of Maya to mock it up, then I built that in OSL, adding more functionality as I went beyond what I could do with just a node tree.

                        Here are some links to stuff that helped me get my head around OSL:

                        Manuals First is the Chaos OSL help.
                        One thing to note is a lot of the metadata widgets are not yet implemented yet which impact the user interface (sliders, dropdown menus, etc). Also the print functions do not currently work which would help a lot with debugging. Now it either works or doesn't with no way to know what is broken.

                        Next is the official manual: SPI OSL manual (pdf)

                        Examples the next thing, as you said, is to learn from examples of what other folks are doing.
                        First up, of course, are the examples from Chaos: Chaos OSL respository
                        Then there are lots of Maya nodes here OpenMaya example OSL (remember that as the Chaos help says "The VRayOSLMtl takes into account only closure color output parameters." So all of these need to have the output changed to color so they will work)
                        and some fun textures here Sambler example OSL dfggd
                        and some examples from Sony too SPI example OSL

                        Since OSL is C-based, it's pretty easy to take a shader from a paper that was written in C++ and re-write it in OSL which means all those Siggraph papers with new cool functionality can be used in Vray with OSL.

                        Comment


                        • #13
                          You're a superstar - much appreciated for that.

                          Comment


                          • #14
                            Originally posted by sharktacos View Post
                            One thing to note is a lot of the metadata widgets are not yet implemented yet which impact the user interface (sliders, dropdown menus, etc).
                            Drop-down menus actually do work in the latest builds - you used that in the fabric shader...

                            Best regards,
                            Vlado
                            I only act like I know everything, Rogers.

                            Comment


                            • #15
                              Originally posted by vlado View Post
                              Drop-down menus actually do work in the latest builds - you used that in the fabric shader...

                              Best regards,
                              Vlado

                              LOL, I put the code in, but it was not working in my version. I'm glad it is now.
                              I looked in the release notes in the nightlies and I do not see this mentioned there. Where could I get a list of the changes to OSL that have been implemented?

                              Comment

                              Working...
                              X