April 4-7, 2016 | Silicon Valley SIGGRAPH’16 : NVIDIA BEST OF GTC MDL MATERIALS TO GLSL SHADERS Andreas Süßenbach, NVIDIA Andreas Mank, ESI Group www.esi-group.com
“ S6311 MDL Materials to GLSL Shaders . Theory and Practice. ” http://on-demand.gputechconf.com/gtc/2016/video/S6311.html 2
MDL IN CUSTOM RENDERERS MATERIAL DEFINITION IMPLEMENTATION MATERIAL TWEAKING CONSTRUCTION MDL SDK NVIDIA IRAY MATERIAL SHARING (LIBRARY) 20.07.2016 7/20/2016 3
MATERIAL CREATION 4
RASTERIZER RAY TRACER Shadows Reflections Walnut Silver Car paint RASTERIZER VS. RAY TRACER 5
RASTERIZER RAY TRACER Shadows Reflections Walnut Silver Car paint RASTERIZER VS. RAY TRACER 6
RASTERIZER RAY TRACER Shadows Reflections Walnut Silver Car paint RASTERIZER VS. RAY TRACER 7
RASTERIZER RAY TRACER Shadows Reflections Walnut Silver Car paint RASTERIZER VS. RAY TRACER 8
RASTERIZER RAY TRACER Shadows Reflections Walnut Silver Car paint RASTERIZER VS. RAY TRACER 9
RASTERIZER RAY TRACER Shadows Reflections Walnut Silver Car paint RASTERIZER VS. RAY TRACER 10
NEXT STEPS Measured Materials and Photometric Lights by courtesy of X-RITE GTC EUROPE / AMSTERDAMM 28-29 SEP 2016 11
What is MDL, what is the MDL SDK ? AGENDA How do I use the MDL SDK ? How do I map MDL materials to GLSL shaders ? 12
WHAT IS MDL, WHAT IS THE MDL SDK ? 13
WHAT IS MDL ? Declarative language to specify visual material properties No shader language ! Renderer agnostic export material tintedStuff( color parTint = color(.6,.2,.2) ) = material ( surface: material_surface( scattering: df::specular_bsdf( tint: parTint ) ) ); 14
MDL MATERIAL FIELDS material_surface: material_surface: surface backface bsdf: bool: bsdf: scattering scattering thin_walled material_emission: material_emission: emission emission material_geometry material_volume float3: displacement vdf: scattering color: ior float: cutout_opacity absorption_coefficient float3: normal scattering_coefficient 15
WHAT IS THE MDL SDK ? A dynamic library providing a C++ API Used to load and compile MDL materials Can be used to create and modify materials as well Used to get detailed information out of the compiled material 16
HOW DO I USE THE MDL SDK ? 17
USING MDL SDK 1/5 Initializing HINSTANCE dll = LoadLibrary("libmdl_sdk.dll"); Material Compiling INeuray_factory* factory = (INeuray_factory*)GetProcAddress(dll,"mi_neuray_factory"); Material Parsing mi::base::Handle<mi::neuraylib::INeuray> neuray = factory(0,MI_NEURAYLIB_API_VERSION ); Expression Parsing mi::base::Handle<mi::neuraylib::IMdl_compiler> mdlCompiler = neuray->get_api_component<mi::neuraylib::IMdl_compiler>(); Call Parsing 18
USING MDL SDK 2/5 Initializing mi::Sint32 reason = mdlCompiler->load_module ("::nvidia::vMaterials::AEC::Concrete::concrete_blocks"); mi::base::Handle<const mi::neuraylib::IModule> module( Material mdlCompiler->access<mi::neuraylib::IModule>( Compiling "mdl::nvidia::vMaterials::AEC::Concrete::concrete_blocks")); for ( mi::Size i=0 ; i<module->get_material_count() ; i++ ) { mi::base::Handle<mi::neuraylib::IMaterial_definition const> Material Parsing materialDefinition(mdlCompiler->access <mi::neuraylib::IMaterial_definition>(module->get_material(i)); mi::base::Handle<mi::neuraylib::IMaterial_instance> materialInstance (materialDefinition->create_material_instance(0,&result)); Expression mi::base::Handle<mi::neuraylib::ICompiled_material> compiledMaterial Parsing (materialInstance->create_compiled_material (mi::neuraylib::IMaterial_instance::CLASS_COMPILATION,1.0f ,&result); } Call Parsing 19
USING MDL SDK 3/5 Initializing for (mi::Size i=0; i<compiledMaterial->get_parameter_count(); i++) { char const* parameterName = compiledMaterial-> Material get_parameter_name(i); Compiling mi::base::Handle<mi::neuraylib::IValue const> value (compiledMaterial->get_argument(i)); } for (mi::Size i=0; i<compiledMaterial->get_temporary_count(); i++) Material Parsing { mi::base::Handle<mi::neuraylib::IExpression const> expression (compiledMaterial->get_temporary(i)); Expression } Parsing mi::base::Handle<mi::neuraylib::IExpression const> surfaceExpression (compiledMaterial->get_field("surface")); mi::base::Handle<mi::neuraylib::IExpression const> backfaceExpression Call Parsing (compiledMaterial->get_field( „backface ")); 20
USING MDL SDK 4/5 switch( expression->get_kind() ) Initializing { case mi::neuraylib::IExpression::EK_CONSTANT: Material ... Compiling break; case mi::neuraylib::IExpression::EK_PARAMETER: ... Material Parsing break; case mi::neuraylib::IExpression::EK_TEMPORARY: ... Expression break; Parsing case mi::neuraylib::IExpression::EK_DIRECT_CALL: ... break; Call Parsing } 21
USING MDL SDK 5/5 Initializing Material mi::base::Handle<mi::neuraylib::IType const> type(call-> Compiling get_type()); mi::base::Handle<mi::neuraylib::IExpression_list const> arguments (call->get_arguments()); for (mi::Size i=0; i<arguments->get_size(); i++) Material Parsing { char const* name = arguments->get_name(i); mi::base::Handle<mi::neuraylib::IExpression const> argument Expression (arguments->get_expression(i)); Parsing } Call Parsing 22
MDL SDK: MAP MDL TO AN EXPRESSION TREE MDL Material Expression Tree tintedStuff export material tintedStuff( color parTint = color(.6,.2,.2) ) = material surface backface ( surface: material_surface( scattering: df::specular_bsdf( tint: parTint ) ) ); scattering emission scattering emission 23
SIMPLIFY YOUR WORK: MDLTokenzier Simple C++ class to derive from About 40 pure virtual functions (visitor pattern) Simple string and value based interface “Guides” you through the Expression tree of a material Hides all the intricacies of the MDL SDK If you just want to convert MDL Materials into something 24
HOW DO I MAP MDL MATERIALS TO GLSL SHADERS ? 25
MAPPING MDL TO GLSL Function Calls GLSL Snippets 26
GLSL SNIPPETS: FUNCTIONS float mdl_math_minValue( in vec3 a ) { return( min( min( a.x, a.y ), a.z ) ); } vec4 mdl_df_weightedLayer( in float weight, in vec4 layer, in vec4 base ) { return( mix( base, layer, weight ) ); } 27
GLSL SNIPPETS: BSDF 28
GLSL SNIPPETS A snippet per BSDF (currently, there are 6 different) A snippet for each function (currently, there are about 50) A snippet for some commonly used helper functions -> about 80 snippets 29
MAPPING MDL TO GLSL Function Calls GLSL Snippets Expression Trees Stitched Snippets 30
EXPRESSION TREE TO GLSL functionCall arg0 nextCall yetAnotherCall X Y z nestedCall y x float functionCall(...) {...} int nextCall(...) {...} float yetAnotherCall(...) {...} int nextedCall(...) {...} ... functionCall(arg0,nextCall(x,y,z),yetAnotherCall(nestedCall(x),y)); 31
GLSL SNIPPETS: WHAT TO DO WITH THEM ? Fixed shader skeletons !! Call some functions in those skeletons Fill the bodies of those functions with some stitched snippets - > resembles kind of “virtual function calls” 32
MASTER FRAGMENT SHADER void main(void) } { materialIOR = 1.0f / materialIOR; stateNormal = normalize(varNormal); } if (! gl_FrontFacing) rgba = vec4(materialEmissive, 0.0f); { if (0 < sys_NumLights) stateNormal = - stateNormal; { } vec3 lightAmbient; texCoord0 = varTexCoord0; for (int i=0; i<sys_NumLights; i++) tangent = normalize(varTangent); { binormal = normalize(varBinormal); sampleLight(sys_Lights[i], varWorldPos, lightDir, viewDir = normalize(varEyePos - varWorldPos); lightAmbient, lightDiffuse, lightSpecular); vec4 rgba = vec4(0.0f, 0.0f, 0.0f, 0.0f); rgba += useFront ? evalColorFront (normal) : if (0.0f < evalCutoutOpacity (stateNormal)) evalColorBack (normal); { } vec3 normal = evalNormal (normal); rgba.a /= sys_NumLights; materialIOR = evalIOR (normal); } vec3 materialEmissive = vec3(0.0f, 0.0f, 0.0f); else bool useFront = gl_FrontFacing; { if (useFront) rgba.a = 1.0f; { } materialEmissive = evalMaterialEmissiveFront (normal); rgba.a *= alphaCutout; } if (0.0f < rgba.a) else { { lightDir = reflect(-viewDir, normal); // there's no emission on the back-side, unless rgba.rgb += (useFront ? evalEnvironmentFront (normal) : thinWalled is true evalEnvironmentBack (normal)).rgb; useFront = !evalThinWalled(); } if (!useFront) } { emitColor(rgba); materialEmissive = evalMaterialEmissiveBack (normal); } 33
FRAGMENT SHADER DETAIL float cutoutOpacity = evalCutoutOpacity(stateNormal); if (0.0f < cutoutOpacity) { vec3 normal = evalNormal(stateNormal); materialIOR = evalIOR(normal); 34
“VIRTUAL” FUNCTIONS USED evalCutoutOpacity evalThinWalled evalNormal evalColorFront evalIOR evalColorBack evalMaterialEmissiveFront evalEnironmentFront evalMaterialEmissiveBack evalEnvironmentBack 35
Implement the functions as GLSL snippets Create a set of shader skeletons that implement your shading algorithms YOUR WORK Specify a set of “virtual” functions that get the material properties Fill the bodies of those functions with the glsl code generated from the expression trees 36
Recommend
More recommend