How to get valid texcoords in MDL?

I’m not quite sure whether I understand the texture coordinate handling right.

For general textures I use base::texture_coordinate_info coordinate() to get the default texcoords (in world space), that is clear to me.
But in the car paint MDL sample “texture_coordinate_object” is used as “coordinate_source”.
The documentation says: "[…]Distances in internal space or object space can be transformed into scene units in world space using the coordinate space transformations in Section 19.2. Scene units can be multiplied with the result of the ::state::meters_per_scene_unit()[…]

But when I use

base::texture_coordinate_info coordinate =   base::texture_coordinate_info(state::texture_coordinate(0) * ::state::meters_per_scene_unit(), 
                                                                            tangent_u: state::texture_tangent_u(0), tangent_v: state::texture_tangent_v(0)  );
                                                                              // I also tried to multiply with ::state::scene_units_per_meter()

the result is not the expected as if base::coordinate_source(coordinate_system: base::texture_coordinate_object) is used.
I also tried it with a checker_texture (see attachment Checker_TexCoords.jpg)

What am I doing wrong here?


is not world space, its uv channel 0.

ignoring the module base for a while, you have multiple ways to get texture coordinates from the state:


this gives you texture coordinates from any of the uv channels. 0 is the first one and unless you know your object has multiple uv channels thats the one you want to access


this gives the position of the shading point in internal space. if you want it to be in world or object space, you need to transform it using functions MDL provides:


Back to the module ::base, its purpose is to implement some common functionality.
base::coordinate_source() will do the above transformation if you choose “texture_coordinate_world” as a source. In addition it will compute matching tangents which are needed for bump mapping.
world space means coordinates are relative to the worlds origin. object space means coordinates are relative to the objects origin.

Once you get the texture coordinate in world space, it will still be in whatever unit you used to model the scene. If you modeled in m, the value will be in m. if you modeled in inch, it will be in inch. If an application has a clear sense of modelling units, it can signal that to MDL using ::state::meters_per_scene_unit() (note, not all applications have a clear sense of modelling units)
modelling units strictly speaking only apply to world space and to a limited degree to object space. (uv spaces have no universally defined unit).

Thank you very much for your answer.
I hope I now understand it right:
so Texcoord UVs obtained from state::texture_coordinate(0) are independent from world/object space (as always in 3D).

And those from base::coordinate_source() are not the actual UVs, they are instead the transformed state::positions of the hitpoints.
And so they are the preferred method as coords for perlin/flake noise (as shown in the carpaint orange peel sample).
Now I think I got it.

mostly ;-)

base::coordinate_source() has 3 modes controlled by the parameter coordinate_system


uvw is like you said explicitly authored texture coordinates.
For flakes, object and world are typically the right choice, mostly i would choose object to glue the flakes to the object during animation.

the main design point of base::coordinate_source() is to bundle the coordinates together with the matching tangents ready for bump mapping and to work well with all the other ::base functions

Thank you for the explanation.
Lately I encountered another issue: When using an absolute Windows Path like this:

uniform texture_2d Texture = texture_2d("/valid_folder/testtexture5.jpg")

I found no way to specify a different drive letter (such as D:)
I was able to add D:\ with mdl_compiler->add_module_path, but that would mean to store this drive information additionally externally for each texture file of each .mdl material. The easiest way would be an access through: texture_2d(“D:/valid_folder/testtexture5.jpg”), this would only require this one definition of the texture file at one place in the .mdl file. (but the docs say that colons are not allowed in a path.)
Is there a way for addressing texture file names from different harddrives within the same .mdl file without adding full folder path through mdl_compiler->add_module_path ?
I can copy all textures to a new sub folder which then is addressed through a relative path, but after time this will waste lot of disk space, cause at least any by a material used texture would be stored twice. I thought to have only one copy of a texture in huge texture libraries (many GBs) across different harddisks to save disk space.

MDL is meant to define materials in a portable manner. Drive letters would make a material only work on your personal setup.

You can still have centralized texture repositories. Think of the mdl space as a virtual file system. you can address both absolute and relative within that system. if you have an mdl root “d:” with a image in “valid_folder\testtexture5.jpg” you can reference that texture through an absolute path in mdl space “/valid_folder/testtexture5.jpg” from any mdl material.

you can have this also across many drives as all mdl roots are merged into a single space.