c++ - Point Lighting Error Directx 11 -
i'm new directx 11, , programmed distance dependent point light shader works pretty rotated , translated objects, after tried scaling models, lighting got dimmer if scaled model larger, , lighting got brighter if scaled model smaller. thought might normals, made sure multiply them inverse transpose of world matrix, , made sure normalize them in pixel shader after interpolated. here shader code:
texture2d txdiffuse : register( t0 ); samplerstate samanisotropic { filter = anisotropic; maxanisotropy = 4; }; cbuffer constantbuffer : register( b0 ) { matrix world; matrix view; matrix projection; matrix worldinvtrans; float3 lightpos; float pad1; float3 eyepos; float pad2; float3 at; float pad3; float shownorms; } struct vs_input { float4 pos : position; float3 norm : normal; float2 texcoor : texcoord0; }; struct ps_input { float4 pos : sv_position; float3 norm : normal; float3 lightdir : position0; float3 eyevector : position1; float2 texcoor : texcoord0; float distance : float0; float shownorms : float1; }; ps_input vs( vs_input input ) { ps_input output = (ps_input)0; output.pos = mul( input.pos, world ); output.lightdir = normalize( lightpos - output.pos ); output.eyevector = normalize( eyepos - @ ); output.distance = distance( lightpos, output.pos); output.pos = mul( output.pos, view ); output.pos = mul( output.pos, projection ); output.norm = mul( input.norm, worldinvtrans ); output.texcoor = input.texcoor; output.shownorms = shownorms; return output; } float4 ps( ps_input input) : sv_target { input.norm = normalize( input.norm ); float specterm = 0; float3 reflvector = normalize( reflect( input.lightdir, input.norm ) ); [flatten] if ( dot( reflvector, input.eyevector ) >= 0 ) { specterm = pow( dot( reflvector, input.eyevector ) , 50 ); } float diffuseterm = saturate( dot( input.lightdir, input.norm ) ); float4 ambient = float4( 0.25f, 0.25f, 0.25f, 1.0f ); float4 lightcolor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); return ( (ambient + (diffuseterm + specterm) / (pow( input.distance, 1 ) * 0.025f)) * lightcolor * txdiffuse.sample( samanisotropic, input.texcoor ) ) * ( 1 - input.shownorms ) + float4( input.norm, 1.0f ) * input.shownorms; }
i still suspicious normals weren't correct, edited last line in pixel shader shade model based on normal vectors if shownorms = 1.0f. normals looked transformed correctly. still suspicious, replaced model plane on xz axis, , scaled 50 times. when rendered it, lighting still dim, plane green when set shownorms 1.0f, must mean normals pointing in upwards y direction. if i'm transforming normals correctly , normalizing them, causing these lighting errors?
if helps, here code when set constant buffers plane:
//render plane mworld = xmmatrixidentity(); cb1.mworld = xmmatrixtranspose( xmmatrixmultiply( xmmatrixmultiply( mworld, xmmatrixscaling( 50.0f, 1.0f, 50.0f ) ), xmmatrixtranslation( 0.0f, -5.0f, 0.0f ) ) ); xmmatrix = cb1.mworld; a.r[3] = xmvectorset(0.0f, 0.0f, 0.0f, 1.0f); det = xmmatrixdeterminant(a); cb1.mworldinvtrans = xmmatrixinverse(&det, a); g_pimmediatecontext->updatesubresource( g_pcbuffershader1, 0, null, &cb1, 0, 0 );
edit: changed code little bit fix specterm:
texture2d txdiffuse : register( t0 ); samplerstate samanisotropic { filter = anisotropic; maxanisotropy = 4; }; cbuffer constantbuffer : register( b0 ) { matrix world; matrix view; matrix projection; matrix worldinvtrans; float3 lightpos; float pad1; float3 eyepos; float pad2; float3 at; float pad3; float shownorms; } struct vs_input { float4 pos : position; float3 norm : normal; float2 texcoor : texcoord0; }; struct ps_input { float4 pos : sv_position; float3 norm : normal; float3 lightdir : position0; float3 eyevector : position1; float2 texcoor : texcoord0; float distance : float0; float shownorms : float1; }; ps_input vs( vs_input input ) { ps_input output = (ps_input)0; output.pos = mul( input.pos, world ); output.lightdir = lightpos - output.pos; output.eyevector = eyepos - at; output.distance = distance( lightpos, output.pos ); output.pos = mul( output.pos, view ); output.pos = mul( output.pos, projection ); output.norm = mul( input.norm, worldinvtrans ); output.texcoor = input.texcoor; output.shownorms = shownorms; return output; } float4 ps( ps_input input) : sv_target { input.norm = normalize( input.norm ); input.lightdir = normalize( input.lightdir ); input.eyevector = normalize( input.eyevector ); float specterm = 0; float3 reflvector = normalize( reflect( -input.lightdir, input.norm ) ); [flatten] if ( dot( reflvector, input.eyevector ) >= 0 ) { specterm = pow( dot( reflvector, input.eyevector ) , 50 ); } float diffuseterm = saturate( dot( input.lightdir, input.norm ) ); float4 ambient = float4( 0.25f, 0.25f, 0.25f, 1.0f ); float4 lightcolor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); return ( (ambient + (diffuseterm + specterm) / (pow( input.distance, 1 ) * 0.025f)) * lightcolor * txdiffuse.sample( samanisotropic, input.texcoor ) ) * ( 1 - input.shownorms ) + float4( input.norm, 1.0f ) * input.shownorms; }
i think should try normalize lightdir vector in pixel shader well. if plane large may happen, after interpolation of these 2 vectors, vector in pixel shader not normalized. error increase scale goes up. give try. picture below shows problem.
Comments
Post a Comment