/* * * fabric.osl shader by Derek Flood (c)2015 * from http://docs.sharktacos.com/vray/osl.html * version 1.5 uses GTR with small tail falloff to get better spec. * */ color getTextureDif(string texture_name, color no_texture_default_color) { int channels = -1; if (gettextureinfo(texture_name, "channels", channels)) { return texture(texture_name, u, v); } return no_texture_default_color; } 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 getBumpedBump(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); } normal getBumpedNormal(color compressedNormalSample, float Bump_amount) { vector worldTangent = normalize(dPdu); vector worldBitangent = normalize(dPdv); vector worldNormal = normalize(N); color normalSample = 2.0 * compressedNormalSample - 1.0; normalSample *= color(Bump_amount, Bump_amount, 1.0); return normalize(normalSample[0] * worldTangent + normalSample[1] * worldBitangent + normalSample[2] * worldNormal); } surface fabricMtl [[ string description = "artist based fabric material" ]] ( /* Diffuse section */ string Sheen_color = "sheen.png" [[ string description = "Sheen color can be black for nylon sheen." ]], float Sheen_opacity = 1.0 [[ string description = "Determines amount of sheen effect as fibres pick up light at incident angle." ]], float Sheen_tint = 0.5 [[ string description = "Tints both the sheen and specular." ]], int Sheen_ramp_type = 3 [[ string widget = "mapper", string description = "Six types of interpolation for sheen: Linear(1), Exponential(2), Smooth(3), Sigmoid(4), Square Root(5), Fresnel(6).", string options = "linear:1|Exponential:2|Smooth:3|Sigmoid:4|Square_root:5|Fresnel:6" ]], string Diffuse_color = "color.png", float Diffuse_weight = 0.8, float Diffuse_roughness = 0.4, /* Spec section */ string Spec_color = "specular.png", float Spec_amount = 0.5, float Spec_glossiness = 0.6, float Spec_tail = 1 [[ string description = "GTR tail below 1.0 gives nice cloth-like sheen to the spec." ]], float IOR = 1.33 [[ string description = "Determines the strength of Fresnel reflections; fabric generally has low frontal reflections." ]], int Subdivs = 8, int Trace_reflections = 1 [[ string widget = "checkBox" ]], /* Anisotropy section */ float Anisotropy = 0.25 [[ string description = "Fabric is anisotropic due to weave." ]], float Aniso_rotation = 0, /* Bump section */ // Disabling bump until it is fixed in OSL for Vray. Use VrayBumpMtl instead // string Bump_Map = "normal.png", // float Bump_amount = 1.0, // int Normal_Mapping = 0 // [[ string widget = "checkBox" ]], float Texture_gamma = 1.0, output color result = 1 ) { /* Define Bump */ normal bumped_normal = N; // Disabling bump until it is fixed in OSL for Vray. Use VrayBumpMtl instead /* float BumpAmount = clamp (Bump_amount,0.001,10); if ( Normal_Mapping == 1 ) { color compressedNormalSample = getTextureDif(Bump_Map, color(0.5,0.5,1)); bumped_normal = getBumpedNormal(compressedNormalSample, BumpAmount); } else { float delta = 0.004; color center = texture(Bump_Map, u, v); color uColor = texture(Bump_Map, u + delta, v); color vColor = texture(Bump_Map, u, v + delta); float BumpAmount = BumpAmount * 10; bumped_normal = getBumpedBump(center, uColor, vColor, 1.0 / BumpAmount); } */ /* Define Main color */ color MainColor = getTextureDif(Diffuse_color, color(0.5,0.2,0.2)); MainColor = pow (MainColor, Texture_gamma); /* Define Sheen */ color SheenTint = Sheen_tint * 2; // intensify tint amount color TintBoost = transformc("hsl", MainColor); TintBoost[2] = TintBoost[2] + 0.5; // make the tint (2=luminance) a brighter version of the mainColor TintBoost[2] = clamp(TintBoost[2],0,1); // clamp tint luminance TintBoost = transformc("hsl","rgb", TintBoost); /* read in sheen color and modify it with tint */ color SheenColor = getTextureDif(Sheen_color, color(1,1,1)); color EdgeColor = SheenColor / 2; //dim sheen value color TintEdge = EdgeColor * TintBoost; //colorize sheen with the tint EdgeColor = mix (EdgeColor, TintEdge, SheenTint); //mix between tinted & untinted sheen based on tint value EdgeColor = clamp (EdgeColor, 0, 1); /* Define Spec */ color SpecColor = getTextureDif(Spec_color, color(1,1,1)); /* mix between tinted & untinted spec based on tint value */ color TintedSpec = SpecColor * TintBoost; SpecColor = mix (SpecColor, TintedSpec, SheenTint); float Roughness = 0; /* Define Ramps */ float facingRatio = 1 - abs(dot(I, bumped_normal)); if( Sheen_ramp_type == 1) // linear {facingRatio = facingRatio; } if( Sheen_ramp_type == 2) // exponential (Down) { facingRatio *= facingRatio; } if( Sheen_ramp_type == 3) // smooth { facingRatio = smoothstep (0,1, facingRatio ); } if( Sheen_ramp_type == 4) // sigmoid S-curve { float Sigmoid = facingRatio / (1 + abs(facingRatio)); facingRatio = clamp( 2 * Sigmoid, 0, 1); } if( Sheen_ramp_type == 5) // square root { facingRatio = sqrt (facingRatio); } if( Sheen_ramp_type == 6) // fresnel { facingRatio = 2 * fresnelReflectionFactor(bumped_normal, IOR); } /* BRDF Mixes*/ color SheenMix = EdgeColor * facingRatio * Sheen_opacity; color EdgeMask = mix(1, SheenColor, (facingRatio * Sheen_opacity) ); MainColor *= EdgeMask; MainColor *= (1.0 - SheenMix); SpecColor *= EdgeMask; closure color sheen_component = SheenMix * diffuse(bumped_normal, "roughness", Diffuse_roughness); closure color diffuse_component = MainColor * Diffuse_weight * diffuse(bumped_normal, "roughness", Diffuse_roughness); closure color specGTR = Spec_amount * SpecColor * microfacet_ggx (bumped_normal, Roughness, IOR, "gtr_gamma", Spec_tail, "subdivs", Subdivs, "reflection_glossiness", Spec_glossiness, "highlight_glossiness", Spec_glossiness, "anisotropy", Anisotropy, "aniso_rotation", Aniso_rotation, "trace_reflections", Trace_reflections ); Ci = diffuse_component + specGTR + sheen_component; }