Friday, April 15, 2011

Writing mental ray shaders: Texture Mapping

Once we have UV coordinates, we can start mapping textures according to these coordinates. This section will introduce the use of miTAG, and the function mi_lookup_color_texture(). I'll create a node thats similar in function to the 2d_placement node in Maya. Key functions are, UV offsets, and  UV scaling.

*col, *state, tag, *v
Return the value in a color texture at a given coordinate.

The tag is assumed to be a texture as taken from a color texture parameter of a shader. This function checks whether the tag refers to a shader (procedural texture) or an image (file texture or byte stream), depending on which type of color texture statement was used in the .mi file. If tag is a shader, coord is stored in state→tex, the referenced texture shader is called, and its return value is returned. If tag is an image, coord is brought into the range (0…1, 0…1) by removing the integer part, the image is looked up at the resulting 2D coordinate, and miTRUE is returned. If the texture has been marked for filtering, like with the filter keyword in the .mi file, then multi-level pyramid filtering is performed, a procedure derived from classical mip-map textures. In both cases, the color resulting from the lookup is stored in *color.

MI Source
declare shader
 color "uv_textures" (
  color texture "tex",
  scalar "u_offset" default 0,
  scalar "v_offset" default 0,
  scalar "u_scale" default 1,
  scalar "v_scale" default 1
apply material
end declare

C Source
#include "shader.h"

struct uv_textures{
 miTag tex;
 miScalar u_offset;
 miScalar v_offset;
 miScalar u_scale;
 miScalar v_scale;

miBoolean uv_textures(miColor *result, miState *state, struct uv_textures *params) {
 miVector uv_coord = {0, 0, 0};
 miTag tex = *mi_eval_tag(&params->tex);
 miScalar u_offset = *mi_eval_scalar(&params->u_offset);
 miScalar v_offset = *mi_eval_scalar(&params->v_offset);
 miScalar u_scale = *mi_eval_scalar(&params->u_scale);
 miScalar v_scale = *mi_eval_scalar(&params->v_scale);
 uv_coord.x = fmod(state->tex_list[0].x * u_scale + u_offset, 1.0);
 uv_coord.y = fmod(state->tex_list[0].y * v_scale + v_offset, 1.0);
 mi_lookup_color_texture(result, state, tex, &uv_coord); 
 return miTRUE;


Post a Comment