<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[HLSL] Point Light and 2D Normal Mapping</title>
		<link>http://www.allegro.cc/forums/view/606857</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 30 Mar 2011 21:27:51 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Here&#39;s my (well, mostly borrowed) shader code:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">   1</span>float4x4 World<span class="k2">;</span>
<span class="number">   2</span>float4x4 View<span class="k2">;</span>
<span class="number">   3</span>float4x4 Projection<span class="k2">;</span>
<span class="number">   4</span>
<span class="number">   5</span>texture DiffuseTexture<span class="k2">;</span>
<span class="number">   6</span>texture BumpTexture<span class="k2">;</span>
<span class="number">   7</span>texture NormalTexture<span class="k2">;</span>
<span class="number">   8</span>float3 CameraPos<span class="k2">;</span>
<span class="number">   9</span>float3 LightPosition<span class="k2">;</span>
<span class="number">  10</span>float3 LightDiffuseColor<span class="k2">;</span> <span class="c">// intensity multiplier</span>
<span class="number">  11</span>float3 LightSpecularColor<span class="k2">;</span> <span class="c">// intensity multiplier</span>
<span class="number">  12</span><span class="k1">float</span> LightDistanceSquared<span class="k2">;</span>
<span class="number">  13</span>float3 DiffuseColor<span class="k2">;</span>
<span class="number">  14</span>float3 AmbientLightColor<span class="k2">;</span>
<span class="number">  15</span>float3 EmissiveColor<span class="k2">;</span>
<span class="number">  16</span>float3 SpecularColor<span class="k2">;</span>
<span class="number">  17</span><span class="k1">float</span> SpecularPower<span class="k2">;</span>
<span class="number">  18</span><span class="k1">bool</span> BumpMapping <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span>
<span class="number">  19</span>
<span class="number">  20</span>sampler texsampler <span class="k3">=</span> sampler_state
<span class="number">  21</span><span class="k2">{</span>
<span class="number">  22</span>  Texture <span class="k3">=</span> <span class="k3">&lt;</span>DiffuseTexture&gt;<span class="k2">;</span>
<span class="number">  23</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  24</span>
<span class="number">  25</span>sampler bumpsampler <span class="k3">=</span> sampler_state
<span class="number">  26</span><span class="k2">{</span>
<span class="number">  27</span>  Texture <span class="k3">=</span> <span class="k3">&lt;</span>BumpTexture&gt;<span class="k2">;</span>
<span class="number">  28</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  29</span>
<span class="number">  30</span>sampler normalsampler <span class="k3">=</span> sampler_state
<span class="number">  31</span><span class="k2">{</span>
<span class="number">  32</span>  Texture <span class="k3">=</span> <span class="k3">&lt;</span>NormalTexture&gt;<span class="k2">;</span>
<span class="number">  33</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  34</span>
<span class="number">  35</span><span class="k1">struct</span> VertexShaderInput
<span class="number">  36</span><span class="k2">{</span>
<span class="number">  37</span>  float4 Position <span class="k2">:</span> POSITION0<span class="k2">;</span>
<span class="number">  38</span>  float2 TexCoords <span class="k2">:</span> TEXCOORD0<span class="k2">;</span>
<span class="number">  39</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  40</span>
<span class="number">  41</span><span class="k1">struct</span> VertexShaderOutput
<span class="number">  42</span><span class="k2">{</span>
<span class="number">  43</span>  float4 Position <span class="k2">:</span> POSITION0<span class="k2">;</span>
<span class="number">  44</span>  float2 TexCoords <span class="k2">:</span> TEXCOORD0<span class="k2">;</span>
<span class="number">  45</span>  float3 WorldPos <span class="k2">:</span> TEXCOORD1<span class="k2">;</span>
<span class="number">  46</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  47</span>
<span class="number">  48</span>VertexShaderOutput VertexShaderFunction<span class="k2">(</span>VertexShaderInput input<span class="k2">)</span>
<span class="number">  49</span><span class="k2">{</span>
<span class="number">  50</span>  VertexShaderOutput output<span class="k2">;</span>
<span class="number">  51</span>
<span class="number">  52</span>  <span class="c">// "Multiplication will be done in the pre-shader - so no cost per vertex"</span>
<span class="number">  53</span>  float4x4 viewprojection <span class="k3">=</span> mul<span class="k2">(</span>View, Projection<span class="k2">)</span><span class="k2">;</span>
<span class="number">  54</span>  float4 posWorld <span class="k3">=</span> mul<span class="k2">(</span>input.Position, World<span class="k2">)</span><span class="k2">;</span>
<span class="number">  55</span>  output.Position <span class="k3">=</span> mul<span class="k2">(</span>posWorld, viewprojection<span class="k2">)</span><span class="k2">;</span>
<span class="number">  56</span>  output.TexCoords <span class="k3">=</span> input.TexCoords<span class="k2">;</span>
<span class="number">  57</span>
<span class="number">  58</span>  <span class="c">// Passing information on to do both specular AND diffuse calculation in pixel shader</span>
<span class="number">  59</span>  output.WorldPos <span class="k3">=</span> posWorld<span class="k2">;</span>
<span class="number">  60</span>
<span class="number">  61</span>  <span class="k1">return</span> output<span class="k2">;</span>
<span class="number">  62</span><span class="k2">}</span>
<span class="number">  63</span>
<span class="number">  64</span>float4 PixelShaderFunctionWithTex<span class="k2">(</span>VertexShaderOutput input<span class="k2">)</span> <span class="k2">:</span> COLOR0
<span class="number">  65</span><span class="k2">{</span>
<span class="number">  66</span>  <span class="c">// Get light direction for this fragment</span>
<span class="number">  67</span>  float3 lightDir <span class="k3">=</span> normalize<span class="k2">(</span>input.WorldPos <span class="k3">-</span> LightPosition<span class="k2">)</span><span class="k2">;</span> <span class="c">// per pixel diffuse lighting</span>
<span class="number">  68</span>  float3 Normal <span class="k3">=</span> tex2D<span class="k2">(</span>normalsampler, input.TexCoords<span class="k2">)</span><span class="k2">;</span>
<span class="number">  69</span>
<span class="number">  70</span>  <span class="c">// Note: Non-uniform scaling not supported</span>
<span class="number">  71</span>  <span class="k1">float</span> diffuseLighting <span class="k3">=</span> saturate<span class="k2">(</span>dot<span class="k2">(</span>Normal, <span class="k3">-</span>lightDir<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  72</span>
<span class="number">  73</span>  <span class="c">// Introduce fall-off of light intensity</span>
<span class="number">  74</span>  diffuseLighting <span class="k3">*</span><span class="k3">=</span> <span class="k2">(</span>LightDistanceSquared <span class="k3">/</span> dot<span class="k2">(</span>LightPosition <span class="k3">-</span> input.WorldPos, LightPosition <span class="k3">-</span> input.WorldPos<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  75</span>
<span class="number">  76</span>  <span class="c">// Using Blinn half angle modification for perofrmance over correctness</span>
<span class="number">  77</span>  float3 h <span class="k3">=</span> normalize<span class="k2">(</span>normalize<span class="k2">(</span>CameraPos <span class="k3">-</span> input.WorldPos<span class="k2">)</span> <span class="k3">-</span> lightDir<span class="k2">)</span><span class="k2">;</span>
<span class="number">  78</span>  <span class="k1">float</span> specLighting <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_618.html" target="_blank">pow</a><span class="k2">(</span>saturate<span class="k2">(</span>dot<span class="k2">(</span>h, Normal<span class="k2">)</span><span class="k2">)</span>, SpecularPower<span class="k2">)</span><span class="k2">;</span>
<span class="number">  79</span>  float4 texel <span class="k3">=</span> tex2D<span class="k2">(</span>texsampler, input.TexCoords<span class="k2">)</span><span class="k2">;</span>
<span class="number">  80</span>  float4 bump <span class="k3">=</span> tex2D<span class="k2">(</span>bumpsampler, input.TexCoords<span class="k2">)</span><span class="k2">;</span>
<span class="number">  81</span>
<span class="number">  82</span>  <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>BumpMapping<span class="k2">)</span>
<span class="number">  83</span>  <span class="k2">{</span>
<span class="number">  84</span>   bump <span class="k3">=</span> float4<span class="k2">(</span><span class="n">1</span>, <span class="n">1</span>, <span class="n">1</span>, <span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  85</span>  <span class="k2">}</span>
<span class="number">  86</span>
<span class="number">  87</span>  <span class="k1">return</span> float4<span class="k2">(</span>saturate<span class="k2">(</span>
<span class="number">  88</span>    AmbientLightColor <span class="k3">+</span>
<span class="number">  89</span>    <span class="k2">(</span>texel.xyz <span class="k3">*</span> DiffuseColor <span class="k3">*</span> LightDiffuseColor <span class="k3">*</span> diffuseLighting <span class="k3">*</span> <span class="n">0</span>.<span class="n">6</span> <span class="k3">*</span> bump<span class="k2">)</span> <span class="k3">+</span> <span class="c">// Use light diffuse vector as intensity multiplier</span>
<span class="number">  90</span>    <span class="k2">(</span>SpecularColor <span class="k3">*</span> LightSpecularColor <span class="k3">*</span> specLighting <span class="k3">*</span> <span class="n">0</span>.<span class="n">5</span> <span class="k3">*</span> bump<span class="k2">)</span> <span class="c">// Use light specular vector as intensity multiplier</span>
<span class="number">  91</span>    <span class="k2">)</span>, texel.w<span class="k2">)</span><span class="k2">;</span>
<span class="number">  92</span>  <span class="k2">}</span>
<span class="number">  93</span>
<span class="number">  94</span>technique TechniqueWithTexture
<span class="number">  95</span><span class="k2">{</span>
<span class="number">  96</span>  pass Pass1
<span class="number">  97</span>  <span class="k2">{</span>
<span class="number">  98</span>    VertexShader <span class="k3">=</span> compile vs_2_0 VertexShaderFunction<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  99</span>    PixelShader <span class="k3">=</span> compile ps_2_0 PixelShaderFunctionWithTex<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 100</span>  <span class="k2">}</span>
<span class="number"> 101</span><span class="k2">}</span>
</div></div><p>

I&#39;m using a point light (its center is more or less in the middle of the image). Here&#39;s what happens:<br /><span class="remote-thumbnail"><span class="json">{"name":"603774","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/7\/a762dc61dd86ec552182359a45e849ac.png","w":712,"h":714,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/7\/a762dc61dd86ec552182359a45e849ac"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/a/7/a762dc61dd86ec552182359a45e849ac-240.jpg" alt="603774" width="240" height="240" /></span></p><p>So, everything seems to be working perfectly for the top left part of the screen, but the other side of the light is completely black.</p><p>I isolated the fault to the <span class="source-code"><span class="k1">float</span> diffuseLighting <span class="k3">=</span> saturate<span class="k2">(</span>dot<span class="k2">(</span>Normal, <span class="k3">-</span>lightDir<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></span> line, but I don&#39;t know why it doesn&#39;t work and how to fix it.</p><p>Any help in making it work like it&#39;s supposed to would be appreciated.</p><p>It would be fairly easy if I were to use directional lights, but I need point lights for this. Heck, directional lights wouldn&#39;t even require a vertex shader, because it&#39;s 2D anyway.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Mon, 28 Mar 2011 00:50:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Is the light <i>on</i> the same plane, or is it floating above the plane? I&#39;m not sure if it being on the plane would cause that error, but it might.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Mon, 28 Mar 2011 10:28:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The light is positioned at +50 Z. The camera is at +20 Z (ortographic). The plane is at 0 Z.</p><p>What is strange is that when I change that faulty line from -lightDir to +lightDir, the normal map is inverted, and the bottom right side works, while the top left one is black. Something really weird is going on here.</p><p><b>EDIT:</b> Praised be examples on the internet. Modifying that single line to <span class="source-code">float3 Normal <span class="k3">=</span> normalize<span class="k2">(</span><span class="k2">(</span><span class="n">2</span> <span class="k3">*</span> tex2D<span class="k2">(</span>normalsampler, input.TexCoords<span class="k2">)</span><span class="k2">)</span> <span class="k3">-</span> <span class="n">1</span>.<span class="n">0</span><span class="k2">)</span><span class="k2">;</span></span> fixed the issue. Still, thanks for trying to help. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p><b>EDIT 2:</b></p><p><div class="media-player youtube"><div style="margin: 1em 2em; background: url(/images/movie.png); width: 180px; height: 100px; text-align: center;"><a href="http://www.allegro.cc//www.youtube.com/watch?v=bEIYDpqTZZs" target="_blank"><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/object/9/d/9ddf402a71e238b5baeded19ffc245f9.jpg" border="0" alt="video" title="Click to play video" /></a></div></div>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Tue, 29 Mar 2011 00:37:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>So puurty! <img src="http://www.allegro.cc/forums/smileys/cheesy.gif" alt=":D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Billybob)</author>
		<pubDate>Wed, 30 Mar 2011 11:21:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks! Who said 2D games can&#39;t be pretty? <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (CursedTyrant)</author>
		<pubDate>Wed, 30 Mar 2011 21:27:51 +0000</pubDate>
	</item>
</rss>
