Sign in to follow this  
Icebone1000

[hlsl]Phong Specular(not Blinn) problem when rotating objects.

Recommended Posts

Icebone1000    1958
Hi, Im trying to implement the most basic shader, Im not experient with shaders but things looks fine at first. My shader calculates ambient + diffuse + specular + texture to outputs the final color, with distance attenuation for diffuse and specular only. I was using Blinn Phongs for specular, and it works perfectly, but now I want implement the original phong(with the reflection vector). At first it looked perfect(the original phong), I noticed the difference on the final result, moved the specular position to see the behavior, translated the object, and everything looks fine. The problem is when I rotate the object, the phong specular highlight looks glued on the object, it rotates together with the object, not as expected. Heres some screenshots:( as you will see, the lights are long(not circular) because it is suppose to be on the "left side" of the ball(as if you where looking at a point where the light lits the ball from the left(a commom behavior of phong speculars, like the sun iluminates the moon, get it?) glued phong1 glued phong2 Now look at the blinn phong, it looks ok: blinn1 blinn1 Heres my shader, the blinn part is commented out:
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------

cbuffer cbChangers{
	matrix mWorld;				//space transformations-WORLD
	float4 vSpecularPos;		//SPECULAR POSITION
};
cbuffer cbConstants{
	matrix mView;				//space transformations-VIEW
	matrix mProjection;			//space transformations-PROJECTION
	float4 vDiffuseDir[2];		//DIFFUSE LIGHT DIRECTION
	float4 vDiffuseColor[2];	//DIFFUSE LIGHT COLOR
	float4 vAmbientColor;		//AMBIENT COLOR
	float4 vSpecularColor;		//SPECULAR COLOR
	float4 vCamPos;				//camera position
};
//cbuffer cbChangeOnResize{
//	matrix mProjection;//space transformations-PROJECTION
//};

//resources
Texture2D tex2D;
SamplerState samLinear{
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = Wrap;
    AddressV = Wrap;
};




struct VS_INPUT{
	float4 Pos : POSITION;
	float3 Norm : NORMAL;
	float2 Tex : TEXCOORD;

	float4 ka : MATERIAL0;
	float4 kd : MATERIAL1;
	float4 ks : MATERIAL2;
	float  sn : MATERIAL3;
	float4 tf : MATERIAL4;
};

struct PS_INPUT{
	float4 Pos : SV_POSITION;
	float3 Norm : NORMAL;
	float2 Tex : TEXCOORD;

	float4 ka : MATERIAL0;
	float4 kd : MATERIAL1;
	float4 ks : MATERIAL2;
	float  sn : MATERIAL3;
	float4 tf : MATERIAL4;

	float3 PosToCamvvv : PHONG1;//phong
	float3 Reflectvvv  : PHONG2;//phong
	float4 SpecDistAttFactor : DISTATT;//
	//float4 HalfWayvvv : BLINN;//blinn phong	
};


//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input_p ){

	PS_INPUT vs_output = (PS_INPUT)0;

		//pos and normal world transform:
	vs_output.Pos = mul( input_p.Pos, mWorld );
	vs_output.Norm = mul( input_p.Norm, (float3x3)mWorld );

		//send texture:
	vs_output.Tex = input_p.Tex;

		//send materials:
	vs_output.ka = input_p.ka;
	vs_output.kd = input_p.kd;
	vs_output.ks = input_p.ks;
	vs_output.sn = input_p.sn;
	vs_output.tf = input_p.tf;

		//phong/blinn phong vectors(v pos to cam and vpos to lit):	
	const float4 vPosToCam = vCamPos - vs_output.Pos;//normalize if phong(the VIEW vector)
	const float4 vPosToSpec = vSpecularPos - vs_output.Pos;//normalize if phong(the -LIGHT(dir) vector)
	//const float4 vSpecToPos = vs_output.Pos - vSpecularPos;

		//blinn phong halfway vector:(halfway = CamToV vector + SpecToV vector)
	//vs_output.HalfWayvvv = normalize( vPosToCam + vPosToSpec );//a moral eh q aki ainda tem a pos original do vertice, nao a transformada em view+projection

		//phong reflect and pos to cam vectors:		
	vs_output.Reflectvvv = normalize(reflect( -vPosToSpec, input_p.Norm ));//normalize(2 * dot(normalize(-vPosToSpec),input_p.Norm)*input_p.Norm-normalize(-vPosToSpec));
	vs_output.PosToCamvvv = normalize(vPosToCam);//ps needs(the VIEW vector)

		//attenuation factor = 1/distancia(sqrtt( (x2-x1)^2 + (y2-y1)^2 ))^2
	const float dist = distance(vs_output.Pos, vSpecularPos);
	vs_output.SpecDistAttFactor = 1/( 1.0 + 0.005*dist + 0.000000005*(dist*dist) ); //pow( dist, 2.0);

		//pos view and projection transform:
	vs_output.Pos = mul( vs_output.Pos, mView );
	vs_output.Pos = mul( vs_output.Pos, mProjection );

	return vs_output;//SV_POSITION + TEXCOORD
}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input_p ) : SV_TARGET{


	float4 finalcolor = 0;

	
		//DIFFUSE:
		//normal.diffusedir for the 2 lites:(saturate keeps on the range 0-1)
	for( int i = 0; i<2; i++ ){
		finalcolor += saturate(dot( input_p.Norm, (float3)-vDiffuseDir[i] )) * vDiffuseColor[i]		*input_p.kd * input_p.SpecDistAttFactor;
	}
	//finalcolor.a = 1;//alpha

		//AMBIENT:
	finalcolor += vAmbientColor		*input_p.ka;

		//SPECULAR:(power always turns positive, thats why saturate comes first)
		//blinn phong specular:
	//finalcolor += pow( saturate(dot( input_p.HalfWayvvv, input_p.Norm )), input_p.sn/*8*/) * vSpecularColor   *input_p.ks * input_p.SpecDistAttFactor;

		//phong specular:
	finalcolor += pow( saturate(dot( input_p.Reflectvvv, input_p.PosToCamvvv )), input_p.sn) * vSpecularColor		*input_p.ks * input_p.SpecDistAttFactor;

		//TEXTURE:
	finalcolor *= tex2D.Sample( samLinear, input_p.Tex );

	//finalcolor *= input_p.tf;

	return finalcolor;//SV_TARGET
}


Just pay attention to the specular part, I have 2 diffuse and an ambient light that dont have anything to do with the specular(I did the lights like each one (ambient, diffuse and specular) are independents sources.) You dont have idea of how much time I alredy spent trying to figure out whats going on, every tutorial/book/article/whatever I read says the same thing, and comparing with my shader I dont see any difference.. Whats phong specular on my view: dot product of Reflection vector and View vector, power specular shinness. The view vector as I saw on all the books I read is the vector FROM the vertex TO the cam position, calculated as cam pos - vertex pos(in THAT ORDER) The reflection is calculated with the light direction and the vertex normal, I alredy saw the light vector calculated in different ways on many places, but on all the books I read it was FROM the vertex TO the light pos, witch means calculated as lightpos - vertexpos(in THAT ORDER), but as I said, I alredy saw calculated from the lightpos TO the vertexpos(but that DOESNT change the problem when rotating the object)... Anything I missing? If you need more information let me know..

Share this post


Link to post
Share on other sites
nullsquared    126
Quote:


vs_output.Reflectvvv = normalize(reflect( -vPosToSpec, input_p.Norm ));



You're calculating your reflected vector using the object's local normal, instead of the world-space normal.

Your Blinn-Phong version works because you're using the world-space normal in the pixel shader.

Share this post


Link to post
Share on other sites
Icebone1000    1958
Quote:
Original post by nullsquared
Quote:


vs_output.Reflectvvv = normalize(reflect( -vPosToSpec, input_p.Norm ));



You're calculating your reflected vector using the object's local normal, instead of the world-space normal.

Your Blinn-Phong version works because you're using the world-space normal in the pixel shader.


Damn dude, would u mary me? xD
Tsc..Whats the problem with me, I said to my self "its problem something stupid that Im not saying, wheres it?" can you believe? At sometime I changed the order with I calculated the normal transformation, but I never figured out I wasnt using the alredy calculated normal.( I was ok because the calculation was happening before )
Thanks a lot, works like a charm.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this