src/testrender/shading.cpp
// recursively walk through the closure tree, creating bsdfs as we go
recursively walk through the closure tree, creating bsdfs as we go
recursively walk through the closure tree creating bsdfs as we go
void process_closure (ShadingResult& result, const ClosureColor* closure, const Color3& w, bool light_only) {
   static const ustring u_ggx("ggx");
   static const ustring u_beckmann("beckmann");
   static const ustring u_default("default");
   if (!closure)
       return;
   switch (closure->id) {
       case ClosureColor::MUL: {
           Color3 cw = w * closure->as_mul()->weight;
           process_closure(result, closure->as_mul()->closure, cw, light_only);
           break;
       }
       case ClosureColor::ADD: {
           process_closure(result, closure->as_add()->closureA, w, light_only);
           process_closure(result, closure->as_add()->closureB, w, light_only);
           break;
       }
       default: {
           const ClosureComponent* comp = closure->as_comp();
           Color3 cw = w * comp->w;
           if (comp->id == EMISSION_ID)
               result.Le += cw;
           else if (!light_only) {
               bool ok = false;
               switch (comp->id) {
                   case DIFFUSE_ID:            ok = result.bsdf.add_bsdf<Diffuse<0>, DiffuseParams   >(cw, *comp->as<DiffuseParams>  ()); break;
                   case OREN_NAYAR_ID:         ok = result.bsdf.add_bsdf<OrenNayar , OrenNayarParams >(cw, *comp->as<OrenNayarParams>()); break;
                   case TRANSLUCENT_ID:        ok = result.bsdf.add_bsdf<Diffuse<1>, DiffuseParams   >(cw, *comp->as<DiffuseParams>  ()); break;
                   case PHONG_ID:              ok = result.bsdf.add_bsdf<Phong     , PhongParams     >(cw, *comp->as<PhongParams>    ()); break;
                   case WARD_ID:               ok = result.bsdf.add_bsdf<Ward      , WardParams      >(cw, *comp->as<WardParams>     ()); break;
                   case MICROFACET_ID: {
                       const MicrofacetParams* mp = comp->as<MicrofacetParams>();
                       if (mp->dist == u_ggx) {
                           switch (mp->refract) {
                               case 0: ok = result.bsdf.add_bsdf<MicrofacetGGXRefl, MicrofacetParams>(cw, *mp); break;
                               case 1: ok = result.bsdf.add_bsdf<MicrofacetGGXRefr, MicrofacetParams>(cw, *mp); break;
                               case 2: ok = result.bsdf.add_bsdf<MicrofacetGGXBoth, MicrofacetParams>(cw, *mp); break;
                           }
                       } else if (mp->dist == u_beckmann || mp->dist == u_default) {
                           switch (mp->refract) {
                               case 0: ok = result.bsdf.add_bsdf<MicrofacetBeckmannRefl, MicrofacetParams>(cw, *mp); break;
                               case 1: ok = result.bsdf.add_bsdf<MicrofacetBeckmannRefr, MicrofacetParams>(cw, *mp); break;
                               case 2: ok = result.bsdf.add_bsdf<MicrofacetBeckmannBoth, MicrofacetParams>(cw, *mp); break;
                           }
                       }
                       break;
                   }
                   case REFLECTION_ID:
                   case FRESNEL_REFLECTION_ID: ok = result.bsdf.add_bsdf<Reflection , ReflectionParams>(cw, *comp->as<ReflectionParams>()); break;
                   case REFRACTION_ID:         ok = result.bsdf.add_bsdf<Refraction , RefractionParams>(cw, *comp->as<RefractionParams>()); break;
                   case TRANSPARENT_ID:        ok = result.bsdf.add_bsdf<Transparent, int             >(cw, 0); break;
               }
               OSL_ASSERT(ok && "Invalid closure invoked in surface shader");
           }
           break;
       }
   }
}
void process_closure ( ShadingResult & result , const ClosureColor * closure , const Color3 & w , bool light_only ) { static const ustring u_ggx ( " " ) ; static const ustring u_beckmann ( " " ) ; static const ustring u_default ( " " ) ; if ( ! closure ) return ; switch ( closure -> id ) { case ClosureColor :: MUL : { Color3 cw = w * closure -> as_mul ( ) -> weight ; process_closure ( result , closure -> as_mul ( ) -> closure , cw , light_only ) ; break ; } case ClosureColor :: ADD : { process_closure ( result , closure -> as_add ( ) -> closureA , w , light_only ) ; process_closure ( result , closure -> as_add ( ) -> closureB , w , light_only ) ; break ; } default : { const ClosureComponent * comp = closure -> as_comp ( ) ; Color3 cw = w * comp -> w ; if ( comp -> id == EMISSION_ID ) result . Le += cw ; else if ( ! light_only ) { bool ok = false ; switch ( comp -> id ) { case DIFFUSE_ID : ok = result . bsdf . add_bsdf < Diffuse < 0 > , DiffuseParams > ( cw , * comp -> as < DiffuseParams > ( ) ) ; break ; case OREN_NAYAR_ID : ok = result . bsdf . add_bsdf < OrenNayar , OrenNayarParams > ( cw , * comp -> as < OrenNayarParams > ( ) ) ; break ; case TRANSLUCENT_ID : ok = result . bsdf . add_bsdf < Diffuse < 1 > , DiffuseParams > ( cw , * comp -> as < DiffuseParams > ( ) ) ; break ; case PHONG_ID : ok = result . bsdf . add_bsdf < Phong , PhongParams > ( cw , * comp -> as < PhongParams > ( ) ) ; break ; case WARD_ID : ok = result . bsdf . add_bsdf < Ward , WardParams > ( cw , * comp -> as < WardParams > ( ) ) ; break ; case MICROFACET_ID : { const MicrofacetParams * mp = comp -> as < MicrofacetParams > ( ) ; if ( mp -> dist == u_ggx ) { switch ( mp -> refract ) { case 0 : ok = result . bsdf . add_bsdf < MicrofacetGGXRefl , MicrofacetParams > ( cw , * mp ) ; break ; case 1 : ok = result . bsdf . add_bsdf < MicrofacetGGXRefr , MicrofacetParams > ( cw , * mp ) ; break ; case 2 : ok = result . bsdf . add_bsdf < MicrofacetGGXBoth , MicrofacetParams > ( cw , * mp ) ; break ; } } else if ( mp -> dist == u_beckmann || mp -> dist == u_default ) { switch ( mp -> refract ) { case 0 : ok = result . bsdf . add_bsdf < MicrofacetBeckmannRefl , MicrofacetParams > ( cw , * mp ) ; break ; case 1 : ok = result . bsdf . add_bsdf < MicrofacetBeckmannRefr , MicrofacetParams > ( cw , * mp ) ; break ; case 2 : ok = result . bsdf . add_bsdf < MicrofacetBeckmannBoth , MicrofacetParams > ( cw , * mp ) ; break ; } } break ; } case REFLECTION_ID : case FRESNEL_REFLECTION_ID : ok = result . bsdf . add_bsdf < Reflection , ReflectionParams > ( cw , * comp -> as < ReflectionParams > ( ) ) ; break ; case REFRACTION_ID : ok = result . bsdf . add_bsdf < Refraction , RefractionParams > ( cw , * comp -> as < RefractionParams > ( ) ) ; break ; case TRANSPARENT_ID : ok = result . bsdf . add_bsdf < Transparent , int > ( cw , 0 ) ; break ; } OSL_ASSERT ( ok && " " ) ; } break ; } } }
recursively walk through the closure tree, creating bsdfs as we go
recursively walk through the closure tree creating bsdfs as we go