2D rendering with per-pixel lighting/normal map - directX
I'm looking for the simplest, easiest and fastest technique to render 2D textured quads with per-pixel normals. what i mean is a 3D world where the camera is fixed and all the texture quads are facing to the same direction (the camera), and between them there will be light points, and i want the textures to have per-pixel normal values so they'll lit as if they were 3D models.
most techniques i found on the net are way too complicated and heavy cause they refer to real 3D models,开发者_JS百科 while all i need is simple 2d quads.
does anyone knows an appropriate technique or can post a useful tutorial? oh, and DX only pls.
thanks.
I'm more experienced with XNA rather than directX, but the principle is the same.
You need a normal map, this tells your shader exactly what the surface normal is at a given point. You then need your quads to be texture mapped (they probably already are, so this isn't really any extra work). Then you draw the quads with a pixel shader, inside the shader you do something like:
//This shader only handles one directional light, there are various tecnhiques for handling multiple lights.
float3 LightDirection;
//Normal map, set this before rendering the quad
Texture NormalMap;
//sampler
sampler normalSampler = sampler_state
{
texture = <NormalMap>;
}
//Diffusemap, set this before rendering the quad. This is just your normal texture you want applied to the quad
Texture DiffuseMap;
//sampler
sampler diffuseSampler = sampler_state
{
texture = <DiffuseMap>;
}
/* you probably need a vertex shader to run all your translations etc, that's pretty bog standard stuff so I won't include one here */
float4 PixelShader(float2 texCoord : TEXCOORD0) : COLOR0
{
//standard directional lighting equation with normals
float3 Normal = tex2D(normalSampler, texCoord);
float dot = dot(LightDirection, Normal);
return tex2D(normalSampler, texCoord) * dot;
}
Well in that case you don't even need to form a tangent basis which makes it quite easy. Assuming, directional lighting, if you transform your light into view space then you can directly N.L the light (L) against the normal (N) from the normal map. You transform teh light vector into view space by simply multiplying it by the view matrix.
It is a little more complicated if you want point lighting. You need to first transform your light position into view space. Then you need to subtract your light position from your pixel position, normalise the resulting vector and use that as your L vector in the N.L calculation :)
Either, way ... job done! :D
精彩评论