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

<p>Results:
<a href="https://i.sstatic.net/tpgrW.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/tpgrW.jpg" alt="enter image description here"></a></p>

CC BY-SA 3.0
2016-09-20T16:37:24.520Z
Nice looking results!
Alan Wolfe
CC BY-SA 3.0
2016-09-19T10:19:05.920Z
2016-09-19T10:19:05.920Z
Josh Nuttall
<p>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.</p>

<p>I am working from <a href="http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf" rel="nofollow noreferrer">Epic's paper on PBR</a> 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.</p>

<p>The method I am using for tube lighting is as follows:</p>

<pre><code>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 ;
}
</code></pre>

<p>If the code snippet is not enough to help solve this issue you can download the <a href="https://github.com/dragonCASTjosh/Urho3D" rel="nofollow noreferrer">full area lighting branch</a> 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 </p>

<pre><code>[build location]/bin/CoreData/Shaders/HLSL
</code></pre>

<p><a href="https://i.sstatic.net/BinG1.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/BinG1.jpg" alt="tube light image"></a></p>

<p>You can see that both images look identical <a href="https://i.sstatic.net/uAZTJ.jpg" rel="nofollow noreferrer">here</a>.</p>

<p>If pos in multiplied into line 40 then it creates more of a tube effect but is still far from correct results, <a href="https://i.sstatic.net/BlYLP.jpg" rel="nofollow noreferrer">As you can see here</a>.</p>

CC BY-SA 3.0
2016-09-16T23:54:53.233Z
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
CC BY-SA 3.0
2016-09-17T00:11:49.867Z
cant post images as i need 10 rep to do more then 2 links
Josh Nuttall
CC BY-SA 3.0
2016-09-17T00:18:24.220Z
Annoying. Someone please upvote this question more :p
Alan Wolfe
CC BY-SA 3.0
2016-09-17T00:21:00.593Z
Could try this [http://imgur.com/a/IxhTd](http://imgur.com/a/IxhTd)
Josh Nuttall
CC BY-SA 3.0
2016-09-17T00:23:04.243Z
I added the link.  For whatever it's worth, is the top or bottom image supposed to be the tube light?
Alan Wolfe
CC BY-SA 3.0
2016-09-17T00:24:22.033Z
yea the botton one is tube lights, the sizes are currently set through defines as its easier to debug. the values are  #define LightRad 0.4
    #define LightLengh 0.5
Josh Nuttall
CC BY-SA 3.0
2016-09-17T08:32:52.263Z
I've edited to clarify which paper in the link is the Epic one - please edit if I've misinterpreted your intention. You should be able to edit in the link to the website you mentioned now too, with your increased reputation.
trichoplax is on Codidact now
CC BY-SA 3.0
2016-09-17T08:48:28.493Z
thanks for cleaning it up a little, i changed the image to the tube lighting one as i felt it was more relevant :)
Josh Nuttall
CC BY-SA 3.0
2016-09-17T21:46:18.580Z
Added a little more detail on multiplying in the light position into L01, it creates a closer to tube look but is not right as the tube rotates.
Josh Nuttall
<lighting><physically-based><directx11><hlsl><pbr>
Error with tube lighting
Josh Nuttall
# Error with tube lighting

(Asked by: username_0 on 2016-09-16)

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](http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf) 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](https://github.com/dragonCASTjosh/Urho3D) 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

```

[![tube light image](https://i.sstatic.net/BinG1.jpg)](https://i.sstatic.net/BinG1.jpg)

You can see that both images look identical [here](https://i.sstatic.net/uAZTJ.jpg).

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](https://i.sstatic.net/BlYLP.jpg).

**Tags:** lighting, physically-based, directx11, hlsl, pbr

> **Comments:**
> **username_1**: 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 (:  
> **username_0**: cant post images as i need 10 rep to do more then 2 links  
> **username_1**: Annoying. Someone please upvote this question more :p  
> **username_0**: Could try this [http://imgur.com/a/IxhTd](http://imgur.com/a/IxhTd)  
> **username_1**: I added the link.  For whatever it's worth, is the top or bottom image supposed to be the tube light?  
> **username_0**: yea the botton one is tube lights, the sizes are currently set through defines as its easier to debug. the values are  #define LightRad 0.4     #define LightLengh 0.5  
> **username_2**: I've edited to clarify which paper in the link is the Epic one - please edit if I've misinterpreted your intention. You should be able to edit in the link to the website you mentioned now too, with your increased reputation.  
> **username_0**: thanks for cleaning it up a little, i changed the image to the tube lighting one as i felt it was more relevant :)  
> **username_0**: Added a little more detail on multiplying in the light position into L01, it creates a closer to tube look but is not right as the tube rotates.  

---

## 1 answers

### Answer by username_0 on 2016-09-19. Score: 4 | Accepted answer

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:
[![enter image description here](https://i.sstatic.net/tpgrW.jpg)](https://i.sstatic.net/tpgrW.jpg)

> **Comments:**
> **username_1**: Nice looking results!  

---

