Access PBR / Physical materials - maybe getting an IGameMaterial from an Mtl somehow? (MaxSDK)


#1

Hi all!

I understand how I can access StdMat standard materials, but I am wondering how can I access the new PBR materials and / or Physical materials.

I am writing a C++ gltf exporter plugin and because gltf already supports PBR I want to support saving them too if possible - not only converted standard materials.

I do not see any kind of ways to do this via the SDK. I also looked at the source code for the Babylon engine’s exporter code and see they use IGame all through but my plugin is not IGame, but normal maxsdk.

My questions:

  • How to access materials for physical and PBR? Is it at all possible without IGame? (hopefully is).
  • If there is any docs on how to access their parameters anywhere where to find those docs?
  • If I cannot access via the normal SDK things just the IGame way, how can I get an IGameMaterial node from an Mtl without refactoring all our plugin with unnumbered amount of work? Is there some way for it?

Am I right that it should be possible to get these data via some kind of Paramblock magic? I never really used these param blocks much, but imagine that maybe that is the way to get/set these informations.

Best regards,
Richard


#2

run this code:

#define PYSMAT_CID Class_ID(0x3d6b1cec, 0xdeadc001)

void dump_physmat(Mtl* physicalMaterial)
{
Class_ID mCid = mtl->ClassID();

if(mCid == PYSMAT_CID)
{
	FILE* f= _tfopen(_M("c:\\physicalMtl.txt"), _M("w"));

	int i, nBlocks = mtl->NumParamBlocks();
	for(i=0; i<nBlocks; i++)
	{
		IParamBlock2* pBlock = mtl->GetParamBlock(i);
		int id, nParams = pBlock->NumParams();
		for(id=0; id<nParams; id++)
		{
			ParamID pid = pBlock->IndextoID(id);
			ParamDef pDef = pBlock->GetParamDef(pid);
			if(pDef.size > 0)
			{
				if(pDef.int_name != NULL)
					_ftprintf(f, _M("id=%d, name: %s\n"), pid, pDef.int_name);
			}
		}
	}
	fclose(f);
}

}

result will be:
ClassName: Physical Material
BlockNum=0
id=0, name: material_mode
id=1, name: base_weight
id=2, name: base_color
id=3, name: reflectivity
id=4, name: roughness
id=5, name: roughness_inv
id=6, name: metalness
id=10, name: refl_color
id=11, name: diff_roughness
id=12, name: brdf_mode
id=13, name: brdf_low
id=14, name: brdf_high
id=15, name: brdf_curve
id=20, name: anisotropy
id=21, name: anisoangle
id=22, name: aniso_mode
id=23, name: aniso_channel
id=30, name: transparency
id=31, name: trans_color

from there its easy to make some header for your exporter

#pragma once

#ifndef PHYSICALMATERIAL_CLASS_ID
#define PHYSICALMATERIAL_CLASS_ID Class_ID(0x3d6b1cec, 0xdeadc001)
#endif

#define PH_material_mode 0
#define PH_base_weight 1
#define PH_base_color 2
#define PH_reflectivity 3
#define PH_roughness 4
#define PH_roughness_inv 5
#define PH_refl_color 10
#define PH_transparency 30
#define PH_trans_ior 33
#define PH_emission 50
#define PH_emit_color 51

#define PH_base_color_map 101
#define PH_refl_color_map 103
#define PH_roughness_map 104
#define PH_transparency_map 109
#define PH_emit_color_map 117
#define PH_bump_map 130
#define PH_displacement_map 132
#define PH_cutout_map 133

#define PH_bump_map_amt 230

and then, to get some color:
Color cRefl = c = pBlock2->GetColor(PH_refl_color, t);

and it would be awesome if this code tag would work here !!
why this forum is messed up so much ? for the mobile kiddies ?


#3

Thanks!

Also thanks for showing the method to get the various parameters, which is handy for the future.

If I see it right, this is the “Physical” material. Do you also know what is Class_ID of the newer “PBR” material? I think that is some new thing in max 2021 and is a bit simpler than the Physical one - albeit in the long run both should be supported by us. I have no max2021 to test with so what you already gave will be priority anyways much earlier…

Thanks again.


#4

Metal/Rough:
Class_ID(0xd00f1e00, 0xbe77e500)

Spec/Gloss:
Class_ID(0xd00f1e00, 0x01dbad33)