{"id":2494,"date":"2013-08-11T13:26:30","date_gmt":"2013-08-11T12:26:30","guid":{"rendered":"http:\/\/positech.co.uk\/cliffsblog\/?p=2494"},"modified":"2013-08-11T17:12:26","modified_gmt":"2013-08-11T16:12:26","slug":"normal-mapping-question-its-my-day-off","status":"publish","type":"post","link":"https:\/\/www.positech.co.uk\/cliffsblog\/2013\/08\/11\/normal-mapping-question-its-my-day-off\/","title":{"rendered":"Normal mapping question (it&#8217;s my day OFF)"},"content":{"rendered":"<p><span style=\"color: #ff0000;\"><strong>EDIT: I&#8217;ve fixed it. It&#8217;s my own dumbassness. I was setting the sprite_angle variable in the shader AFTER the shader had started, and it was presumably never being set, and populated with garbage (or the ship beforehand) it works a charm now :D<\/strong><\/span><\/p>\n<p>Right so, despite being good at AI coding and optimisation, i suck at this clever stuff you people call &#8216;3D math&#8217;. I was in the pub that day of school. So I enlist you, the all-knowing internet to explain to me like a child what I am doing wrong. Here are 3 images:<\/p>\n<p align=\"center\"><a href=\"http:\/\/positech.co.uk\/cliffsblog\/wp-content\/uploads\/2013\/08\/normalmapstuff.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2495\" alt=\"normalmapstuff\" src=\"http:\/\/positech.co.uk\/cliffsblog\/wp-content\/uploads\/2013\/08\/normalmapstuff.jpg\" width=\"768\" height=\"256\" srcset=\"https:\/\/www.positech.co.uk\/cliffsblog\/wp-content\/uploads\/2013\/08\/normalmapstuff.jpg 768w, https:\/\/www.positech.co.uk\/cliffsblog\/wp-content\/uploads\/2013\/08\/normalmapstuff-300x100.jpg 300w, https:\/\/www.positech.co.uk\/cliffsblog\/wp-content\/uploads\/2013\/08\/normalmapstuff-317x105.jpg 317w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>The left is just the ship, the middle is a normal map thingy (thanks to charles!) and the right is what it looks like on screen given a single light source. The end result is exactly what I wanted, and there is much rejoicing&#8230; BUT. It&#8217;s screwed up, the position of the light source is wrong, and seemingly random, and sometimes jumps and cycles all over the place. I reckon I have everything sorted except the shader, which is an fx file as follows:<\/p>\n<pre>sampler2D g_samSrcColor : register( s0);\r\nsampler2D g_samNormalMapColor: register( s1);\r\nfloat sprite_angle : register(C0); \r\n\r\nfloat4 NormalMap( float2 texCoord : TEXCOORD0 ) : COLOR0\r\n{ \u00a0\r\n\u00a0\u00a0 \u00a0\/\/get the value of the normal at this texturecoord\r\n\u00a0\u00a0\u00a0 \u00a0float3 normalcolor = tex2D(g_samNormalMapColor, texCoord);\r\n\r\n\u00a0\u00a0\u00a0 \u00a0\/\/convert it to +\/- 1.0 range\r\n\u00a0\u00a0\u00a0 \u00a0normalcolor *= 2.0f;\r\n\u00a0\u00a0\u00a0 \u00a0normalcolor -= 1.0f;\r\n\r\n\u00a0\u00a0\u00a0 \u00a0float3 LightDirection;\r\n\u00a0\u00a0\u00a0 \u00a0LightDirection.x = sin(sprite_angle);\r\n\u00a0\u00a0\u00a0 \u00a0LightDirection.y = cos(sprite_angle);\r\n\u00a0\u00a0\u00a0 \u00a0LightDirection.z = 0;\r\n\r\n\u00a0\u00a0\u00a0 \u00a0float dot_prod = dot(LightDirection, normalcolor);\r\n\r\n\u00a0\u00a0\u00a0 \u00a0\/\/apply as a tint to the final pixel\r\n\u00a0 \u00a0\u00a0\u00a0 \u00a0float4 original = tex2D(g_samSrcColor, texCoord); \r\n\u00a0 \u00a0\u00a0\u00a0 \u00a0float4 final = original;\r\n\u00a0 \u00a0\u00a0\u00a0 \u00a0final.r *= dot_prod;\r\n\u00a0 \u00a0\u00a0\u00a0 \u00a0final.b *= dot_prod;\r\n\u00a0 \u00a0\u00a0\u00a0 \u00a0final.g *= dot_prod;\r\n\r\n\u00a0 \u00a0\u00a0\u00a0 \u00a0return final;\r\n}<\/pre>\n<p>As an idiot, I&#8217;m not really sure what I am doing here. What I *think* I&#8217;m doing is this: I am drawing a sprite which has a separate normal map (g_samNormalMapColor) I also pass in the current angle of the sprite. I sample the color of the normal map, and convert it into the required range. I then convert the sprites angle into a light direction vector (probably wrongly) and I then do some magic which kids call &#8216;dot&#8217; which I&#8217;m guessing gives me the brightness of the pixel given the angle and the default light direction. I then multiply the original texture color by this brightness to tint my final rendered sprite. Yay.<\/p>\n<p>it&#8217;s something clever to do with angles and vectors and stuff isn&#8217;t it? explain it to me like I&#8217;m an idiot :D<\/p>\n<p>&nbsp;<\/p>\n<p>And yeah&#8230;I&#8217;m playing about with Gratuitous Space Battles. It&#8217;s a Sunday morning, don&#8217;t read too much into it :D<\/p>\n","protected":false},"excerpt":{"rendered":"<p>EDIT: I&#8217;ve fixed it. It&#8217;s my own dumbassness. I was setting the sprite_angle variable in the shader AFTER the shader had started, and it was presumably never being set, and populated with garbage (or the ship beforehand) it works a charm now :D Right so, despite being good at AI coding and optimisation, i suck<\/p>\n<p class=\"text-right\"><span class=\"screen-reader-text\">Continue Reading&#8230; Normal mapping question (it&#8217;s my day OFF)<\/span><a class=\"btn btn-secondary continue-reading\" href=\"https:\/\/www.positech.co.uk\/cliffsblog\/2013\/08\/11\/normal-mapping-question-its-my-day-off\/\">Continue Reading&#8230;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-2494","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts\/2494","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/comments?post=2494"}],"version-history":[{"count":4,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts\/2494\/revisions"}],"predecessor-version":[{"id":2499,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts\/2494\/revisions\/2499"}],"wp:attachment":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/media?parent=2494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/categories?post=2494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/tags?post=2494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}