sukovf, on 01 March 2012 - 02:22 PM, said:
Hi guys.
I am trying to achieve simple light shafts effect and have some weird problem with it.

As you can see the 3/4 of the effect look quite good but there are weird streaks going top left. This is the HLSL code:
float3 lightPos;
float2 texCoords=input.TexCoords;
float4 pos=lightPos;
pos.x=((lightPos.x+1.0f)/2.0f);
pos.y=((-lightPos.y+1.0f)/2.0f);
float2 dir=(texCoords-pos.xy)/SAMPLES;
float3 sum=0.0f;
float add=1.0f;
for(int i=0;i<SAMPLES;i++)
{
float val=tex2D(tex, texCoords).rgb;
sum+=val*add;
add*=0.94f;
texCoords-=dir;
}
return float4(sum, 1.0f);
Light position in screen space is computed in C++ this way:
D3DXVec3Transform(&outPos, &lightPosWorldSpace, &(camera->GetViewMatrix()*camera->GetProjMatrix()));
"outPos" is a D3DXVECTOR3 and is passed to the shader.
Screen space position of the light looks good. I have no idea what is wrong.
Any advice please?
If you don't perform homogeneous division by w that can lead to problems ! Therefore, I suggest you to perform the light position transform using a 4D vector like this: lightPos4D = D3DXVECTOR4(lightPosWorldSpace,1.f);
(supposing that lightPosWorldSpace is a 3D vector of course).
Then you transform that 4D vector by viewProjection and then perform division by w and only then your lightPos will be in normalized screen space which goes from 0,1 and not from -w,w (as in the case of clip space)
D3DXVec4Transform(&clipSpaceLightPos,&D3DXVECTOR4(lightPosWorldSpace,1.f),&(camera->GetViewMatrix()*camera->GetProjMatrix()));
D3DXVECTOR4 screenSpaceLightPos = clipSpaceLightPos / clipSpaceLightPos.w; //after the division by w your light position will be in screen space
// so you pass screenSpaceLightPos to the shader (of course you can just pass it as a 3D vector now if you want, as after the homogeneous division w would equal to 1 )
Also remember that you should always transform the points (and therefore not the directions) in the form of 4D vectors and only directions should be threated as 3D vectors eventually. The reason is simple: directions are translation invariant (therefore no need to specify the 4th component which obviously would be 0). Points are points !!! Not directions so they are not translation invariant (therefore you need the 4th component specyfing 1 to account for the translation part of the 4x4 matrix).
Directions are not rotation nor scaling invariant that's why the only thing that will change if you transform a direction will be it's direction

and eventually its length (if the scaling part is not 1).
So, when you transform directions you should always use the inverseTranspose of your transformation matrix to account for the general case.
Let me know if it works for you and show me the results