Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

aboeing

vertexshader - specular

This topic is 5658 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi, im trying to implement the fixed pipeline using a vertex shader, and i have it looking mostly the same, but the specular light is wrong. [i wrote it in cg:]
struct appin
{
    float4 Position     : POSITION;
    float4 Normal       : NORMAL;
    float2 TexCoord	: TEXCOORD0;
};

struct vertout
{
    float4 HPosition    : POSITION;
    float4 Color0       : COLOR0;
    float4 Color1       : COLOR1;
    float2 Tex0		: TEXCOORD0;
    float2 Tex1		: TEXCOORD1;
};

vertout main(appin IN, 
             uniform float4x4 ModelViewProj,
			 uniform float4x4 ModelView,
             uniform float4x4 Model,
             uniform float4 LightVec)
{
	vertout OUT;
	OUT.HPosition = mul(ModelViewProj, IN.Position);
	float3 normalVec = mul(Model, IN.Normal).xyz;
	float3 lightVec = -LightVec.xyz;
	float diffuse = dot(normalVec.xyz, lightVec.xyz);

	
    //specular

	//this doesn''t work

	//H = norm(norm(- Vp) + Ldir) {from DX sdk..}

//	float3 posVec = mul(ModelView, IN.Position).xyz;

//  float3 halfVec = normalize(normalize(-posVec) + lightVec );

	float3 halfVec = lightVec;

    float specular = dot(normalVec.xyz, halfVec.xyz);

	OUT.Color0 = diffuse;
	OUT.Color1 = specular;

	OUT.Tex0 = IN.TexCoord;
	OUT.Tex1 = IN.TexCoord;
	return OUT;
}

//============

//pixel shader:

ps.1.3

tex t0
texbem t1,t0
mov r0,t1
mul r0,r0,v0
add r0,r0,v1
can someone tell me what i should be doing? (in the current form, you get a specular highlighty thing, it just doesnt move around like it should (and its the wrong size.)

Share this post


Link to post
Share on other sites
Advertisement
here''s the vertex shader in vs.1.1:

//set texture coords
mov oT1.xy, v7
mov oT0.xy, v7
//set output position
m4x4 oPos, v0, c0
//transform normal
m3x3 r0, v3, c8
//calc diffuse
dp3 r0.x, r0.xyz, -c12.xyz
//how to calc specular??
mov oD1, r0.x
mov oD0, r0.x

Share this post


Link to post
Share on other sites
Specular is:
SpecClr*(L dot H)^p
where L is the light vector, H is the half angle vector, p is the specular power (the "glossiness" in MAX terms I think). It looks like you don''t have the exponentiation.

Share this post


Link to post
Share on other sites
Yup, what blue_knight said. Plus:

H = L+V / |L+V|

Where L is the light vector and V is the view vector (camera to vertex, not just pos or eye). |L+V| is the magnitude, so that''s really just H=L+V and then the result normalised.

That''s also known as Blinn specular. It''s more common and often faster than Phong specular, and what D3D uses. Phong specular is (R.V)^shininess where R is the reflection vector for the light around the normal.

IIRC there''s also a presentation on the nVidia or ATI developer website called something like "implementing the fixed function pipeline with shaders" that has shader snippets for each stage.

Also remember to take into account the differences if localviewer is enabled.

--
Simon O''Connor
Insert Company Name Here

Share this post


Link to post
Share on other sites
hi guys, thanks for the help, i went out and found as many examples of specular lighting as i could, and tried them all:


struct appin
{
float4 Position : POSITION;
float4 Normal : NORMAL;
float2 TexCoord : TEXCOORD0;
};

struct vertout
{
float4 HPosition : POSITION;
float4 Color0 : COLOR0;
float4 Color1 : COLOR1;
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
};

vertout main(appin IN,
uniform float4x4 ModelViewProj,
uniform float4x4 ModelView,
uniform float4x4 Model,
uniform float4 LightVec,
uniform float4 Eye,
uniform float4x4 ModelViewIT
)
{
vertout OUT;
OUT.HPosition = mul(ModelViewProj, IN.Position);
float3 normalVec = mul(Model, IN.Normal).xyz;
float3 lightVec = -LightVec.xyz;
float diffuse = dot(normalVec.xyz, lightVec.xyz);
//specular

/*
//directX 9 (LOCALVIEW = true) way
//doenst work correctly, shiny spot doesnt move around right.. (i assume im using the wrong matrix''s to multiply..?)
float3 nVec = mul(Model,IN.Normal).xyz;
float3 posVec = mul(Model, IN.Position).xyz;
float3 halfVec = normalize(normalize(Eye.xyz-posVec)+lightVec.xyz);
float specular = dot(nVec, halfVec.xyz);
*/

/*
//directX 9 (LOCALVIEWER = false) way
//this works, but looks just like I had it before (read: the specular light doesnt move around properly)
float3 nVec = mul(Model,IN.Normal).xyz;
float3 eyeVec = float3(0.0, 0.0, 1.0);
float3 halfVec = normalize(eyeVec+lightVec.xyz);
float specular = dot(nVec, halfVec.xyz);
*/

/*
//directX 8 (LOCALVIEWER = false) way
//doenst work correctly, shiny spot doenst move around right.. (i assume im using the wrong matrix''s to multiply..?)
float3 nVec = mul(Model,IN.Normal).xyz;
float3 posVec = mul(Model, IN.Position).xyz;
float3 halfVec = normalize(normalize(-posVec)+lightVec.xyz);
float specular = dot(nVec, halfVec.xyz);
*/

/*
//blue_knight & S1CA''s way
//doesnt work correctly, shiny spot comes in from wrong direction.. (i assume i need a - somewhere..?)
float3 posVec = mul(ModelView, IN.Position).xyz;
float3 viewVec = posVec-Eye.xyz;
float3 halfVec = normalize(LightVec.xyz + viewVec );
float specular = dot(LightVec.xyz, halfVec.xyz);
*/

/*
//nVidia''s way (Erik Lindholm)
//doesnt work, just looks plain wierd.
float3 nVec = mul(ModelViewProj, IN.Normal).xyz;
float3 halfVec = normalize(Eye.xyz+LightVec.xyz);
float specular = dot(halfVec, nVec);
*/


//nVidia''s way (CG)

//this works, but is just like DX9''s LOCALVIEW=false way (not what i want)

float3 nVec = normalize(mul(ModelViewIT,IN.Normal).xyz);
float3 lVec = normalize(lightVec.xyz);
float3 eyeVec = float3(0.0, 0.0, 1.0);
float3 halfVec = normalize(lVec + eyeVec);
float specular = dot(normalVec, halfVec);

//including this line makes everything go white

//specular = pow(specular,1);


OUT.Color0 = diffuse;
OUT.Color1 = specular;

OUT.Tex0 = IN.TexCoord;
OUT.Tex1 = IN.TexCoord;
return OUT;
}


The only specular lighting methods that worked were the ones equivilent to (LOCALVIEWER = false), which wasnt what i was really after..

Im starting to think the problem is to do with the ''spaces'', which im not all too clued up on, so if anyone could tell me what the matrices should be that i should be multiplying by that would be great.

Another very wierd point, was trying to use the power function, from my overwhelmingly strong grasp of maths I thought (x)^1 would equal x.. but if i try and say:
specular = pow(specular,1);
then everything just goes white. Whats the deal with this!?

The only shader that didnt seem to work at all was the one i tried to figure out from the vs1 code:
nvidia document:

ADD RH,Rv,Rl;
DP3 RH.w,RH,RH;
RSQ RH.w,RH.w;
MUL RH,RH,RH.w;
read: halfvect = normalize(eye+light)

DP3 R0.y,Rn,RH;
read: r0=dot(normal, halfvect)

MOV R0.w,c[LIGHT_SPECULAR].w;
LIT R0,R0;
read: pow(r0,LIGHT_SPECULAR)

is how i interpreted it, so something still apears to be wrong.

all in all, none of them work, so if anyone could let me know what exactly is wrong (obviously the specular lighting equations everyone provided (or at least one of them) are correct, so it must be something else..)

the matrices are being set up via:

void DXVertexShader::SetTransViewMatrixITConstant(int position, D3DMATRIX *pTransform) {
D3DXMATRIX mat;
D3DXMatrixMultiply( &mat,(D3DXMATRIX *)pTransform, (D3DXMATRIX *)dxe->matView );
D3DXMatrixInverse(&mat,NULL,&mat);
D3DXMatrixTranspose( &mat, &mat );
dxe->g_pd3dDevice->SetVertexShaderConstant( position, &mat, 4 );
}

void DXVertexShader::SetTransViewProjMatrixConstant(int position, D3DMATRIX *pTransform) {
D3DXMATRIX mat;
D3DXMatrixMultiply( &mat,(D3DXMATRIX *)pTransform, (D3DXMATRIX *)dxe->matView );
D3DXMatrixMultiply( &mat, &mat, (D3DXMATRIX *)dxe->matProj);
D3DXMatrixTranspose( &mat, &mat );
dxe->g_pd3dDevice->SetVertexShaderConstant( position, &mat, 4 );
}

void DXVertexShader::SetTransViewMatrixConstant(int position, D3DMATRIX *pTransform) {
D3DXMATRIX mat;
D3DXMatrixMultiply( &mat,(D3DXMATRIX *)pTransform, (D3DXMATRIX *)dxe->matView );
D3DXMatrixTranspose( &mat, &mat );
dxe->g_pd3dDevice->SetVertexShaderConstant( position, &mat, 4 );
}

void DXVertexShader::SetTransMatrixConstant(int position, D3DMATRIX *pTransform) {
D3DXMATRIX mat(*pTransform);
D3DXMatrixTranspose( &mat, &mat );
dxe->g_pd3dDevice->SetVertexShaderConstant( position, &mat, 4 );
}


where pTransform would be set to D3DTS_WORLD, matProj to D3DTS_PROJECTION and matView to D3DTS_VIEW in the fixed pipeline...

im setting ''Eye'' to just the cameras position, and ''LightVect'' to the normalized direction of the light.

thanks!

Share this post


Link to post
Share on other sites
hey,
figured out what was wrong, i was using 4x4 matrices in places where i should only be using 3x3 (i assumed putting the .xyz at the end of the mul would tell the compiler that it was a 3x3) instead i just needed to cast the input matrix to a float3x3 aswell..
eg:

float3 nVec = mul((float3x3)ModelView, IN.Normal.xyz).xyz;


but i still cant figure out what im doing wrong with the power function.. if i calculate the specular highlight, and then do:

specular = pow(specular,1);


then everything just goes all white..
any posible explanations?
thanks!

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!