Archived

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

kimryo

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.H)^p

Where:
- 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
www.creative-asylum.com

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.SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
m_D3DDevice.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);

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
m_Panel.Render();

}

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...

thanks.

We create world.

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

Share this post


Link to post
Share on other sites