Ok i have perfected my texture projector method.. is a little complicated so bare with me...

the way it works is you need to have a light projector object.. it will project according to its pan, tilt, roll and position... just think of it like a slide projector. assign this action the projector and make it's skill4=6666 in wed(this could be any number in any skill):

//put these vars somewhere before the action..
var scan_radius=210;
//how far it scans for objects.. if you use multiple projectors make sure the scan radius is small enough so they wont intersect..

var lighttimer=0; //needed for wait() statement.. this way the camera view are initialized.. you'll see later.

Code:
ACTION lightobject

{
MY.passable=ON;
MY.shadow=OFF;
my.flare=off;
my.transparent=off;
my.invisible=on;
my.enable_detect=on;
my.event=light_data;

my.skill100=lighttimer;
lighttimer+=1;

if my.skill4==6666 //is a projector
{
wait(my.skill100);

light_view_matrix();

while(1)
{

temp.pan = 360;
temp.tilt = 360;
temp.z = 220;
indicator=NULL;
scan_entity(my.x,temp);
wait(1);
}
}
)



before this action, you need this function:

Code:
 var tempmatrix[16];


function light_view_matrix()
{

//temporary matrix to store view matrix
vec_set(camera.x,my.x);
vec_set(camera.pan,my.pan);

wait(1);

mat_set(tempmatrix,matView);

my.skill80=tempmatrix[0];
my.skill81=tempmatrix[1];
my.skill82=tempmatrix[2];
my.skill83=tempmatrix[3];

my.skill84=tempmatrix[4];
my.skill85=tempmatrix[5];
my.skill86=tempmatrix[6];
my.skill87=tempmatrix[7];

my.skill88=tempmatrix[8];
my.skill89=tempmatrix[9];
my.skill90=tempmatrix[10];
my.skill91=tempmatrix[11];

my.skill92=tempmatrix[12];
my.skill93=tempmatrix[13];
my.skill94=tempmatrix[14];
my.skill95=tempmatrix[15];

}



what this is does move the camera around to each projector and stores the view matrix for each one in its skills 80-95.

now you need the projectors event function..put this before everything else:
Code:
 function light_data()

{

if event_type==event_detect && my.skill4 == 6666 //projector
{

your.material=mat_projection;
//you.skill100=6666;
//texture projection matrix
you.skill80=my.skill80;
you.skill81=my.skill81;
you.skill82=my.skill82;
you.skill83=my.skill83;

you.skill84=my.skill84;
you.skill85=my.skill85;
you.skill86=my.skill86;
you.skill87=my.skill87;

you.skill88=my.skill88;
you.skill89=my.skill89;
you.skill90=my.skill90;
you.skill91=my.skill91;

you.skill92=my.skill92;
you.skill93=my.skill93;
you.skill94=my.skill94;
you.skill95=my.skill95;

// return;
}

}



this assings the view matrix values to the object and also tells it to use the projection material if it isnt set already.

now on to the shader..

first you need the init function:
Code:
var matTexProj[16];


function mat_projection_init()
{

mtl.enable_render=on;

//set up the texture projection matrix

matTexProj[0]=my.skill80;
matTexProj[1]=my.skill81;
matTexProj[2]=my.skill82;
matTexProj[3]=my.skill83;

matTexProj[4]=my.skill84;
matTexProj[5]=my.skill85;
matTexProj[6]=my.skill86;
matTexProj[7]=my.skill87;

matTexProj[8]=my.skill88;
matTexProj[9]=my.skill89;
matTexProj[10]=my.skill90;
matTexProj[11]=my.skill91;

matTexProj[12]=my.skill92;
matTexProj[13]=my.skill93;
matTexProj[14]=my.skill94;
matTexProj[15]=my.skill95;

mat_set(mtl.matrix,matWorld);
mat_multiply(mtl.matrix,matTexProj);

}



now here is a very simple one pass shader set.. obviously this technique can be combined with others to mix projectors with per pixel lights etc..

Code:
 

material mat_projection
{

skin1 = projectiontex;

event = mat_projection_init;

flags = tangent;
effect =
"

texture mtlSkin1; //projector
texture entSkin1; //colormap
matrix matWorldViewProj;
//matrix matWorld;
matrix matMtl;

technique projector
{

pass p0 //projector
{

//load matrices
VertexShaderConstant[0] = <matWorld>; //World Matrix
VertexShaderConstant[8] = <matWorldViewProj>; //World*View*Proj Matrix
VertexShaderConstant[95] = <matMtl>;


//range constant
VertexShaderConstant[33] = (0.01f, 0.5f, 0.05f, 0.0f);

Texture[0] = <mtlSkin1>; //projection tex
Texture[1] = <entSkin1>; //projection tex

AddressU[0] = Clamp; // don't wrap around edges
AddressV[0] = Clamp;
AddressU[1] = Clamp; // don't wrap around edges
AddressV[1] = Clamp;

zWriteEnable=true; // enables writing to the z-buffer
//AlphaBlendEnable=true; // disables alpha blending
//srcblend=destcolor;
//destblend=one;


VertexShader=
decl
{
stream 0;
float v0[3]; //position
float v3[3]; //normal
float v7[3]; //uv
float v8[3]; //tangent
}
asm
{
vs.1.1

; position in clip space
m4x4 oPos, v0, c8

; position in texture projection space
m4x4 r10,v0,c95

; Divide each component by the range value
mul r10, r10, c33.x

; multiply with 0.5 and add 0.5
mad r10, r10, c33.yyyy, c33.yyyy

; map the x and y components into the first texture
mov oT0.xy, r10.xy

mov oT1.xy, v7.xy; color

};

PixelShader=
asm
{

ps.1.1

tex t0
tex t1

mov r0,t0
mul r0,r0,t1

};
}

}
";
}



i hope this all makes sense.. ive something doesnt work let me know and i can help. btw rememebr to setup a bitmap called projectiontex like so: bmap projectiontex = <light_alpha_1.tga>;

**NOTE-one problem that is inherent in this kind of texture projection is that it will project in front AND behind the projector.. if you want a true spot light projector there is probably somwway to clip the backside out but i dont know what it is.. can someone figure this out?

I dont think i will be making a demo.. if someone else wants to that would be great. but i'm too busy :P

Last edited by Matt_Aufderheide; 09/03/04 00:06.