# Error with tube lighting

I have recently been working on area lights for a small open source game engine called Urho3D but have run into an issues when rendering tube lights where the lights look the same as sphere lights despite the length value being changed.

I am working from Epic's paper on PBR by Brian Karis. I have tried looking at other sources to see if I could find anything but none of the results fixed the issue I was having.

The method I am using for tube lighting is as follows:

float3 TubeLight(float3 worldPos, float3 lightVec, float3 normal, float3 toCamera, float roughness, float3 specColor, out float ndl)
{
float3 pos   = (cLightPosPS.xyz - worldPos);
float3 reflectVec  = reflect(-toCamera, normal);

float3 L01 = lightVec * LightLengh;
float3 L0 = pos - 0.5 * L01;
float3 L1 = pos + 0.5 * L01;
float3 ld = L1 - L0;

float distL0    = length( L0 );
float distL1    = length( L1 );

float NoL0      = dot( L0, normal ) / ( 2.0 * distL0 );
float NoL1      = dot( L1, normal ) / ( 2.0 * distL1 );
ndl             = ( 2.0 * clamp( NoL0 + NoL1, 0.0, 1.0 ) )
/ ( distL0 * distL1 + dot( L0, L1 ) + 2.0 );

float RoL0      = dot( reflectVec, L0 );
float RoLd      = dot( reflectVec, ld );
float L0oLd     = dot( L0, ld );
float distLd    = length( ld );
float t         = ( RoL0 * RoLd - L0oLd )
/ ( distLd * distLd - RoLd * RoLd );

float3 closestPoint   = L0 + ld * saturate( t);
float3 centreToRay    = dot( closestPoint, reflectVec ) * reflectVec - closestPoint;
closestPoint = closestPoint + centreToRay * saturate(LightRad / length(centreToRay));

float3 l = normalize(closestPoint);
float3 h = normalize(toCamera + l);

ndl       = saturate(dot(normal, l));
float hdn = saturate(dot(h, normal));
float hdv = dot(h, toCamera);
float ndv = saturate(dot(normal, toCamera));

float distL      = length(closestPoint);
float alpha      = roughness * roughness;
float alphaPrime = saturate(LightRad / (distL * 2.0) + alpha);

const float3 fresnelTerm = Fresnel(specColor, hdv) ;
const float distTerm     = Distribution(hdn, alphaPrime);
const float visTerm      = Visibility(ndl, ndv, roughness);

return distTerm * visTerm * fresnelTerm ;
}


If the code snippet is not enough to help solve this issue you can download the full area lighting branch from GitHub. Build instructions can be found on the Urho3D website (cant link due to reputation), note currently area lighting is only tested in DX11. Shader source files can be found under

[build location]/bin/CoreData/Shaders/HLSL


You can see that both images look identical here.

If pos in multiplied into line 40 then it creates more of a tube effect but is still far from correct results, As you can see here.

• Could we see an image of how it looks? You said it looks the same with tube lights vs not so if you don't feel like posting both images that's ok, but an image alone might shed some light on things (: – Alan Wolfe Sep 16 '16 at 23:54
• cant post images as i need 10 rep to do more then 2 links – Josh Nuttall Sep 17 '16 at 0:11
• Annoying. Someone please upvote this question more :p – Alan Wolfe Sep 17 '16 at 0:18
• Could try this http://imgur.com/a/IxhTd – Josh Nuttall Sep 17 '16 at 0:21
• I added the link. For whatever it's worth, is the top or bottom image supposed to be the tube light? – Alan Wolfe Sep 17 '16 at 0:23

Found the solution, it turns out the lightVec is not the vector of light from the tube but rather the direction the tube will point. Therefore i will need to pass it a light rotation value to be used there.

Results:

• Nice looking results! – Alan Wolfe Sep 20 '16 at 16:37