// Texture Coord Rotation
//=============================================================================
//
// Eric (Steempipe) Hendrickson-Lambert
// needs: 3DGS C/P DirectX 9 vs/ps_2_0
//
// 1/15/16 version 1
// 1/17/16 version 2
// changed code to calculate/initialize rotation matrix outside of
// shader in material event. recomendation by "txesmi"
// 1/17/16 version 3
// 1). added texture scaling and shifting example.
// 2). moved all texture rotation/scaling/shifting operations to
// vertex shader.
// 3). an example of trick using (1) texCoord to pass 2 sets of UV's and use
// those 2 sets of UV's in pixelshader.
// 4). put tweakable scaling and shifting vars in the action to be in one place.
// 5). pan_slider controls shifting speed
//=============================================================================
BMAP* tex = "stone.tga";
var tex_rotation_in_degrees; // var for degrees rotation
function mtlEffect_init()
{
// example of using 4x4 matrix to rotate a texture in a shader
//
// tweakables to control how our texture is translated
//var tex_rotation_in_degrees = 45; // 0-360 degrees in CW rotation.
// initialize variables in our rotation matrix
float rotation_matrix[16] =
{ 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
// apply necessary maths to our matrix
rotation_matrix[0] = cosv(tex_rotation_in_degrees);
rotation_matrix[1] = -sinv(tex_rotation_in_degrees);
rotation_matrix[4] = sinv(tex_rotation_in_degrees);
rotation_matrix[5] = cosv(tex_rotation_in_degrees);
mat_effect1 = rotation_matrix; // assign our matrix to a pointer for the shader
}
MATERIAL* mtlEffect =
{
event = mtlEffect_init; // set up the texture rotation matrix for the shader
skin1 = tex;
effect = "
//-------------------------------------
// non-tweakables
//-------------------------------------
float4x4 matWorldViewProj;
float4x4 matEffect1; // rotation matrix
float4 vecSkill41; // texture scaling in x, scrolling time in y
//-------------------------------------
// tweakables
//-------------------------------------
// rotation degree variable located in mtlEffect_init function
//-------------------------------------
// textures
//-------------------------------------
texture mtlSkin1;
sampler sTex = sampler_state
{
Texture = <mtlSkin1>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = wrap;
AddressV = wrap;
};
//-------------------------------------
// structs
//-------------------------------------
struct VS_INPUT
{
float4 Position : POSITION;
float2 TexCoord0 : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 PosWorld : POSITION;
float4 TexCoord0 : TEXCOORD0;
};
// ----------------------------------------------------------------
// vertexshader
// ----------------------------------------------------------------
VS_OUTPUT vs_main( VS_INPUT In )
{
VS_OUTPUT Out;
float4 Position = mul(In.Position, matWorldViewProj);
Out.PosWorld = Position;
//==========Texture Translations=============================
// translate texture origin to the center
float2 rotated_tex = In.TexCoord0 -=0.5;
// rotate
rotated_tex = mul(In.TexCoord0.xy ,matEffect1);
// translate texture back to 0..1 range
rotated_tex += 0.5;
// do scaling and shift after the rotation operation
// scale/tile factor for our texture
rotated_tex *= vecSkill41.x;
// shift the texture coordinates
// adjust as needed by choosing which xy component to influence
// and by either +/- sign.
rotated_tex.y += vecSkill41.y;
//===========================================================
Out.TexCoord0.xy = rotated_tex.xy; // pass rotated texture coords to pixel shader
// a trick to get the most use out of one texture coordinate
Out.TexCoord0.zw = In.TexCoord0.xy;// pass unrotated texture coords thru
return Out;
}
// ----------------------------------------------------------------
// pixelshader
// ----------------------------------------------------------------
float4 ps_main(VS_OUTPUT In) : COLOR
{
float4 oTex1 = tex2D(sTex,In.TexCoord0.zw); // unrotated (is that a word?) tex
float4 oTex2 = tex2D(sTex, In.TexCoord0.xy); // rotated tex
// assemble our final output color
// in this case we lerp the rotated tex with an unroted version
// just an example for experimenting
float4 finalcolor = lerp (oTex1, oTex2, 0.7);
return finalcolor;
}
// ----------------------------------------------------------------
// Technique
// ----------------------------------------------------------------
Technique tech1
{
Pass One
{
vertexshader = compile vs_2_0 vs_main();
pixelshader = compile ps_2_0 ps_main();
}
}
";
}
action mtl_texrot () {
my.material = mtlEffect;
// texture 0-360 degrees in CW rotation.
// used in mtlEffect_init
tex_rotation_in_degrees = 100;
// pass scaling/tiling factor to shader vecSkill41.x
my.skill41 = floatv(2);
// adjust scrolling rate via slider
var tmp =20;
var time_smooth = 0.666;
// the var fac_speed_adj is from <panel_func.h> via the slider
while(1){
tmp+= time_step/fac_speed_adj;
my.skill42 = floatv(tmp); // pass scrolling time to shader vecSkill41.y
wait(1);}
}