2 registered members (AndrewAMD, VoroneTZ),
779
guests, and 3
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
[REQ] Spotlight Shader
#327998
06/09/10 19:06
06/09/10 19:06
|
Joined: Feb 2009
Posts: 3,207 Germany, Magdeburg
Rei_Ayanami
OP
Expert
|
OP
Expert
Joined: Feb 2009
Posts: 3,207
Germany, Magdeburg
|
Hello , I need a really(really, really) good Spotlight shader - it will be the most important part of the game, so vertex lightning is much to bad. I know that there is a Spotlight shader by Emre, who already helped me once adding Dynamic Lights. But I get more and more problems with that Shader... It looks good, but I need some things to be changed/a new one. Here is how it looks at the moment(Its a bit racked... but just because i got a new monitor today..): I applied the object shader to the view... Invisible Objects sometimes get Visible, Translucent things aren't translucent and no static lights... EDIT: Here is the code for the shader (at the moment)
// By Joseph Duffey Jan 2008
// For the GameStudio Community
//
// Projective Texturing Spotlight + Fog
//
const float4x4 matWorldViewProj; // World*view*projection matrix.
const float4x4 matMtl; // custom matrix passed via the material
const float4x4 matWorld; // World matrix.
const float4 vecViewPos; // Current view position passed from application
const float4 vecFog; // Vector calculated from the current view's clip and fog parameters
const float4 vecAmbient; // Ambient color, passed by the engine.
const float4 vecSkill1; // spotlights pos (xyz) and range (w) from application
const float4 vecSkill5; // spotlights normalized direction vector from aplication
static const float SpecularIntensity = 0.5f; // The intensity of the specular light.
static const float SpecularPower = 2.0f; // The specular power, used as 'glossiness' factor.
texture entSkin1; // bitmap of object material applied to
texture mtlSkin1; // projection bitmap defined in material
sampler BaseTex = sampler_state
{
Texture = <entSkin1>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = wrap;
AddressV = wrap;
};
sampler ProjTex = sampler_state
{
Texture = <mtlSkin1>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = clamp;
AddressV = clamp;
};
struct VS_INPUT
{
float4 Pos : POSITION;
float3 Normal : NORMAL;
float4 Tex : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Pos : POSITION;
float4 Tex : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 LightVec : TEXCOORD2;
float3 Normal : TEXCOORD3;
float3 ViewDir : TEXCOORD4;
float Fog : FOG;
};
struct PS_INPUT
{
float4 Tex : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 LightVec : TEXCOORD2;
float3 Normal : TEXCOORD3;
float4 ViewDir : TEXCOORD4;
};
VS_OUTPUT MAIN_VS( VS_INPUT In )
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
Out.Pos = mul(In.Pos, matWorldViewProj); // Transform vertex position to screen space:
Out.Normal = normalize(mul(In.Normal, matWorld)); // Transform the normal from object space to world space:
Out.Tex = In.Tex; // Copy color texture coordinates through
Out.Tex1 = mul( mul(In.Pos,matWorld), matMtl); // Calc the projected texture coordinates
Out.LightVec.xyz = mul(In.Pos, matWorld) - vecSkill1; // light to position vector
Out.LightVec.w = length(Out.LightVec.xyz)/vecSkill1.w; // light range
Out.ViewDir = vecViewPos - mul(In.Pos, matWorld); // Calculate a vector from the vertex to the view, for specular
float3 worldPos = mul(In.Pos, matWorld); // Transform the vertex to world space
Out.Fog = 1 - (distance(worldPos, vecViewPos) - vecFog.x) * (vecFog.z); // Calculate Fog
return Out;
}
float4 MAIN_PS( PS_INPUT In ) : COLOR
{
In.LightVec.xyz = normalize(In.LightVec.xyz); // normalize light pos xyz, but not w (range)
In.Normal = normalize(In.Normal);
In.ViewDir = normalize(In.ViewDir);
float4 LightDir = normalize(vecSkill5); // Normalize spotlight direction
float4 Attn = 1 - saturate(dot(In.LightVec.w, In.LightVec.w)); // Calculate attenuation
float4 Color = tex2D( BaseTex, In.Tex ); // Base texture lookup
float projIntensity = saturate(dot(-In.LightVec, In.Normal)); // The more perpendicular the polygon to the light, the more light PPL
float4 projColor = In.Tex1.w < 0.0 ? 0.0 : tex2Dproj( ProjTex, In.Tex1 ); // look up projection texture only in facing dir (avoid back proj)
float4 proj = projColor * projIntensity; // multiply the proj color with the amount of intensity
float3 R = normalize(2 * dot(In.Normal, -LightDir) * In.Normal + LightDir); // Calculate the reflection vector:
float Specular = 0;//(pow(saturate(dot(R, In.ViewDir)), SpecularPower) * SpecularIntensity); // Calculate the speculate component only in spotlight
Specular *= saturate(proj); // only allow specular in projection area
return (Color * vecAmbient) + Color * ((proj + Specular)* Attn); // final color
}
//////////////////////////////
// ADD POINTLIGHT
//////////////////////////////
float4 vecLightPos[8];
float4 vecLightColor[8];
float4x4 matWorldInv;
struct PointOut
{
float4 Position : POSITION;
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR0;
float Fog : FOG;
};
PointOut PointVS(float4 inPos : POSITION, float2 inTex0 : TEXCOORD0,float3 inNormal: NORMAL0)
{
PointOut Out;
Out.Position = mul(inPos, matWorldViewProj);
Out.Tex0 = inTex0;
Out.Color = float4(0,0,0,0);
//Add point lights
for(int i = 0; i <= 5; i++)
{
// Diffuse lighting
float4 objLightPos = mul(float4(vecLightPos[i].xyz, 1), matWorldInv);
float4 objLightDir = objLightPos - inPos;
float4 objLightDirN = normalize(objLightDir);
float diffLight = max(dot(objLightDirN, inNormal), 0);
// Calculate attenuation factor
float falloffFactor = 0;
if(vecLightPos[i].w > 0)
{
float linearDistance = length(objLightDir)/vecLightPos[i].w;
if(linearDistance < 1) falloffFactor = 1 - linearDistance;
}
diffLight *= falloffFactor;
// Add to final result
Out.Color.rgb += vecLightColor[i].rgb * diffLight;
}
float3 worldPos = mul(inPos, matWorld);
Out.Fog = 1 - (distance(worldPos, vecViewPos) - vecFog.x) * (vecFog.z);
return Out;
}
float4 PointPS(PointOut In) : COLOR0
{
float4 FinalColor;
FinalColor = tex2D(BaseTex,In.Tex0);
FinalColor *=(In.Color)*3;
return FinalColor;
}
technique PP_Spot
{
pass p0
{
VertexShader = compile vs_1_1 MAIN_VS();
PixelShader = compile ps_2_0 MAIN_PS();
}
pass P1
{
alphablendenable=true;
srcblend=one;
destblend=one;
VertexShader = compile vs_2_0 PointVS();
PixelShader = compile ps_2_0 PointPS();
}
}
So, but the shader I need, needs: - Pointlights
- Use Models Ambient Value to make Object brighter
- Static Lights (pre-compiled with wed)
- Let Translucent Objects Translucent
- Let Invisible Objects Invisible
- Should apply to all objects
- Not be tooo slow...not so important, A8 Pro will make with BSP faster
- Size should be adjustable
- Lightrange should be adjustable
- Make use of FOG
Thanks for any input I know it is really, really, really much what I want, but I am such a noob at programming shaders... Thanks for advance and best regards, Rei
Last edited by Rei_Ayanami; 06/10/10 13:27.
|
|
|
Re: [REQ] Spotlight Shader
[Re: Rei_Ayanami]
#328339
06/12/10 08:59
06/12/10 08:59
|
Joined: Aug 2008
Posts: 482
bart_the_13th
Senior Member
|
Senior Member
Joined: Aug 2008
Posts: 482
|
Adapted from XDiv10's projected texture ( http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=315503&page=1)
//Apply this material to levelblocks
MATERIAL* mtl_pTexBlock =
{
effect = "
////////////////////////////////////////////////////////
// Projected texture (FFP) by Xd1Vo
// Adapted for level blocks by bart_the_13th
////////////////////////////////////////////////////////
float4x4 matEffect3;
texture mtlSkin1;
texture entSkin1;
texture entSkin2;
texture StencilMap;//I was planning to modulate the flashlight to the stencilmap too, but my A7E version doesnt allow it :P
technique proj_tex
{
pass p0
{
Texture[0] = <entSkin1>; // texture
Texture[1] = <entSkin2>; // light map
Texture[2] = <mtlSkin1>; // projected shadow/flashlight
FogEnable=1;
ColorArg1[0] = Texture;
ColorArg2[0] = Diffuse;
ColorOp[0] = Modulate; //use selectArg1 if not using dynamic lights
ResultArg[0] = Temp; //Temp = texture + diffuse
ColorArg1[1] = Texture;
ColorArg2[1] = Current;
ColorOp[1] = Modulate2X;
ColorArg1[2] = Texture;
ColorArg2[2] = Current;
ColorOp[2] = Add;
magfilter[2] = linear;
minfilter[2] = linear;
mipfilter[2] = linear;
AddressU[2] = BORDER;
AddressV[2] = BORDER;
BorderColor[2] = 0x000001;
texcoordindex[2] = cameraspaceposition ;
TextureTransformFlags[2] = count3 |projected;
TextureTransform[2] = <matEffect3>;
ColorArg1[3] = temp; // (shadow map + vertex lighting)
ColorArg2[3] = Current; // (color map + detail map)
ColorOp[3] = Modulate2X; // modulate (color map + detail map) with (shadow map + vertex lighting)
magfilter[3] = linear;
minfilter[3] = linear;
mipfilter[3] = linear;
}
}
";
}
/* Add these lines to main function
if(flashlite!=NULL)
{
create_dxmat(mat_effect3,flashlite.x,flashlite.pan,focus,mtl_pTexBlock.skin3); //eagle
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
|
|
|
Re: [REQ] Spotlight Shader
[Re: bart_the_13th]
#328354
06/12/10 12:26
06/12/10 12:26
|
Joined: Feb 2009
Posts: 3,207 Germany, Magdeburg
Rei_Ayanami
OP
Expert
|
OP
Expert
Joined: Feb 2009
Posts: 3,207
Germany, Magdeburg
|
Thanks But I don't know how apply it... At the moment I just apply it to the camera.material , and I use this code for adapting:
//
// By Joseph Duffey Jan 2008
// Edited by Dennis van den Broek Feb 2010
// For the GameStudio Community
//
// Projective Texturing Spotlight
#define PRAGMA_PATH "GFX"
#define PRAGMA_PATH "Scripts"
BMAP* projectiontex = "Spotlight.jpg"; // texture to be projected
var flashlight_energy;
var flashlight_stat;
//=======================================================================================
// MATERIAL FOR OBJECTS LIT BY SPOTLIGHT
//=======================================================================================
MATERIAL* mtlSpotlit =
{
ambient_red = 18; // The ambient color - a dark grey.
ambient_green = 18;
ambient_blue = 18;
skin1 = projectiontex;
effect = "PT_Spot.fx"; // The effect file containing the vertex shader, pixel shader and technique.
flags |= OVERRIDE;
}
MATERIAL* mtlSpotlitObj =
{
ambient_red = 100; // The ambient color - a dark grey.
ambient_green = 100;
ambient_blue = 100;
skin1 = projectiontex;
effect = "PT_Spot.fx"; // The effect file containing the vertex shader, pixel shader and technique.
flags |= OVERRIDE;
}
MATERIAL* mtlNoSpotLight =
{
effect = "technique DepthTechnique { pass p0 { }}";
flags = OVERRIDE;
}
//=======================================================================================
// PROJECTION
//=======================================================================================
MATERIAL* mtlProjView =
{
effect = "technique DepthTechnique { pass p0 { }}"; // must have an effect or crash!
event = mtlProjection_event; // transform and adjust views view matrix
flags = ENABLE_VIEW; // call the event before view rendering
}
VIEW* ProjectionView = // Put at projectors position during rendering to get its view matrix
{
material = mtlProjView;
flags = SHOW | UNTOUCHABLE;
}
function mtlProjection_event() // adjust matrices to size of bitmaps and pass to "matMtl" and "matEffect"
{
// create a transformation matrix
float pTexAdj[16] = { 0.5, 0.0, 0.0, 0.0, 0.0,-0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
// Adjust projection matrix for texture size
pTexAdj[12] = 0.5 + (0.5/(float)bmap_width(projectiontex)*2.0);// store bitmap diminsions into matrix
pTexAdj[13] = 0.5 + (0.5/(float)bmap_height(projectiontex)*2.0);
// Store the transformation matrix to the materials then adjust the matrix with the bitmap size
mat_set(mtlSpotlit.matrix,matViewProj); // store the transformation matrix to the material
mat_multiply(mtlSpotlit.matrix,pTexAdj); // adjust the matrix with the bitmap size
mat_set(mtlSpotlitObj.matrix,matViewProj); // store the transformation matrix to the material
mat_multiply(mtlSpotlitObj.matrix,pTexAdj); // adjust the matrix with the bitmap size
}
//=======================================================================================
// SPOTLIGHT ACTION
//=======================================================================================
function Spotlight()
{
diag_var("\nSpotlight started at %.3f\n", total_ticks/16);
SOUND* flashlight_snd = "flashlight.ogg";
VECTOR temp_vec; // for temporary vectors
VECTOR temp_vec2, temp_vec3;
ENTITY* temp_ent = ent_create(NULL, nullvector, NULL);
ProjectionView.aspect = 0.77; // adjust views aspect to desired ratio, squash or stretch
wait(10);
mtlSpotlit.skill4 = floatv(1.0); // spotlights range
mtlSpotlitObj.skill4 = floatv(1.0); // spotlights range
while(!player) wait(1);
while(player)
{
// move me with keyboard keys
//c_move(me, vector((key_w - key_s) * time_step * 8,0,0), nullvector, IGNORE_PASSABLE | GLIDE);
//c_rotate(me, vector((key_cul - key_cur)*time_step*8, (key_cuu-key_cud)*time_step*8,0), IGNORE_PASSABLE);
// Put projection view at my pos and dir
if(mouse_mode != 1)
{
vec_set(temp_ent.x, camera.x);
temp_ent.z -= player.skill100*1.5;
vec_set(temp_ent.pan, camera.pan);
c_move(temp_ent, vector(0,-10,0), nullvector, IGNORE_MODELS | IGNORE_MAPS);
vec_set(ProjectionView.x, temp_ent.x);
vec_set(ProjectionView.pan, camera.pan);
}
else
{
vec_set(temp_ent.x, camera.x);
temp_ent.z -= player.skill100*1.5;
vec_set(temp_ent.pan, camera.pan);
vec_set(ProjectionView.x, temp_ent.x);
temp_vec2.x = mouse_pos.x;
temp_vec2.y = mouse_pos.y;
temp_vec2.z = 50000;
vec_for_screen(temp_vec2, camera);
you = player;
c_trace(camera.x, temp_vec2, IGNORE_YOU);
vec_set(temp_vec3, target.x);
vec_sub(temp_vec3, camera.x);
vec_to_angle(ProjectionView.pan, temp_vec3);
}
// send my position to shader (vecSkill1.xyzw)
mtlSpotlit.skill1 = floatv(camera.x);
mtlSpotlit.skill2 = floatv(camera.z-player.skill100*1.5); // z and y must be reversed!
mtlSpotlit.skill3 = floatv(camera.y);
mtlSpotlitObj.skill1 = floatv(camera.x);
mtlSpotlitObj.skill2 = floatv(camera.z-player.skill100*1.5); // z and y must be reversed!
mtlSpotlitObj.skill3 = floatv(camera.y);
if(flashlight_stat == 1)
{
if(flashlight_energy > 500)
{
mtlSpotlit.skill4 = floatv(2000); // spotlights range
mtlSpotlitObj.skill4 = floatv(2000); // spotlights range
}
else
{
if(flashlight_energy > 0)
{
mtlSpotlit.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
mtlSpotlitObj.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
}
else
{
flashlight_stat = 0;
mtlSpotlit.skill4 = floatv(1.0); // spotlights range
mtlSpotlitObj.skill4 = floatv(1.0); // spotlights range
}
}
flashlight_energy -= time_step/2;
}
if(key_f)
{
if(flashlight_energy > 0)
{
if(flashlight_stat == 1)
{
mtlSpotlit.skill4 = floatv(1.0); // spotlights range
mtlSpotlitObj.skill4 = floatv(1.0); // spotlights range
player.skill1 = 0;
flashlight_stat = 0;
}
else
{
if(flashlight_energy > 500)
{
mtlSpotlitObj.skill4 = floatv(2000); // spotlights range
mtlSpotlit.skill4 = floatv(2000); // spotlights range
}
else
{
if(flashlight_energy > 0)
{
mtlSpotlit.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
mtlSpotlitObj.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
}
else
{
flashlight_stat = 0;
mtlSpotlit.skill4 = floatv(1); // spotlights range
mtlSpotlitObj.skill4 = floatv(1); // spotlights range
}
}
player.skill1 = 1;
flashlight_stat = 1;
snd_play(flashlight_snd,100, 0);
}
while(key_f)
{
// Put projection view at my pos and dir
if(mouse_mode != 1)
{
vec_set(temp_ent.x, camera.x);
vec_set(temp_ent.pan, camera.pan);
temp_ent.z -= player.skill100*1.5;
c_move(temp_ent, vector(0,-10,0), nullvector, IGNORE_MODELS | IGNORE_MAPS);
vec_set(ProjectionView.x, temp_ent.x);
vec_set(ProjectionView.pan, camera.pan);
}
else
{
vec_set(temp_ent.x, camera.x);
vec_set(temp_ent.pan, camera.pan);
temp_ent.z -= player.skill100*1.5;
vec_set(ProjectionView.x, temp_ent.x);
temp_vec2.x = mouse_pos.x;
temp_vec2.y = mouse_pos.y;
temp_vec2.z = 50000;
vec_for_screen(temp_vec2, camera);
you = player;
c_trace(camera.x, temp_vec2, IGNORE_YOU);
vec_set(temp_vec3, target.x);
vec_sub(temp_vec3, camera.x);
vec_to_angle(ProjectionView.pan, temp_vec3);
}
// send my position to shader (vecSkill1.xyzw)
mtlSpotlit.skill1 = floatv(camera.x);
mtlSpotlit.skill2 = floatv(camera.z-player.skill100*1.5); // z and y must be reversed!
mtlSpotlit.skill3 = floatv(camera.y);
vec_for_angle(temp_vec.x, vector((camera.pan), camera.tilt, camera.roll)); //turn my angles into a dir vector
mtlSpotlit.skill5 = floatv(temp_vec.x);
mtlSpotlit.skill6 = floatv(temp_vec.z); // z and y must be reversed!
mtlSpotlit.skill7 = floatv(temp_vec.y);
wait(1);
}
}
}
// send my direction to shader (vecSkill2.xyzw)
vec_for_angle(temp_vec.x, ProjectionView.pan); //turn my angles into a dir vector
mtlSpotlit.skill5 = floatv(temp_vec.x);
mtlSpotlit.skill6 = floatv(temp_vec.z); // z and y must be reversed!
mtlSpotlit.skill7 = floatv(temp_vec.y);
mtlSpotlitObj.skill5 = floatv(temp_vec.x);
mtlSpotlitObj.skill6 = floatv(temp_vec.z); // z and y must be reversed!
mtlSpotlitObj.skill7 = floatv(temp_vec.y);
wait(1);
}
}
//=======================================================================================
// ACTION FOR OBJECTS LIT BY SPOTLIGHT
//=======================================================================================
action Spotlit_object()
{
my.material = mtlSpotlit;
}
//=======================================================================================
// FUNCTION FOR SETTING STAGE RENDERING
//=======================================================================================
// this should be done immediatly after level load
function init_stages()
{
ProjectionView.stage = camera; // so projection is not lagging one frame behind
}
Can you please help me again? It is already sooo great that you helped me till now Best regards, Rei
|
|
|
Re: [REQ] Spotlight Shader
[Re: bart_the_13th]
#328858
06/15/10 17:06
06/15/10 17:06
|
Joined: Feb 2009
Posts: 3,207 Germany, Magdeburg
Rei_Ayanami
OP
Expert
|
OP
Expert
Joined: Feb 2009
Posts: 3,207
Germany, Magdeburg
|
Thanks, I got it working. But I am having a problem: Why the light is not in the middle of the screen (when setting the pan as camera.pan and the pos to camera.x) ? It is at the lower right blue line, and not in the middle of them all... Thanks in advance, Rei
|
|
|
Re: [REQ] Spotlight Shader
[Re: bart_the_13th]
#341043
09/09/10 21:35
09/09/10 21:35
|
Joined: Jun 2005
Posts: 656
Grafton
User
|
User
Joined: Jun 2005
Posts: 656
|
Oops, sorry, my bad. Doh, I should have read the whole post before replying.
Last edited by Grafton; 09/12/10 16:37.
Not two, not one.
|
|
|
|