Adobe Standard Material Definition (ASM) shader
Import from libraries.
Copied to your clipboardimport lib-pbr.glslimport lib-pbr-aniso.glsl//: param custom {//: "group": "Base Surface",//: "label": "Enable anisotropy",//: "default": false,//: "asm": "anisotropy",//: "description": "<html><head/><body><p>Allows reflections to stretch in one direction along the surface.<br/><b>Please note</b>: The following channels need to be present for this parameter to have an effect: <b>Anisotropy angle</b> and <b>Anisotropy level</b>.</p></body></html>"//: }uniform_specialization bool anisotropyEnabled;//: param custom {//: "group": "Base Surface",//: "label": "Index of refraction",//: "min": 0.0,//: "max": 40.0,//: "default": 1.5,//: "asm": "specular_ior",//: "description": "<html><head/><body><p>The amount light bends as it passes through the object. Also affects the specular reflection intensity.</p></body></html>"//: }uniform float specularIoR;//: param custom {//: "group": "Base Surface",//: "label": "Enable edge color",//: "default": false,//: "asm": "specular_edge_color",//: "description": "<html><head/><body><p>Allows specifying the color of light reflections. Affects glancing angles for metallic materials.<br/><b>Please note</b>: The following channel needs to be present for this parameter to have an effect: <b>Specular edge color</b></p></body></html>"//: }uniform_specialization bool specularEdgeColorEnabled;import lib-sheen.glsl//: param custom {//: "group": "Geometry",//: "label": "Double sided",//: "default": false,//: "description": "<html><head/><body><p>When enabled, the surface is visible on both sides, i.e. back-face culling is disabled.</p></body></html>"//: }uniform_specialization bool doubleSided;import lib-pom.glslimport lib-bent-normal.glsl//: param custom {//: "group": "Interior",//: "label": "Enable translucency",//: "default": false,//: "asm": "translucency",//: "description": "<html><head/><body><p>Allows for refractive transmission of light through the surface.<br/><b>Please note</b>: The following channel needs to be present for this parameter to have an effect: <b>Translucency</b></p></body></html>",//: "enable": "!input.sssEnabled",//: "description_disabled": "<html><head/><body><p>Disable the <b>Subsurface Scattering</b> to use <b>Translucency</b>.</p></body></html>"//: }uniform_specialization bool translucencyEnabled;import lib-sss.glsl//: param custom {//: "group": "Interior",//: "label": "Enable absorption",//: "default": false,//: "asm": "absorption_color",//: "description": "<html><head/><body><p>Filters the light that passes through the volume by absorbing certain colors. Affects both translucency and subsurface scattering.<br/><b>Please note</b>: The following channel needs to be present for this parameter to have an effect: <b>Absorption color</b></p></body></html>",//: "visible": "input.translucencyEnabled || input.sssEnabled"//: }uniform_specialization bool absorptionEnabled;import lib-alpha-test.glsl//: param custom {//: "group": "Geometry/Opacity",//: "label": "Enable alpha blending",//: "default": false,//: "asm": "opacity",//: "description": "<html><head/><body><p>Uses the opacity texture to progressively blend the transparent surface over the background.<br/><b>Please note</b>: The following channel needs to be present for this parameter to have an effect: <b>Opacity</b></p></body></html>",//: "enable": "!input.sssEnabled",//: "description_disabled": "<html><head/><body><p>Disable the <b>Subsurface Scattering</b> to use <b>Alpha blending</b>.</p></body></html>"//: }uniform_specialization bool alphaBlendEnabled;import lib-coat.glslimport lib-utils.glsl
Declare the iray mdl material to use with this shader.
Copied to your clipboard//: metadata {//: "mdl":"mdl::alg::materials::painter::standard"//: }
Disable culling if double sided option is enabled
Copied to your clipboard//: state cull_face off {"enable":"input.doubleSided"}
Enable 'over' alpha blending if opacity alpha blend
Copied to your clipboard//: state blend over {"enable":"input.alphaBlendEnabled && !input.sssEnabled && !input.translucencyEnabled"}
Enable 'premultiplied over' alpha blending if translucency
Copied to your clipboard//: state blend over_premult {"enable":"input.translucencyEnabled && !input.absorptionEnabled && !input.sssEnabled"}
Enable 'add multiply' alpha blending if absorption is required
Copied to your clipboard//: state blend add_multiply {"enable":"input.translucencyEnabled && input.absorptionEnabled && !input.sssEnabled"}
Channels needed for metal/rough workflow are bound here.
Copied to your clipboard//: param auto channel_basecoloruniform SamplerSparse basecolor_tex;//: param auto channel_roughnessuniform SamplerSparse roughness_tex;//: param auto channel_metallicuniform SamplerSparse metallic_tex;//: param auto channel_anisotropyleveluniform SamplerSparse anisotropylevel_tex;//: param auto channel_anisotropyangleuniform SamplerSparse anisotropyangle_tex;//: param auto channel_specularleveluniform SamplerSparse specularlevel_tex;//: param auto channel_specularedgecoloruniform SamplerSparse specularedgecolor_tex;//: param auto channel_absorptioncoloruniform SamplerSparse absorptioncolor_tex;
Shader entry point.
Copied to your clipboardvoid shade(V2F inputs){// Apply parallax occlusion mapping if possiblevec3 viewTS = worldSpaceToTangentSpace(getEyeVec(inputs.position), inputs);applyParallaxOffset(inputs, viewTS);// Fetch material parameters, and conversion to the specular/roughness modelfloat baseRoughness = getRoughness(roughness_tex, inputs.sparse_coord);float anisotropyLevel = 0.0;float anisotropyAngle = 0.0;if (anisotropyEnabled) {anisotropyLevel = getAnisotropyLevel(anisotropylevel_tex, inputs.sparse_coord);if (anisotropyLevel > 0.0) {anisotropyAngle = getAnisotropyAngle(anisotropyangle_tex, inputs.sparse_coord);}}vec3 baseColor = getBaseColor(basecolor_tex, inputs.sparse_coord);float metallic = getMetallic(metallic_tex, inputs.sparse_coord);vec3 diffColor = generateDiffuseColor(baseColor, metallic);float specularLevel = getSpecularLevel(specularlevel_tex, inputs.sparse_coord);vec3 specColor_metal = baseColor;float dielectricF0 = iorToSpecularLevel(1.0, specularIoR);float coatOpacity = 0.0;if (coatEnabled) {coatOpacity = getCoatOpacity(coatOpacity_tex, inputs.sparse_coord);if (coatOpacity > 0.0) {float underCoatF0 = iorToSpecularLevel(coatIoR, specularIoR);dielectricF0 = mix(dielectricF0, underCoatF0, coatOpacity);}}vec3 specColor_dielectric = vec3(dielectricF0 * 2.0 * specularLevel);// Get detail (ambient occlusion) and global (shadow) occlusion factors// separately in order to blend the bent normals properlyfloat shadowFactor = getShadowFactor();float occlusion = getAO(inputs.sparse_coord, true, use_bent_normal);float specOcclusion = specularOcclusionCorrection(use_bent_normal ? shadowFactor : occlusion * shadowFactor,metallic,baseRoughness);vec3 normal = computeWSNormal(inputs.sparse_coord,inputs.tangent, inputs.bitangent, inputs.normal);LocalVectors vectors = computeLocalFrame(inputs, normal, anisotropyAngle);computeBentNormal(vectors,inputs);// Diffuse lobe:vec3 diffuseShading = occlusion * shadowFactor * envIrradiance(getDiffuseBentNormal(vectors));// Specular lobes:// The specs can be interpreted as interpolating between two lobes.// However, due to the prohibitive cost for real-time, we interpolate// between two specular colors and use it for a single specular lobe.vec3 specColor = mix(specColor_dielectric, specColor_metal, metallic);vec3 specSecondaryColor = vec3(1.0);if (specularEdgeColorEnabled) {specSecondaryColor = getSpecularEdgeColor(specularedgecolor_tex, inputs.sparse_coord);}vec3 specEdgeColor = mix(vec3(1.0), specSecondaryColor, metallic);vec3 specColoring = mix(vec3(1.0), specSecondaryColor, 1.0 - metallic);vec3 specReflection = vec3(0.0);if (anisotropyEnabled) {vec2 roughnessAniso = generateAnisotropicRoughnessASM(baseRoughness, anisotropyLevel);specReflection = pbrComputeSpecularAnisotropic(vectors,specColor,specEdgeColor,roughnessAniso,occlusion,getBentNormalSpecularAmount());}else {specReflection = pbrComputeSpecular(vectors,specColor,specEdgeColor,baseRoughness,occlusion,getBentNormalSpecularAmount());}vec3 specularShading = specOcclusion * specColoring * specReflection;// Sheen:if (sheenEnabled) {float sheenOpacity = getSheenOpacity(sheenOpacity_tex, inputs.sparse_coord);if (sheenOpacity > 0.0) {float sheenRoughness = getSheenRoughness(sheenRoughness_tex, inputs.sparse_coord);vec3 sheenColor = sheenOpacity * getSheenColor(sheenColor_tex, inputs.sparse_coord);vec3 sheenSpecularShading = pbrComputeSheen(vectors, sheenColor, sheenRoughness);specularShading += specOcclusion * sheenSpecularShading;}}// Coating:// Keep track of coat absorption quantity to know how much to reduce contribution for lower layersvec3 coatAbsorption = vec3(1.0);if (coatOpacity > 0.0) {vec3 coatNormal = getWSCoatNormal(inputs.sparse_coord,inputs.tangent, inputs.bitangent, inputs.normal);LocalVectors coatVectors = computeLocalFrame(inputs, coatNormal, 0.0);vec3 coatColor = getCoatColor(coatColor_tex, inputs.sparse_coord);float coatSpecularLevel = getCoatSpecularLevel(coatSpecularLevel_tex, inputs.sparse_coord);vec3 coatSpecColor = vec3(iorToSpecularLevel(1.0, coatIoR) * 2.0 * coatSpecularLevel);float coatRoughness = getCoatRoughness(coatRoughness_tex, inputs.sparse_coord);float coatSpecOcclusion = specularOcclusionCorrection(occlusion * shadowFactor, 0.0, coatRoughness);vec3 coatSpecularShading = pbrComputeSpecular(coatVectors, coatSpecColor, coatRoughness);float ndv = clamp(dot(coatVectors.normal, vectors.eye), 1e-4, 1.0);coatAbsorption = coatPassageColorMultiplier(coatColor, coatOpacity, ndv);coatAbsorption *= coatAbsorption;diffuseShading *= coatAbsorption;specularShading *= coatAbsorption;specularShading += (coatSpecOcclusion * coatOpacity) * coatSpecularShading;}albedoOutput(diffColor);vec3 emissiveShading = pbrComputeEmissive(emissive_tex, inputs.sparse_coord);// Blending related effectsif ((translucencyEnabled || alphaBlendEnabled) && !sssEnabled) {float alpha = 1.0;// Opacity cut-throughif (alphaBlendEnabled) {alpha = getOpacity(opacity_tex, inputs.sparse_coord);}// Refractive transmissionif (translucencyEnabled) {// Blending premultiplied over: must premultiply contributions manuallyemissiveShading *= alpha;specularShading *= alpha;diffuseShading *= alpha;float translucency = getTranslucency(sss_translucency_tex, inputs.sparse_coord) * (1.0-metallic);diffuseShading *= 1.0-translucency;vec3 absorption = vec3(1.0);if (absorptionEnabled) {// Absorption use dual output blending modeabsorption = coatAbsorption * getAbsorptionColor(absorptioncolor_tex, inputs.sparse_coord);color1Output(vec4(vec3(1.0)-alpha*(vec3(1.0)-absorption*translucency*(1.0-baseRoughness)), 1.0));}// Approximation: roughness cutoff the transparencydiffuseShading += absorption * alpha * baseRoughness * translucency * envIrradiance(-vectors.normal);alpha *= 1.0-(translucency*(1.0-baseRoughness));}alphaOutput(alpha);}emissiveColorOutput(emissiveShading);diffuseShadingOutput(diffuseShading);specularShadingOutput(specularShading);sssCoefficientsOutput(getSSSCoefficients(inputs.sparse_coord));vec4 baseSSSColor = getSSSColor(inputs.sparse_coord);if (usesSSSScatteringColorChannel()) {// Must be dimmed by metallic factor as for diffuse colorbaseSSSColor.rgb = generateDiffuseColor(baseSSSColor.rgb, metallic);}if (sssEnabled && absorptionEnabled) {// Combine absorption color with scattering color if both enabledbaseSSSColor.rgb *= getAbsorptionColor(absorptioncolor_tex, inputs.sparse_coord);}sssColorOutput(baseSSSColor);// Discard current fragment on the basis of the opacity channel// and a user defined thresholdalphaKill(inputs.sparse_coord);}