Material Definition Language API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Example for User-Defined State Modules
[Previous] [Up] [Next]

This example shows how to use a custom implementation of the state module. It enables you to adapt the generated code to your renderer, thus avoiding costly copies of your renderer state to the MDL SDK API state.

New Topics

  • User-defined state modules

Detailed Description

User-defined state modules


Usually, when you use code generated by the MDL SDK, you first setup the MDL material state structure mi::neuraylib::Shading_state_material by copying data from your own renderer state. But the duplicated state not only takes up stack space, it also causes several memory writes. By letting the generated code know, how to access your renderer state directly, this superfluous marshalling can be avoided. You can do this by specifying your own implementation of the state module.

To use a custom state module implementation, you have to provide LLVM-3.4-compatible bitcode data containing the state accessor functions as "llvm_state_module" binary option to the CUDA PTX, LLVM IR, or native backend via mi::neuraylib::IMdl_backend::set_option_binary().

Note
The data will be copied, so you don't have to keep the data alive. The module will not be checked for errors at this time, yet.

The required accessor functions mainly represent the functions in section 19 "Renderer state" of the MDL specification. The functions are expected to be implemented in C++ and must be placed in a "state" namespace. They use special types like "vfloat3" defined in "mdl_user_modules.h" which will be translated to LLVM vector types. The functions will be treated as side-effect-free, so function calls may be reordered or optimized away and their results may be reused.

All functions get a pointer to the shading state context as first parameter. This pointer will receive the "state" the renderer provided to the functions generated by the MDL backend. Currently, there are two contexts: Environment state functions expect a const pointer to an (opaque) "State_environment" structure and everything else expects a const pointer to an (opaque) "State_core" structure. In your implementation, you can just cast the context pointers to your own state types.

Note
It is not allowed to define those structures to avoid the casts in the source code, as these opaque structure types are required for linking with the generated code.

State functions with an "index" parameter get a const pointer to an (opaque) "Exception_state" structure as second parameter, because your implementation may want to handle out-of-bounds exceptions. But before such functions are called, the "index" argument will already be bounds-checked against the "num_texture_spaces" backend option as all indices refer to texture spaces.

For the environment context, only the "direction()" function must be implemented.

In addition to the functions described in the MDL specification, some special functions are required for the core context:

// Special function required by the init function of distribution functions for updating
// the normal field in the state.
void set_normal(State_core *state_context, vfloat3 new_normal);
// Get the texture results table, required by the distribution functions.
// Init will write the texture results, while sample, evaluate and PDF will only read it.
float4 *get_texture_results(State_core *state_context);
// Get the read-only data segment.
const char *get_ro_data_segment(State_core const *state_context);

The "user_modules" examples subfolder contains a reference C++ implementation corresponding to the current implementation in the MDL SDK and a precompiled bitcode file for testing. Please refer to "state.cpp" for the expected function signatures.

Note
You should not change the names, the parameter types or the return types of these functions. They are required to identify the state module functions in your module.

To test a custom state module with the example_df_cuda example of the MDL SDK, you can add this code snippet to the "Material_compiler::Material_compiler()" constructor in "example_cuda_shared.h" before calling mi::neuraylib::IMdl_backend::create_link_unit():

FILE *file = fopen("user_modules\\state.bc", "rb");
fseek(file, 0, SEEK_END);
size_t size(ftell(file));
fseek(file, 0, SEEK_SET);
char *data = (char *) malloc(size);
fread(data, 1, size, file);
fclose(file);
check_success(m_be_cuda_ptx->set_option_binary(
"llvm_state_module", data, mi::Size(size)) == 0);
free(data);

To see, that the backend really uses your implementation, you can add a very visual modification to the state implementation at first, like scaling one axis of the texture coordinates in "state::texture_coordinate()" in "state.cpp":

// float3 texture_coordinate(int index) varying
vfloat3 texture_coordinate(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
vfloat3 res = make_vector(state->text_coords[index]);
res.x *= 5;
return res;
}

After recompiling "state.bc" and restarting the example_df_cuda example, the texture on the sphere should look shrinked along the x-axis.

From here, you can start adapting the state module to your own renderer by replacing the "User_state_material" structure in "state.cpp" by the structure your renderer is using. When calling the code generated by the MDL SDK, you then simply provide your own renderer state as (reinterpret-casted) state parameter.

Note
This feature is still experimental. If you notice any problems, please report them in our MDL SDK forum: https://devtalk.nvidia.com/default/board/253/.

Example Source

To compile the state module, you require CUDA and a Clang from a LLVM 3.4.* release, which you can download from http://releases.llvm.org/download.html.

The recommended command line options for clang are:

clang -I<CUDA include path> -emit-llvm -c -O2 -ffast-math -target x86_64-pc-win32 state.cpp
Note
The target ensures that one fixed ABI (application binary interface) will be used, so the code generator knows how to process the functions. Do not use a different target.

In case of errors reported by the MDL SDK code generator, it may be useful to look at the LLVM IR code of your module. You can create an LLVM IR assembly text file "state.ll" with this command line:

clang -I<CUDA include path> -emit-llvm -S -O2 -ffast-math -target x86_64-pc-win32 state.cpp

Source Code Location: examples/mdl_sdk/user_modules/state.cpp

/***************************************************************************************************
* Copyright 2020 NVIDIA Corporation. All rights reserved.
**************************************************************************************************/
//
// Compile with
// clang.exe -I<CUDA include path> -emit-llvm -c -O2 -ffast-math -target x86_64-pc-win32 state.cpp
//
// The target ensures that one fixed ABI will be used, so we know how to process the functions.
//
#include "mdl_user_modules.h"
//
// The state structures used inside the renderer.
//
struct User_state_environment {
float3 direction;
};
struct User_state_material
{
float3 normal;
float3 geom_normal;
float3 position;
float animation_time;
const float3 *text_coords;
const float3 *tangent_u;
const float3 *tangent_v;
const float4 *text_results;
const char *ro_data_segment;
// these fields are used only if the uniform state is included
const float4 *world_to_object;
const float4 *object_to_world;
int object_id;
};
// Convert the given matrix from row major to column major and set last row to (0, 0, 0, 1).
static vfloat4x4 make_matrix_rm2cm(float4 const *v)
{
return vfloat4x4{
v[0].x, v[1].x, v[2].x, 0,
v[0].y, v[1].y, v[2].y, 0,
v[0].z, v[1].z, v[2].z, 0,
v[0].w, v[1].w, v[2].w, 1
};
}
namespace state {
//
// Environment state functions
//
// float3 direction() varying
vfloat3 direction(State_environment const *state_context)
{
User_state_environment const *state =
reinterpret_cast<User_state_environment const *>(state_context);
return make_vector(state->direction);
}
//
// Core state functions
//
// float3 position() varying
vfloat3 position(State_core const *state_context)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return make_vector(state->position);
}
// float3 normal() varying
vfloat3 normal(State_core const *state_context)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return make_vector(state->normal);
}
// Special function required by the init function for distribution functions for updating
// the normal field in the state.
void set_normal(State_core *state_context, vfloat3 new_normal)
{
User_state_material *state = reinterpret_cast<User_state_material *>(state_context);
state->normal.x = new_normal.x;
state->normal.y = new_normal.y;
state->normal.z = new_normal.z;
}
// float3 geometry_normal() varying
vfloat3 geometry_normal(State_core const *state_context)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return make_vector(state->geom_normal);
}
// float3 motion() varying
vfloat3 motion(State_core const *state_context)
{
return vfloat3{ 0, 0, 0 };
}
// int texture_space_max()
// Use default implementation: return value of "num_texture_spaces" option
// float3 texture_coordinate(int index) varying
vfloat3 texture_coordinate(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return make_vector(state->text_coords[index]);
}
// float3 texture_tangent_u(int index) varying
vfloat3 texture_tangent_u(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return make_vector(state->tangent_u[index]);
}
// float3 texture_tangent_v(int index) varying
vfloat3 texture_tangent_v(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return make_vector(state->tangent_v[index]);
}
// float3x3 tangent_space(int index) varying
vfloat3x3 tangent_space(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
return vfloat3x3(0);
}
// float3 geometry_tangent_u(int index) varying
vfloat3 geometry_tangent_u(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
return vfloat3{ 0, 0, 0 };
}
// float3 geometry_tangent_v(int index) varying
vfloat3 geometry_tangent_v(
State_core const *state_context,
Exception_state const *exc_state,
int index)
{
return vfloat3{ 0, 0, 0 };
}
// float animation_time() varying
float animation_time(State_core const *state_context)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return state->animation_time;
}
// float[WAVELENGTH_BASE_MAX] wavelength_base() uniform
float *wavelength_base(State_core const *state_context)
{
return nullptr;
}
// float4x4 transform(
// coordinate_space from,
// coordinate_space to) uniform
vfloat4x4 transform(State_core const *state_context, coordinate_space from, coordinate_space to)
{
if (from == coordinate_internal) from = INTERNAL_SPACE;
if (to == coordinate_internal) to = INTERNAL_SPACE;
if (from == to) {
return vfloat4x4{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
}
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
float4 const *transform_matrix =
(from == coordinate_world) ? state->world_to_object : state->object_to_world;
return make_matrix_rm2cm(transform_matrix);
}
// float3 transform_point(
// coordinate_space from,
// coordinate_space to,
// float3 point) uniform
State_core const *state_context,
coordinate_space from,
coordinate_space to,
vfloat3 point)
{
if (from == coordinate_internal) from = INTERNAL_SPACE;
if (to == coordinate_internal) to = INTERNAL_SPACE;
if (from == to) return point;
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
float4 const *mat =
(from == coordinate_world) ? state->world_to_object : state->object_to_world;
return vfloat3{
point.x * mat[0].x + point.y * mat[0].y + point.z * mat[0].z + mat[0].w,
point.x * mat[1].x + point.y * mat[1].y + point.z * mat[1].z + mat[1].w,
point.x * mat[2].x + point.y * mat[2].y + point.z * mat[2].z + mat[2].w
};
}
// float3 transform_vector(
// coordinate_space from,
// coordinate_space to,
// float3 vector) uniform
State_core const *state_context,
coordinate_space from,
coordinate_space to,
vfloat3 vector)
{
if (from == coordinate_internal) from = INTERNAL_SPACE;
if (to == coordinate_internal) to = INTERNAL_SPACE;
if (from == to) return vector;
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
float4 const *mat =
(from == coordinate_world) ? state->world_to_object : state->object_to_world;
return vfloat3{
vector.x * mat[0].x + vector.y * mat[0].y + vector.z * mat[0].z,
vector.x * mat[1].x + vector.y * mat[1].y + vector.z * mat[1].z,
vector.x * mat[2].x + vector.y * mat[2].y + vector.z * mat[2].z
};
}
// float3 transform_normal(
// coordinate_space from,
// coordinate_space to,
// float3 normal) uniform
State_core const *state_context,
coordinate_space from,
coordinate_space to,
vfloat3 normal)
{
if (from == coordinate_internal) from = INTERNAL_SPACE;
if (to == coordinate_internal) to = INTERNAL_SPACE;
if (from == to) return normal;
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
// the inverse matrix of world_to_object is object_to_world and vice versa
float4 const *inv_mat =
(from == coordinate_world) ? state->object_to_world : state->world_to_object;
// multiply with transpose of inversed matrix
return vfloat3{
normal.x * inv_mat[0].x + normal.y * inv_mat[1].x + normal.z * inv_mat[2].x,
normal.x * inv_mat[0].y + normal.y * inv_mat[1].y + normal.z * inv_mat[2].y,
normal.x * inv_mat[0].z + normal.y * inv_mat[1].z + normal.z * inv_mat[2].z
};
}
// float transform_scale(
// coordinate_space from,
// coordinate_space to,
// float scale) uniform
float transform_scale(
State_core const *state_context,
coordinate_space from,
coordinate_space to,
float scale)
{
if (from == coordinate_internal) from = INTERNAL_SPACE;
if (to == coordinate_internal) to = INTERNAL_SPACE;
if (from == to) return scale;
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
float4 const *mat =
(from == coordinate_world) ? state->world_to_object : state->object_to_world;
// t_0 = || transform_vector(float3(1,0,0), from, to) || = | mat[0] |
// t_1 = || transform_vector(float3(0,1,0), from, to) || = | mat[1] |
// t_2 = || transform_vector(float3(0,0,1), from, to) || = | mat[2] |
// res = scale * (t_0 + t_1 + t_2) / 3
float t_0 = math::length(make_vector(*reinterpret_cast<const float3 *>(&mat[0])));
float t_1 = math::length(make_vector(*reinterpret_cast<const float3 *>(&mat[1])));
float t_2 = math::length(make_vector(*reinterpret_cast<const float3 *>(&mat[2])));
return scale * ((t_0 + t_1 + t_2) / 3.0f);
}
// float3 rounded_corner_normal(
// uniform float radius = 0.0,
// uniform bool across_materials = false,
// uniform float roundness = 1.0
// ) varying
// Use default implementation -> return state::normal()
// float meters_per_scene_unit() uniform
// Use default implementation -> return value provided to backend
// float scene_units_per_meter() uniform
// Use default implementation -> return inverse meters_per_scene_unit value provided to backend
// int object_id() uniform
int object_id(State_core const *state_context)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return state->object_id;
}
// float wavelength_min() uniform
// Use default implementation -> return value provided to backend
// float wavelength_max() uniform
// Use default implementation -> return value provided to backend
// Get the texture results table, required by the distribution functions.
// Init will write the texture results, sample, evaluate and PDF will only read it.
float4 *get_texture_results(State_core *state_context)
{
User_state_material *state = reinterpret_cast<User_state_material *>(state_context);
return const_cast<float4 *>(state->text_results);
}
// Get the read-only data segment.
const char *get_ro_data_segment(State_core const *state_context)
{
User_state_material const *state = reinterpret_cast<User_state_material const *>(state_context);
return state->ro_data_segment;
}
} // namespace state

Source Code Location: examples/mdl_sdk/user_modules/mdl_user_modules.h

/***************************************************************************************************
* Copyright 2020 NVIDIA Corporation. All rights reserved.
**************************************************************************************************/
#ifndef MDL_USER_MODULES_H
#define MDL_USER_MODULES_H
// CUDA vector types
#include <vector_types.h>
struct __align__(2) bool2
{
bool x, y;
};
struct bool3
{
bool x, y, z;
};
struct __align__(4) bool4
{
bool x, y, z, w;
};
typedef char const *string;
typedef bool vbool2 __attribute((ext_vector_type(2)));
typedef bool vbool3 __attribute((ext_vector_type(3)));
typedef bool vbool4 __attribute((ext_vector_type(4)));
typedef int vint2 __attribute((ext_vector_type(2)));
typedef int vint3 __attribute((ext_vector_type(3)));
typedef int vint4 __attribute((ext_vector_type(4)));
typedef float vfloat2 __attribute((ext_vector_type(2)));
typedef float vfloat3 __attribute((ext_vector_type(3)));
typedef float vfloat4 __attribute((ext_vector_type(4)));
typedef float vfloat3x3 __attribute((ext_vector_type(9)));
typedef float vfloat4x4 __attribute((ext_vector_type(16)));
typedef double vdouble2 __attribute((ext_vector_type(2)));
typedef double vdouble3 __attribute((ext_vector_type(3)));
typedef double vdouble4 __attribute((ext_vector_type(4)));
typedef double vdouble3x3 __attribute((ext_vector_type(9)));
typedef double vdouble4x4 __attribute((ext_vector_type(16)));
#include "mdl_runtime.h"
// Structs used by the MDL SDK API.
struct State_core;
struct State_environment;
struct Exception_state;
//
// Some helper functions
//
// Convert a scalar bool2 to a vector bool2.
static vbool2 make_vector(bool2 const &v)
{
return vbool2{ v.x, v.y };
}
// Convert a scalar bool3 to a vector bool3.
static vbool3 make_vector(bool3 const &v)
{
return vbool3{ v.x, v.y, v.z };
}
// Convert a scalar bool4 to a vector bool4.
static vbool4 make_vector(bool4 const &v)
{
return vbool4{ v.x, v.y, v.z, v.w };
}
// Convert a scalar int2 to a vector int2.
static vint2 make_vector(int2 const &v)
{
return vint2{ v.x, v.y };
}
// Convert a scalar int3 to a vector int3.
static vint3 make_vector(int3 const &v)
{
return vint3{ v.x, v.y, v.z };
}
// Convert a scalar int4 to a vector int4.
static vint4 make_vector(int4 const &v)
{
return vint4{ v.x, v.y, v.z, v.w };
}
// Convert a scalar float2 to a vector float2.
static vfloat2 make_vector(float2 const &v)
{
return vfloat2{ v.x, v.y };
}
// Convert a scalar float3 to a vector float3.
static vfloat3 make_vector(float3 const &v)
{
return vfloat3{ v.x, v.y, v.z };
}
// Convert a scalar float4 to a vector float4.
static vfloat4 make_vector(float4 const &v)
{
return vfloat4{ v.x, v.y, v.z, v.w };
}
// Convert a scalar double2 to a vector double2.
static vdouble2 make_vector(double2 const &v)
{
return vdouble2{ v.x, v.y };
}
// Convert a scalar double3 to a vector double3.
static vdouble3 make_vector(double3 const &v)
{
return vdouble3{ v.x, v.y, v.z };
}
// Convert a scalar double4 to a vector double4.
static vdouble4 make_vector(double4 const &v)
{
return vdouble4{ v.x, v.y, v.z, v.w };
}
namespace state {
enum coordinate_space {
coordinate_internal,
coordinate_object,
coordinate_world
};
} // namespace state
// The internal space according to the "internal_space" backend option.
// Defaults to world space.
extern state::coordinate_space INTERNAL_SPACE;
#endif // MDL_USER_MODULES_H

Source Code Location: examples/mdl_sdk/user_modules/mdl_runtime.h

/***************************************************************************************************
* Copyright 2020 NVIDIA Corporation. All rights reserved.
**************************************************************************************************/
#ifndef MDL_USER_MODULES_MDL_RUNTIME_H
#define MDL_USER_MODULES_MDL_RUNTIME_H
namespace math
{
int abs(int a);
vint2 abs(vint2 a);
vint3 abs(vint3 a);
vint4 abs(vint4 a);
float abs(float a);
vfloat2 abs(vfloat2 a);
vfloat3 abs(vfloat3 a);
vfloat4 abs(vfloat4 a);
double abs(double a);
vdouble2 abs(vdouble2 a);
vdouble3 abs(vdouble3 a);
vdouble4 abs(vdouble4 a);
// color abs(color const &a); (not supported yet)
float acos(float a);
vfloat2 acos(vfloat2 a);
vfloat3 acos(vfloat3 a);
vfloat4 acos(vfloat4 a);
double acos(double a);
vdouble2 acos(vdouble2 a);
vdouble3 acos(vdouble3 a);
vdouble4 acos(vdouble4 a);
bool all(bool a);
bool all(vbool2 a);
bool all(vbool3 a);
bool all(vbool4 a);
bool any(bool a);
bool any(vbool2 a);
bool any(vbool3 a);
bool any(vbool4 a);
float asin(float a);
vfloat2 asin(vfloat2 a);
vfloat3 asin(vfloat3 a);
vfloat4 asin(vfloat4 a);
double asin(double a);
vdouble2 asin(vdouble2 a);
vdouble3 asin(vdouble3 a);
vdouble4 asin(vdouble4 a);
float atan(float a);
vfloat2 atan(vfloat2 a);
vfloat3 atan(vfloat3 a);
vfloat4 atan(vfloat4 a);
double atan(double a);
vdouble2 atan(vdouble2 a);
vdouble3 atan(vdouble3 a);
vdouble4 atan(vdouble4 a);
float atan2(float y, float x);
vfloat2 atan2(vfloat2 y, vfloat2 x);
vfloat3 atan2(vfloat3 y, vfloat3 x);
vfloat4 atan2(vfloat4 y, vfloat4 x);
double atan2(double y, double x);
vdouble2 atan2(vdouble2 y, vdouble2 x);
vdouble3 atan2(vdouble3 y, vdouble3 x);
vdouble4 atan2(vdouble4 y, vdouble4 x);
float average(float a);
float average(vfloat2 a);
float average(vfloat3 a);
float average(vfloat4 a);
double average(double a);
double average(vdouble2 a);
double average(vdouble3 a);
double average(vdouble4 a);
// float average(color const &a); (not supported yet)
float ceil(float a);
vfloat2 ceil(vfloat2 a);
vfloat3 ceil(vfloat3 a);
vfloat4 ceil(vfloat4 a);
double ceil(double a);
vdouble2 ceil(vdouble2 a);
vdouble3 ceil(vdouble3 a);
vdouble4 ceil(vdouble4 a);
int clamp(int a, int min, int max);
vint2 clamp(vint2 a, vint2 min, vint2 max);
vint3 clamp(vint3 a, vint3 min, vint3 max);
vint4 clamp(vint4 a, vint4 min, vint4 max);
float clamp(float a, float min, float max);
vfloat2 clamp(vfloat2 a, vfloat2 min, vfloat2 max);
vfloat3 clamp(vfloat3 a, vfloat3 min, vfloat3 max);
vfloat4 clamp(vfloat4 a, vfloat4 min, vfloat4 max);
double clamp(double a, double min, double max);
vdouble2 clamp(vdouble2 a, vdouble2 min, vdouble2 max);
vdouble3 clamp(vdouble3 a, vdouble3 min, vdouble3 max);
vdouble4 clamp(vdouble4 a, vdouble4 min, vdouble4 max);
// color clamp(color const &a, color const &min, color const &max); (not supported yet)
vint2 clamp(vint2 a, vint2 min, int max);
vint2 clamp(vint2 a, int min, vint2 max);
vint2 clamp(vint2 a, int min, int max);
vint3 clamp(vint3 a, vint3 min, int max);
vint3 clamp(vint3 a, int min, vint3 max);
vint3 clamp(vint3 a, int min, int max);
vint4 clamp(vint4 a, vint4 min, int max);
vint4 clamp(vint4 a, int min, vint4 max);
vint4 clamp(vint4 a, int min, int max);
vfloat2 clamp(vfloat2 a, vfloat2 min, float max);
vfloat2 clamp(vfloat2 a, float min, vfloat2 max);
vfloat2 clamp(vfloat2 a, float min, float max);
vfloat3 clamp(vfloat3 a, vfloat3 min, float max);
vfloat3 clamp(vfloat3 a, float min, vfloat3 max);
vfloat3 clamp(vfloat3 a, float min, float max);
vfloat4 clamp(vfloat4 a, vfloat4 min, float max);
vfloat4 clamp(vfloat4 a, float min, vfloat4 max);
vfloat4 clamp(vfloat4 a, float min, float max);
// color clamp(color const &a, color const &min, float max); (not supported yet)
// color clamp(color const &a, float min, color const &max); (not supported yet)
// color clamp(color const &a, float min, float max); (not supported yet)
vdouble2 clamp(vdouble2 a, vdouble2 min, double max);
vdouble2 clamp(vdouble2 a, double min, vdouble2 max);
vdouble2 clamp(vdouble2 a, double min, double max);
vdouble3 clamp(vdouble3 a, vdouble3 min, double max);
vdouble3 clamp(vdouble3 a, double min, vdouble3 max);
vdouble3 clamp(vdouble3 a, double min, double max);
vdouble4 clamp(vdouble4 a, vdouble4 min, double max);
vdouble4 clamp(vdouble4 a, double min, vdouble4 max);
vdouble4 clamp(vdouble4 a, double min, double max);
float cos(float a);
vfloat2 cos(vfloat2 a);
vfloat3 cos(vfloat3 a);
vfloat4 cos(vfloat4 a);
double cos(double a);
vdouble2 cos(vdouble2 a);
vdouble3 cos(vdouble3 a);
vdouble4 cos(vdouble4 a);
vfloat3 cross(vfloat3 a, vfloat3 b);
vdouble3 cross(vdouble3 a, vdouble3 b);
float degrees(float a);
vfloat2 degrees(vfloat2 a);
vfloat3 degrees(vfloat3 a);
vfloat4 degrees(vfloat4 a);
double degrees(double a);
vdouble2 degrees(vdouble2 a);
vdouble3 degrees(vdouble3 a);
vdouble4 degrees(vdouble4 a);
float distance(float a, float b);
float distance(vfloat2 a, vfloat2 b);
float distance(vfloat3 a, vfloat3 b);
float distance(vfloat4 a, vfloat4 b);
double distance(double a, double b);
double distance(vdouble2 a, vdouble2 b);
double distance(vdouble3 a, vdouble3 b);
double distance(vdouble4 a, vdouble4 b);
float dot(float a, float b);
float dot(vfloat2 a, vfloat2 b);
float dot(vfloat3 a, vfloat3 b);
float dot(vfloat4 a, vfloat4 b);
double dot(double a, double b);
double dot(vdouble2 a, vdouble2 b);
double dot(vdouble3 a, vdouble3 b);
double dot(vdouble4 a, vdouble4 b);
float exp(float a);
vfloat2 exp(vfloat2 a);
vfloat3 exp(vfloat3 a);
vfloat4 exp(vfloat4 a);
double exp(double a);
vdouble2 exp(vdouble2 a);
vdouble3 exp(vdouble3 a);
vdouble4 exp(vdouble4 a);
// color exp(color const &a); (not supported yet)
float exp2(float a);
vfloat2 exp2(vfloat2 a);
vfloat3 exp2(vfloat3 a);
vfloat4 exp2(vfloat4 a);
double exp2(double a);
vdouble2 exp2(vdouble2 a);
vdouble3 exp2(vdouble3 a);
vdouble4 exp2(vdouble4 a);
// color exp2(color const &a); (not supported yet)
float floor(float a);
vfloat2 floor(vfloat2 a);
vfloat3 floor(vfloat3 a);
vfloat4 floor(vfloat4 a);
double floor(double a);
vdouble2 floor(vdouble2 a);
vdouble3 floor(vdouble3 a);
vdouble4 floor(vdouble4 a);
float fmod(float a, float b);
vfloat2 fmod(vfloat2 a, vfloat2 b);
vfloat3 fmod(vfloat3 a, vfloat3 b);
vfloat4 fmod(vfloat4 a, vfloat4 b);
double fmod(double a, double b);
vdouble2 fmod(vdouble2 a, vdouble2 b);
vdouble3 fmod(vdouble3 a, vdouble3 b);
vdouble4 fmod(vdouble4 a, vdouble4 b);
vfloat2 fmod(vfloat2 a, float b);
vfloat3 fmod(vfloat3 a, float b);
vfloat4 fmod(vfloat4 a, float b);
vdouble2 fmod(vdouble2 a, double b);
vdouble3 fmod(vdouble3 a, double b);
vdouble4 fmod(vdouble4 a, double b);
float frac(float a);
vfloat2 frac(vfloat2 a);
vfloat3 frac(vfloat3 a);
vfloat4 frac(vfloat4 a);
double frac(double a);
vdouble2 frac(vdouble2 a);
vdouble3 frac(vdouble3 a);
vdouble4 frac(vdouble4 a);
bool isnan(float a);
vbool2 isnan(vfloat2 a);
vbool3 isnan(vfloat3 a);
vbool4 isnan(vfloat4 a);
bool isnan(double a);
vbool2 isnan(vdouble2 a);
vbool3 isnan(vdouble3 a);
vbool4 isnan(vdouble4 a);
bool isfinite(float a);
vbool2 isfinite(vfloat2 a);
vbool3 isfinite(vfloat3 a);
vbool4 isfinite(vfloat4 a);
bool isfinite(double a);
vbool2 isfinite(vdouble2 a);
vbool3 isfinite(vdouble3 a);
vbool4 isfinite(vdouble4 a);
float length(float a);
float length(vfloat2 a);
float length(vfloat3 a);
float length(vfloat4 a);
double length(double a);
double length(vdouble2 a);
double length(vdouble3 a);
double length(vdouble4 a);
float lerp(float a, float b, float l);
vfloat2 lerp(vfloat2 a, vfloat2 b, vfloat2 l);
vfloat3 lerp(vfloat3 a, vfloat3 b, vfloat3 l);
vfloat4 lerp(vfloat4 a, vfloat4 b, vfloat4 l);
double lerp(double a, double b, double l);
vdouble2 lerp(vdouble2 a, vdouble2 b, vdouble2 l);
vdouble3 lerp(vdouble3 a, vdouble3 b, vdouble3 l);
vdouble4 lerp(vdouble4 a, vdouble4 b, vdouble4 l);
vfloat2 lerp(vfloat2 a, vfloat2 b, float l);
vfloat3 lerp(vfloat3 a, vfloat3 b, float l);
vfloat4 lerp(vfloat4 a, vfloat4 b, float l);
vdouble2 lerp(vdouble2 a, vdouble2 b, double l);
vdouble3 lerp(vdouble3 a, vdouble3 b, double l);
vdouble4 lerp(vdouble4 a, vdouble4 b, double l);
// color lerp(color const &a, color const &b, color const &l); (not supported yet)
// color lerp(color const &a, color const &b, float l); (not supported yet)
float log(float a);
vfloat2 log(vfloat2 a);
vfloat3 log(vfloat3 a);
vfloat4 log(vfloat4 a);
double log(double a);
vdouble2 log(vdouble2 a);
vdouble3 log(vdouble3 a);
vdouble4 log(vdouble4 a);
// color log(color const &a); (not supported yet)
float log2(float a);
vfloat2 log2(vfloat2 a);
vfloat3 log2(vfloat3 a);
vfloat4 log2(vfloat4 a);
double log2(double a);
vdouble2 log2(vdouble2 a);
vdouble3 log2(vdouble3 a);
vdouble4 log2(vdouble4 a);
// color log2(color const &a); (not supported yet)
float log10(float a);
vfloat2 log10(vfloat2 a);
vfloat3 log10(vfloat3 a);
vfloat4 log10(vfloat4 a);
double log10(double a);
vdouble2 log10(vdouble2 a);
vdouble3 log10(vdouble3 a);
vdouble4 log10(vdouble4 a);
// color log10(color const &a); (not supported yet)
float luminance(vfloat3 a);
// float luminance(color const &a); (not supported yet)
int max(int a, int b);
vint2 max(vint2 a, vint2 b);
vint3 max(vint3 a, vint3 b);
vint4 max(vint4 a, vint4 b);
float max(float a, float b);
vfloat2 max(vfloat2 a, vfloat2 b);
vfloat3 max(vfloat3 a, vfloat3 b);
vfloat4 max(vfloat4 a, vfloat4 b);
double max(double a, double b);
vdouble2 max(vdouble2 a, vdouble2 b);
vdouble3 max(vdouble3 a, vdouble3 b);
vdouble4 max(vdouble4 a, vdouble4 b);
// color max(color const &a, color const &b); (not supported yet)
// color max(float a, color const &b); (not supported yet)
// color max(color const &a, float b); (not supported yet)
float max_value(float a);
float max_value(vfloat2 a);
float max_value(vfloat3 a);
float max_value(vfloat4 a);
double max_value(double a);
double max_value(vdouble2 a);
double max_value(vdouble3 a);
double max_value(vdouble4 a);
// float max_value(color const &a); (not supported yet)
int min(int a, int b);
vint2 min(vint2 a, vint2 b);
vint3 min(vint3 a, vint3 b);
vint4 min(vint4 a, vint4 b);
float min(float a, float b);
vfloat2 min(vfloat2 a, vfloat2 b);
vfloat3 min(vfloat3 a, vfloat3 b);
vfloat4 min(vfloat4 a, vfloat4 b);
double min(double a, double b);
vdouble2 min(vdouble2 a, vdouble2 b);
vdouble3 min(vdouble3 a, vdouble3 b);
vdouble4 min(vdouble4 a, vdouble4 b);
// color min(color const &a, color const &b); (not supported yet)
// color min(float a, color const &b); (not supported yet)
// color min(color const &a, float b); (not supported yet)
float min_value(float a);
float min_value(vfloat2 a);
float min_value(vfloat3 a);
float min_value(vfloat4 a);
double min_value(double a);
double min_value(vdouble2 a);
double min_value(vdouble3 a);
double min_value(vdouble4 a);
// float min_value(color const &a); (not supported yet)
// float[2] modf(float a); (not supported yet)
// float2[2] modf(vfloat2 a); (not supported yet)
// float3[2] modf(vfloat3 a); (not supported yet)
// float4[2] modf(vfloat4 a); (not supported yet)
// double[2] modf(double a); (not supported yet)
// double2[2] modf(vdouble2 a); (not supported yet)
// double3[2] modf(vdouble3 a); (not supported yet)
// double4[2] modf(vdouble4 a); (not supported yet)
float normalize(float a);
vfloat2 normalize(vfloat2 a);
vfloat3 normalize(vfloat3 a);
vfloat4 normalize(vfloat4 a);
double normalize(double a);
vdouble2 normalize(vdouble2 a);
vdouble3 normalize(vdouble3 a);
vdouble4 normalize(vdouble4 a);
int pow(int a, int b);
vint2 pow(vint2 a, vint2 b);
vint3 pow(vint3 a, vint3 b);
vint4 pow(vint4 a, vint4 b);
float pow(float a, float b);
vfloat2 pow(vfloat2 a, vfloat2 b);
vfloat3 pow(vfloat3 a, vfloat3 b);
vfloat4 pow(vfloat4 a, vfloat4 b);
double pow(double a, double b);
vdouble2 pow(vdouble2 a, vdouble2 b);
vdouble3 pow(vdouble3 a, vdouble3 b);
vdouble4 pow(vdouble4 a, vdouble4 b);
vint2 pow(vint2 a, int b);
vint3 pow(vint3 a, int b);
vint4 pow(vint4 a, int b);
vfloat2 pow(vfloat2 a, float b);
vfloat3 pow(vfloat3 a, float b);
vfloat4 pow(vfloat4 a, float b);
vdouble2 pow(vdouble2 a, double b);
vdouble3 pow(vdouble3 a, double b);
vdouble4 pow(vdouble4 a, double b);
// color pow(color const &a, color const &b); (not supported yet)
// color pow(color const &a, float b); (not supported yet)
float radians(float a);
vfloat2 radians(vfloat2 a);
vfloat3 radians(vfloat3 a);
vfloat4 radians(vfloat4 a);
double radians(double a);
vdouble2 radians(vdouble2 a);
vdouble3 radians(vdouble3 a);
vdouble4 radians(vdouble4 a);
float round(float a);
vfloat2 round(vfloat2 a);
vfloat3 round(vfloat3 a);
vfloat4 round(vfloat4 a);
double round(double a);
vdouble2 round(vdouble2 a);
vdouble3 round(vdouble3 a);
vdouble4 round(vdouble4 a);
float rsqrt(float a);
vfloat2 rsqrt(vfloat2 a);
vfloat3 rsqrt(vfloat3 a);
vfloat4 rsqrt(vfloat4 a);
double rsqrt(double a);
vdouble2 rsqrt(vdouble2 a);
vdouble3 rsqrt(vdouble3 a);
vdouble4 rsqrt(vdouble4 a);
// color rsqrt(color const &a); (not supported yet)
float saturate(float a);
vfloat2 saturate(vfloat2 a);
vfloat3 saturate(vfloat3 a);
vfloat4 saturate(vfloat4 a);
double saturate(double a);
vdouble2 saturate(vdouble2 a);
vdouble3 saturate(vdouble3 a);
vdouble4 saturate(vdouble4 a);
// color saturate(color const &a); (not supported yet)
int sign(int a);
vint2 sign(vint2 a);
vint3 sign(vint3 a);
vint4 sign(vint4 a);
float sign(float a);
vfloat2 sign(vfloat2 a);
vfloat3 sign(vfloat3 a);
vfloat4 sign(vfloat4 a);
double sign(double a);
vdouble2 sign(vdouble2 a);
vdouble3 sign(vdouble3 a);
vdouble4 sign(vdouble4 a);
float sin(float a);
vfloat2 sin(vfloat2 a);
vfloat3 sin(vfloat3 a);
vfloat4 sin(vfloat4 a);
double sin(double a);
vdouble2 sin(vdouble2 a);
vdouble3 sin(vdouble3 a);
vdouble4 sin(vdouble4 a);
// float[2] sincos(float a); (not supported yet)
// float2[2] sincos(vfloat2 a); (not supported yet)
// float3[2] sincos(vfloat3 a); (not supported yet)
// float4[2] sincos(vfloat4 a); (not supported yet)
// double[2] sincos(double a); (not supported yet)
// double2[2] sincos(vdouble2 a); (not supported yet)
// double3[2] sincos(vdouble3 a); (not supported yet)
// double4[2] sincos(vdouble4 a); (not supported yet)
float smoothstep(float a, float b, float l);
vfloat2 smoothstep(vfloat2 a, vfloat2 b, vfloat2 l);
vfloat3 smoothstep(vfloat3 a, vfloat3 b, vfloat3 l);
vfloat4 smoothstep(vfloat4 a, vfloat4 b, vfloat4 l);
double smoothstep(double a, double b, double l);
vdouble2 smoothstep(vdouble2 a, vdouble2 b, vdouble2 l);
vdouble3 smoothstep(vdouble3 a, vdouble3 b, vdouble3 l);
vdouble4 smoothstep(vdouble4 a, vdouble4 b, vdouble4 l);
vfloat2 smoothstep(vfloat2 a, vfloat2 b, float l);
vfloat3 smoothstep(vfloat3 a, vfloat3 b, float l);
vfloat4 smoothstep(vfloat4 a, vfloat4 b, float l);
vdouble2 smoothstep(vdouble2 a, vdouble2 b, double l);
vdouble3 smoothstep(vdouble3 a, vdouble3 b, double l);
vdouble4 smoothstep(vdouble4 a, vdouble4 b, double l);
float sqrt(float a);
vfloat2 sqrt(vfloat2 a);
vfloat3 sqrt(vfloat3 a);
vfloat4 sqrt(vfloat4 a);
double sqrt(double a);
vdouble2 sqrt(vdouble2 a);
vdouble3 sqrt(vdouble3 a);
vdouble4 sqrt(vdouble4 a);
// color sqrt(color const &a); (not supported yet)
float step(float a, float b);
vfloat2 step(vfloat2 a, vfloat2 b);
vfloat3 step(vfloat3 a, vfloat3 b);
vfloat4 step(vfloat4 a, vfloat4 b);
double step(double a, double b);
vdouble2 step(vdouble2 a, vdouble2 b);
vdouble3 step(vdouble3 a, vdouble3 b);
vdouble4 step(vdouble4 a, vdouble4 b);
float tan(float a);
vfloat2 tan(vfloat2 a);
vfloat3 tan(vfloat3 a);
vfloat4 tan(vfloat4 a);
double tan(double a);
vdouble2 tan(vdouble2 a);
vdouble3 tan(vdouble3 a);
vdouble4 tan(vdouble4 a);
// float2x2 transpose(float2x2 a); (not supported yet)
// float2x3 transpose(float3x2 a); (not supported yet)
// float3x2 transpose(float2x3 a); (not supported yet)
// float3x3 transpose(float3x3 a); (not supported yet)
// float4x2 transpose(float2x4 a); (not supported yet)
// float2x4 transpose(float4x2 a); (not supported yet)
// float3x4 transpose(float4x3 a); (not supported yet)
// float4x3 transpose(float3x4 a); (not supported yet)
// float4x4 transpose(float4x4 a); (not supported yet)
// double2x2 transpose(double2x2 a); (not supported yet)
// double2x3 transpose(double3x2 a); (not supported yet)
// double3x2 transpose(double2x3 a); (not supported yet)
// double3x3 transpose(double3x3 a); (not supported yet)
// double4x2 transpose(double2x4 a); (not supported yet)
// double2x4 transpose(double4x2 a); (not supported yet)
// double3x4 transpose(double4x3 a); (not supported yet)
// double4x3 transpose(double3x4 a); (not supported yet)
// double4x4 transpose(double4x4 a); (not supported yet)
// color blackbody(float temperature); (not supported yet)
// color emission_color(float[<N>] wavelengths, float[N] amplitudes); (not supported yet)
// color emission_color(color const &value); (not supported yet)
}
namespace debug
{
bool breakpoint();
bool assert(bool condition, string reason, string funcname = "", string filename = "",
int line = 0);
bool print(bool v);
bool print(vbool2 v);
bool print(vbool3 v);
bool print(vbool4 v);
bool print(int v);
bool print(vint2 v);
bool print(vint3 v);
bool print(vint4 v);
bool print(float v);
bool print(vfloat2 v);
bool print(vfloat3 v);
bool print(vfloat4 v);
bool print(double v);
bool print(vdouble2 v);
bool print(vdouble3 v);
bool print(vdouble4 v);
// bool print(color const &v); (not supported yet)
bool print(string v);
}
#endif // MDL_USER_MODULES_MDL_RUNTIME_H
[Previous] [Up] [Next]