OSL – UVTransform

An OSL shader for offsetting, tiling, and rotating textures.

uvtransform_rndr

Download link
http://www.rensheeren.com/osl/UVTransform_tex_v002.osl
Right-click and save as.

Features
– Offset, rotate, or tile your textures in the shader.
– You can insert a replacement UV map. For example after you have added distortions to the map.

How to use
VRay:
– Create a VRay OSL Texture map.
– Load in the downloaded OSL shader.
– Set the transform values for Offset, Tiling and Rotation.
– If you want to generate a replacement UV map for adding distortions, you can use a VRaySamplerInfoTex map set to UVW coordinates. You can then mix it with a noise map for example. It will look cool, believe me!

uvtransform_node

uvtransform_ui

UI Properties

input_tex
– The input texture.

input_replacement_UV_tex
– A UV gradient if you want to replace the UV coordinates.

transform_order
– Choose the transform order, tile, rotate, offset.

UV_offset
– Texture offset (translation).

UV_tiling
– Texture tiling (scale).

UV_tiling_center
– The center point around which to tile.

UV_rotation
– Texture rotation.

UV_rotation_center
– The center point around which to rotate.

flip_U
– Flip the texture horizontally.

flip_V
– Flip the texture vertically.

O = Offset
T = Tile
R = Rotate

Code

/*

UVTransform_tex_v002


By Rens Heeren (mail [at] rensheeren [dot] com)

Info Page: http://www.rensheeren.com/blog/osl-uvtransform/


Use as an OSL texture, not as an OSL material.


An OSL shader for transforming textures. You can rotate, offset and scale (tile)
input textures. You can also use a random input to drive random transforms.

Usage:



Use at your own risk.



2016-01-01 - v001 - Created (rh)
2016-05-30 - v002 - UI Tweaks. (rh)

*/



////////////////////////////////////


color fn_offset(color c_in, color c_offset)
{
	color c_out = c_in + c_offset;
	return c_out;
}

color fn_tile(color c_in, color c_tiling, color c_center)
{
	color c_out = ((c_in - c_center) / c_tiling) + c_center;
	return c_out;
}

color fn_rotate(color c_in, float f_rotate, color c_center)
{
	point p_out = point(c_in[0], c_in[1], c_in[2]);
	point p_base = point(c_center[0], c_center[1], 0.0);
	point p_project = point(c_center[0], c_center[1], 1.0);
	p_out = rotate(p_out, f_rotate, p_base, p_project);
	color c_out = color(p_out[0], p_out[1], p_out[2]);
	return c_out;
}


//////////////////////////////////////


shader
UVTransform_tex_v002
(
	string input_tex = "",
	string input_replacement_UV_tex = "",
	int use_replacement_UV_tex = 0
		[[ string widget = "checkBox" ]],
	
	
	int transform_order = 1
		[[ string widget = "mapper",
		string description = "",
		string options = "RTO:1|ORT:2|TOR:3|TRO:4|ROT:5|OTR:6" ]],
	
	point UV_offset = point(0.0, 0.0 ,0.0),
	point UV_tiling = point(1.0, 1.0, 1.0),
	point UV_tiling_center = point(0.0, 0.0, 0.0),
	float UV_rotation = 0,
	point UV_rotation_center = point(0.5, 0.5, 0.0),
	
	int flip_U = 0
		[[ string widget = "checkBox" ]],
	
	int flip_V = 0
		[[ string widget = "checkBox" ]],
	
	//point random_seed_OTR = point(1, 2, 3),
	
	//string input_random_generator = "",
	
	string UV_offset_tex = "",
	int use_UV_offset_tex = 0
		[[ string widget = "checkBox" ]],
		
	string UV_tiling_tex = "",
	int use_UV_tiling_tex = 0
		[[ string widget = "checkBox" ]],
		
	string UV_rotation_tex = "",
	int use_UV_rotation_tex = 0
		[[ string widget = "checkBox" ]],
	
	
	output color out_tex_transformed = color(0),
	output color out_UV_transformed = color(0),
	output color out_UV_default = color(0),

	output float out_alpha_transformed = 0,
	output float out_alpha_white = 1
)


///////////////////////////////////////


{
	int i_useUVReplTex = use_replacement_UV_tex;
	int i_useOffsetTex = use_UV_offset_tex;
	int i_useTilingTex = use_UV_tiling_tex;
	int i_useRotationTex = use_UV_rotation_tex;
	int i_flipU = flip_U;
	int i_flipV = flip_V;
	int i_TO = transform_order;
	
	color c_UVDefault = color(u, v, 0.0);
	color c_UVTransformed = color(u, v, 0.0);
	
	if (i_useUVReplTex)
	{
		c_UVTransformed = texture(input_replacement_UV_tex, u, v);
	}

	color c_inputOffset = color(UV_offset[0], UV_offset[1], UV_offset[2]);
	if (i_useOffsetTex)
	{
		c_inputOffset = texture(UV_offset_tex, u, v);
	}
	c_inputOffset[1] = -c_inputOffset[1];

	color c_tilingCenter = color(UV_tiling_center[0], UV_tiling_center[1], UV_tiling_center[2]);
	color c_inputTiling = color(UV_tiling[0], UV_tiling[1], UV_tiling[2]);
	if (i_useTilingTex)
	{
		c_inputTiling = texture(UV_tiling_tex, u, v);
	}
	c_inputTiling = 1 / c_inputTiling;
	
	color c_rotationCenter = color(UV_rotation_center[0], UV_rotation_center[1], UV_rotation_center[2]);
	color c_inputRotation = color(UV_rotation);
	if (i_useRotationTex)
	{
		c_inputRotation = texture(UV_rotation_tex, u, v);
	}
	
	
	//input_random_generator
	//random_seed_OTR
	
	
	
	
	float f_rotateAngle = radians((c_inputRotation[0]) * 360.0);
	
	// RTO
	if (i_TO < 2 || i_TO > 6)
	{
		c_UVTransformed = fn_rotate(c_UVTransformed, f_rotateAngle, c_rotationCenter);
		c_UVTransformed = fn_tile(c_UVTransformed, c_inputTiling, c_tilingCenter);
		c_UVTransformed = fn_offset(c_UVTransformed, c_inputOffset);
		
	}
	
	// ORT
	if (i_TO == 2)
	{
		c_UVTransformed = fn_offset(c_UVTransformed, c_inputOffset);
		c_UVTransformed = fn_rotate(c_UVTransformed, f_rotateAngle, c_rotationCenter);
		c_UVTransformed = fn_tile(c_UVTransformed, c_inputTiling, c_tilingCenter);
		
	}
	
	// TOR
	if (i_TO == 3)
	{
		c_UVTransformed = fn_tile(c_UVTransformed, c_inputTiling, c_tilingCenter);
		c_UVTransformed = fn_offset(c_UVTransformed, c_inputOffset);
		c_UVTransformed = fn_rotate(c_UVTransformed, f_rotateAngle, c_rotationCenter);
	}
	
	// TRO
	if (i_TO == 4)
	{
		c_UVTransformed = fn_tile(c_UVTransformed, c_inputTiling, c_tilingCenter);
		c_UVTransformed = fn_rotate(c_UVTransformed, f_rotateAngle, c_rotationCenter);
		c_UVTransformed = fn_offset(c_UVTransformed, c_inputOffset);
	}
	
	// ROT
	if (i_TO == 5)
	{	
		c_UVTransformed = fn_rotate(c_UVTransformed, f_rotateAngle, c_rotationCenter);
		c_UVTransformed = fn_offset(c_UVTransformed, c_inputOffset);
		c_UVTransformed = fn_tile(c_UVTransformed, c_inputTiling, c_tilingCenter);
	}
	
	// OTR
	if (i_TO == 6)
	{	
		c_UVTransformed = fn_offset(c_UVTransformed, c_inputOffset);
		c_UVTransformed = fn_tile(c_UVTransformed, c_inputTiling, c_tilingCenter);
		c_UVTransformed = fn_rotate(c_UVTransformed, f_rotateAngle, c_rotationCenter);
	}
	
	if (i_flipU)
	{
		c_UVTransformed[0] = 1.0 - c_UVTransformed[0];
	}
	
	if (i_flipV)
	{
		c_UVTransformed[1] = 1.0 - c_UVTransformed[1];
	}
	
	float f_outputTexAlpha = 0.0;
	color c_outputTex = texture(input_tex, c_UVTransformed[0], c_UVTransformed[1], "alpha", f_outputTexAlpha);
	
	out_tex_transformed = c_outputTex;
	out_UV_transformed = c_UVTransformed;
	out_UV_default = c_UVDefault;

	out_alpha_transformed = f_outputTexAlpha;
}