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


How to add specular effect to per-pixel lighting?

Recommended Posts

kimryo    100
Now I already added ambient+diffuse with 2 pass, ambient is constant color value;diffuse is a normalmap. What need to be down to add specular? thanks. We create world.

Share this post

Link to post
Share on other sites
S1CA    1418
Another pass to do:


- N is the normal vector,
- H is the (Blinn) Half vector: [H=normalise(V + L), V=view vector, L=light vector]
- p is the power or shininess

[As an alternative you could use the Phong specular reflection vector]

There are two difficult parts:

- normalisation of the half vector. A common technique is to use a "normalization cubemap" where the input vector is put into the u,v,w texture coordinates for a cube map. The pixels of the cube map then all correspond to the normalised result of the source vector - texture clamping keeps the coordinates in range. An alternative is to use 2 pixel shader instructions to do the normalisation.

- the power - this usually requires multiplying the output of a stage with itself a few times (easier in a shader) - so you often start to need multiple passes for highet powers. A greater problem however is that raising the power of the specular value loses the lower bits of precision from each colour (the lower bits of your 8 bits per component) so you get ugly banding. Floating point textures/frame buffers are the best way round this.

Something else you''ve ommitted which can make per-pixel stuff look better is attenuation/falloff - you can do that in a shader or with lookup textures.

Simon O''Connor
Creative Asylum Ltd

Share this post

Link to post
Share on other sites
kimryo    100
Emm....the effect looks so bad...and many places should be speculared are not;and many white color blocks....
My code as follow :

{//Specular pass

m_D3DDevice.m_p->SetRenderState( D3DRS_TEXTUREFACTOR,
VectortoRGBA(&(m_vLookatPt-m_vEyePt),0.0f) );//View vector????

m_D3DDevice.m_p->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TFACTOR );
m_D3DDevice.m_p->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TEXTURE );//Base texture color,light vector?

m_D3DDevice.m_p->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_ADD );//Add,got halfway...

m_D3DDevice.m_p->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);//dotproduct3 to get N.H
m_D3DDevice.m_p->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );//Normalmap color
m_D3DDevice.m_p->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_D3DDevice.m_p->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_D3DDevice.m_p->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
m_D3DDevice.m_p->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );

m_D3DDevice.SetTexture(m_TexNormal,1);//base texture
m_Panel.m_Texture=m_TexLocal;//Normal map


What is wrong?

Add other two questions:
1, how to change the color of diffuse light?Now I only simply use the Normalmap to Dot with tfactor,then modulate with base texture...
2, what is the point for using cube-env-mapping in diffuse per-pixel lighting...


We create world.

[edited by - kimryo on April 28, 2003 10:14:26 PM]

Share this post

Link to post
Share on other sites