<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1788573719903725277</id><updated>2012-02-16T01:05:25.274-08:00</updated><category term='naming conventions'/><category term='fast'/><category term='diffuse lighting'/><category term='oren nayar'/><category term='HLSL'/><category term='introduction'/><category term='van ouwerkerk&apos;s rewrite'/><category term='speeding up'/><category term='first shader'/><title type='text'>Shaders by Jos van Ouwerkerk</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://shaderjvo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://shaderjvo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jos van Ouwerkerk</name><uri>http://www.blogger.com/profile/06888254519257072619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-JL8qlZUf_JA/Tkl0FXCVYSI/AAAAAAAAAAU/Qw_zoHxrHUQ/s220/76818008_6_WFWh.jpeg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1788573719903725277.post-7215556960769158164</id><published>2011-08-31T12:26:00.000-07:00</published><updated>2011-08-31T12:26:18.492-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='van ouwerkerk&apos;s rewrite'/><category scheme='http://www.blogger.com/atom/ns#' term='oren nayar'/><category scheme='http://www.blogger.com/atom/ns#' term='HLSL'/><category scheme='http://www.blogger.com/atom/ns#' term='fast'/><category scheme='http://www.blogger.com/atom/ns#' term='speeding up'/><title type='text'>van Ouwerkerk's rewrite (of the Oren Nayar BRDF)</title><content type='html'>&lt;b&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;M. Oren and S.K. Nayar proposed a diffuse BRDF in &lt;i&gt;Generalization of Lambert's Reflectance Model, Michael Oren, Shree K. Nayar, July 1994, Siggraph, pp. 239-246&lt;/i&gt; that takes the roughness of a surface into account. This BRDF is often cited as too slow for realtime use, because of the sin and tan instructions in the equation. In this post I present a rewritten version of the equation which I'd like to call "&lt;b&gt;van Ouwerkerk's rewrite&lt;/b&gt;". The rewritten equation evaluates significantly faster on modern GPU's, making it more feasible to use the Oren Nayar BRDF in realtime applications.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ipys1TP5Mao/Tl5LebxjRiI/AAAAAAAAAA0/oGNcBN9bxqM/s1600/Backscattering.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="210" src="http://2.bp.blogspot.com/-ipys1TP5Mao/Tl5LebxjRiI/AAAAAAAAAA0/oGNcBN9bxqM/s400/Backscattering.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Figure 1 - backscattering towards light source in V-cavities&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The Oren Nayar BRDF is based on mathematical analysis of light interacting with a surface consisting of V-cavities. In their work they predict that roughness results in more light being reflected back in the direction of the light source, which is illustrated in figure 1. This backscatter effect is contained in the resulting simplified Oren Nayar BRDF listed in equation 1.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-5s-vGpVXoeQ/Tl5Ljv1Y9EI/AAAAAAAAABA/tYXi258iB74/s1600/Equation_01.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="105" src="http://3.bp.blogspot.com/-5s-vGpVXoeQ/Tl5Ljv1Y9EI/AAAAAAAAABA/tYXi258iB74/s400/Equation_01.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 1 - (simplified) Oren Nayar BRDF&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Angle range&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-G8s0d9MWYgE/Tl5LjI65D7I/AAAAAAAAAA8/J955xm2_W-g/s1600/Angle_overview.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="230" src="http://2.bp.blogspot.com/-G8s0d9MWYgE/Tl5LjI65D7I/AAAAAAAAAA8/J955xm2_W-g/s320/Angle_overview.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Figure 2 - graphical overview of angles&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The incoming light direction is described by the angles θ&lt;span style="font-size: x-small;"&gt;i&lt;/span&gt; and φ&lt;span style="font-size: x-small;"&gt;i&lt;/span&gt;, while the reflected light direction is described by the angles θ&lt;span style="font-size: x-small;"&gt;r&lt;/span&gt; and φ&lt;span style="font-size: x-small;"&gt;r&lt;/span&gt; as illustrated in figure 2. The azimuth angles are described by φ&lt;span style="font-size: x-small;"&gt;i&lt;/span&gt; and φ&lt;span style="font-size: x-small;"&gt;r&lt;/span&gt; in a full circle from 0 to 2π on the plane of the surface. The zenith angles described by θ&lt;span style="font-size: x-small;"&gt;i&lt;/span&gt; and θ&lt;span style="font-size: x-small;"&gt;r&lt;/span&gt; are therefore always positive and range from 0 to π. Since light can't illuminate a surface from the back and we can't see a surface from the back, θ&lt;span style="font-size: x-small;"&gt;i&lt;/span&gt; and θ&lt;span style="font-size: x-small;"&gt;r&lt;/span&gt; are constrained to a meaningful range of 0 to π/2 as made explicit in equation 2.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-qOXkanrCOjY/Tl5LkD58uSI/AAAAAAAAABE/p7_ItkC2lSE/s1600/Equation_02.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="93" src="http://4.bp.blogspot.com/-qOXkanrCOjY/Tl5LkD58uSI/AAAAAAAAABE/p7_ItkC2lSE/s200/Equation_02.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 2 - angles constrained to meaningful range&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Trigonometric identities&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Our goal is to remove the sin and tan instructions from the Oren Nayar BRDF. Since a cos can often be replaced by a much faster dot product, we start by transforming the sin and tan instructions into cos instructions using the two trigonometric identities listed in equation 3. Note that the square root would mathematically have both a positive and a negative result. Since the zenith angles are constrained to the 0 to π/2 range, we can assume the positive result.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-wOSHq90oZiI/Tl5LkswpSoI/AAAAAAAAABI/wa9Qg8MNnys/s1600/Equation_03.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="109" src="http://3.bp.blogspot.com/-wOSHq90oZiI/Tl5LkswpSoI/AAAAAAAAABI/wa9Qg8MNnys/s200/Equation_03.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 3 - trigonometric identities&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;This will transform the BRDF into the expanded form listed in equation 4. For easier reading, the part with the original sin and tan instructions is split into a separate part C of the equation.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zVdBR2mvDM4/Tl5Lk99JsdI/AAAAAAAAABM/LRA6OUnpvFE/s1600/Equation_04.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="111" src="http://4.bp.blogspot.com/-zVdBR2mvDM4/Tl5Lk99JsdI/AAAAAAAAABM/LRA6OUnpvFE/s400/Equation_04.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 4 - application of trigonometric identities&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Alpha and beta&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-o4mfFxW-EBc/Tl5LnPne3MI/AAAAAAAAABc/kYcqp6nnDzY/s1600/Ranged_cosine.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="232" src="http://2.bp.blogspot.com/-o4mfFxW-EBc/Tl5LnPne3MI/AAAAAAAAABc/kYcqp6nnDzY/s320/Ranged_cosine.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Figure 3 - cosine from 0 to π/2&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The dot product of two normalized vectors equals the cosine of the angle between them. This identity is very often used in computer graphics. The problem that arises with the Oren Nayar BRDF is that the angles α and β can't be readily expressed as an angle between two vectors. This prevents the use of a dot product instead of the more expensive cos instruction. In order to overcome this, we'll have to remove the min and max instructions inside the cos. If we look at the cosine function we see that it is strictly decreasing in the 0 to π/2 range as illustrated in figure 3. We can use this to move the min and max instructions outwards as listed in equation 5.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-C92hmyx8Taw/Tl5LlV-jpRI/AAAAAAAAABQ/YSL5yl2RXEo/s1600/Equation_05.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="111" src="http://4.bp.blogspot.com/-C92hmyx8Taw/Tl5LlV-jpRI/AAAAAAAAABQ/YSL5yl2RXEo/s400/Equation_05.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 5 - moving min and max outwards&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Minimum and maximum&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Since both the minimum and the maximum of the incoming and reflected zenith angles are processed in the same way, we can apply another simplification as listed in equation 6. If one of the angles is the minimum, the other one is automatically the maximum. This means we can replace the mirrored min and max instructions with the two parameters contained in them. We can also combine the two square roots into one.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Gex5Qe5xqqU/Tl5LlyVH8OI/AAAAAAAAABU/YCNS4dHbUAw/s1600/Equation_06.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="118" src="http://1.bp.blogspot.com/-Gex5Qe5xqqU/Tl5LlyVH8OI/AAAAAAAAABU/YCNS4dHbUAw/s320/Equation_06.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 6 - mirrored min and max&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Vector math&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;At this point we can replace all cosine functions with dot products and transform the equation into the vector math commonly found in realtime shaders. The final result is listed in equation 7.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Tu71CqwusSU/Tl5LmYMsxII/AAAAAAAAABY/n0eqU3zuT44/s1600/Equation_07.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="156" src="http://4.bp.blogspot.com/-Tu71CqwusSU/Tl5LmYMsxII/AAAAAAAAABY/n0eqU3zuT44/s400/Equation_07.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Equation 7 - &lt;b&gt;van Ouwerkerk's rewrite&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Implementation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;The proposed equation is implemented in an HLSL pixel shader as shown in the listing below. The determination of the surface albedo and the amount of incoming light is not included in this listing as it depends on many other factors.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;// Input vectors&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;normal = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(input.normal);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;light = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(input.light);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;view = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(input.view);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;// Roughness, A and B&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float &lt;/span&gt;roughness = input.roughness;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float &lt;/span&gt;roughness2 = roughness * roughness;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float2 &lt;/span&gt;oren_nayar_fraction = roughness2 / (roughness2 + &lt;span style="color: #134f5c;"&gt;float2&lt;/span&gt;(0.33, 0.09));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float2 &lt;/span&gt;oren_nayar = &lt;span style="color: #134f5c;"&gt;float2&lt;/span&gt;(1, 0) + &lt;span style="color: #134f5c;"&gt;float2&lt;/span&gt;(-0.5, 0.45) * oren_nayar_fraction;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;// Theta and phi&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float2 &lt;/span&gt;cos_theta = &lt;span style="color: #134f5c;"&gt;saturate&lt;/span&gt;(&lt;span style="color: #134f5c;"&gt;float2&lt;/span&gt;(&lt;span style="color: #134f5c;"&gt;dot&lt;/span&gt;(normal, light), &lt;span style="color: #134f5c;"&gt;dot&lt;/span&gt;(normal, view)));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float2 &lt;/span&gt;cos_theta2 = cos_theta * cos_theta;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float &lt;/span&gt;sin_theta = &lt;span style="color: #134f5c;"&gt;sqrt&lt;/span&gt;((1-cos_theta2.x) * (1-cos_theta2.y));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;light_plane = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(light - cos_theta.x * normal);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;view_plane = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(view - cos_theta.y * normal);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float &lt;/span&gt;cos_phi = &lt;span style="color: #134f5c;"&gt;saturate&lt;/span&gt;(&lt;span style="color: #134f5c;"&gt;dot&lt;/span&gt;(light_plane, view_plane));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;// Composition&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float &lt;/span&gt;diffuse_oren_nayar = cos_phi * sin_theta / &lt;span style="color: #134f5c;"&gt;max&lt;/span&gt;(cos_theta.x, cos_theta.y);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;span style="color: #134f5c;"&gt;float &lt;/span&gt;diffuse = cos_theta.x * (oren_nayar.x + oren_nayar.y * diffuse_oren_nayar);&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Final words&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I've hereby presented a faster way to evaluate the Oren Nayar BRDF specifically targeted at usage in realtime shaders. This document has been submitted as proposal to the GPU Pro 3 book.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1788573719903725277-7215556960769158164?l=shaderjvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shaderjvo.blogspot.com/feeds/7215556960769158164/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/van-ouwerkerks-rewrite-of-oren-nayar.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/7215556960769158164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/7215556960769158164'/><link rel='alternate' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/van-ouwerkerks-rewrite-of-oren-nayar.html' title='van Ouwerkerk&apos;s rewrite (of the Oren Nayar BRDF)'/><author><name>Jos van Ouwerkerk</name><uri>http://www.blogger.com/profile/06888254519257072619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-JL8qlZUf_JA/Tkl0FXCVYSI/AAAAAAAAAAU/Qw_zoHxrHUQ/s220/76818008_6_WFWh.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-ipys1TP5Mao/Tl5LebxjRiI/AAAAAAAAAA0/oGNcBN9bxqM/s72-c/Backscattering.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1788573719903725277.post-6914268501933755302</id><published>2011-08-18T11:58:00.000-07:00</published><updated>2011-08-18T12:05:22.093-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='HLSL'/><category scheme='http://www.blogger.com/atom/ns#' term='diffuse lighting'/><title type='text'>Introduction to HLSL - Part 3</title><content type='html'>&lt;ul&gt;&lt;li&gt;&lt;a href="http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-2.html"&gt;Part 2&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Diffuse lighting&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;In this part we're going to add some simple diffuse lighting. The new lines compared to the previous part are marked in bold.&lt;br /&gt;&lt;blockquote&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 1: Application inputs&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: #134f5c;"&gt;float4x4 &lt;/span&gt;object_to_world: &lt;span style="color: #134f5c;"&gt;WORLD&lt;/span&gt;;&lt;/b&gt; &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;float4x4 &lt;/span&gt;object_to_clip: &lt;span style="color: #134f5c;"&gt;WORLDVIEWPROJECTION&lt;/span&gt;;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;light_pos: &lt;span style="color: #134f5c;"&gt;LIGHT_POS&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;light_color: &lt;span style="color: #134f5c;"&gt;LIGHT_COLOR&lt;/span&gt;;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: #134f5c;"&gt;float3x3 &lt;/span&gt;object_to_world3x3 = (&lt;span style="color: #134f5c;"&gt;float3x3&lt;/span&gt;)object_to_world;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 2: Structures&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;struct &lt;/span&gt;vs_in {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float4 &lt;/span&gt;pos_object: &lt;span style="color: #134f5c;"&gt;POSITION&lt;/span&gt;;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;normal_object: &lt;span style="color: #134f5c;"&gt;NORMAL&lt;/span&gt;;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;};&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;struct &lt;/span&gt;ps_in {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float4 &lt;/span&gt;pos_clip: &lt;span style="color: #134f5c;"&gt;POSITION&lt;/span&gt;;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;&lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;normal_world: &lt;span style="color: #134f5c;"&gt;TEXCOORD0&lt;/span&gt;;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;light_world: &lt;span style="color: #134f5c;"&gt;TEXCOORD1&lt;/span&gt;; &lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;};&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 3: Vertex Shaders&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ps_in vs_main(vs_in input) {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; ps_in output;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; output.pos_clip = &lt;span style="color: #134f5c;"&gt;mul&lt;/span&gt;(input.pos_object, object_to_clip);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;output.normal_world =&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;mul&lt;/span&gt;(input.normal_object, object_to_world3x3);&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float4 &lt;/span&gt;pos_world = &lt;span style="color: #134f5c;"&gt;mul&lt;/span&gt;(input.pos_object, object_to_world);&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; output.light_world = light_pos - pos_world.xyz;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;return &lt;/span&gt;output;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 4: Pixel Shaders&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;float4 &lt;/span&gt;ps_main(ps_in input) : &lt;span style="color: #134f5c;"&gt;COLOR &lt;/span&gt;{&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;result = light_world;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;normal_world = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(input.normal_world); &lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float3 &lt;/span&gt;light_world = &lt;span style="color: #134f5c;"&gt;normalize&lt;/span&gt;(input.light_world);&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; result *= &lt;span style="color: #134f5c;"&gt;saturate&lt;/span&gt;(&lt;span style="color: #134f5c;"&gt;dot&lt;/span&gt;(normal_world, light_world));&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;return float4&lt;/span&gt;(result, 1.f);&lt;/b&gt; &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 5: Techniques&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;technique &lt;/span&gt;main {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;pass &lt;/span&gt;p0 {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VertexShader = &lt;span style="color: #134f5c;"&gt;compile &lt;/span&gt;vs_3_0 vs_main();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PixelShader  = &lt;span style="color: #134f5c;"&gt;compile &lt;/span&gt;ps_3_0 ps_main();&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;/blockquote&gt;In this example we add the normals (in object space) as inputs to the vertex shader. The vertex shader turns them into world space. Note that the full 4-by-4 transformation matrix includes translation, rotation and scale. For the transformation of normals we are only really interested in the rotation, so we use a reduced 3-by-3 matrix for the transformation. The vertex shader also calculates the vector from the surface of the object to the light source (in world space) and passes this information on to the pixel shader.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1788573719903725277-6914268501933755302?l=shaderjvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shaderjvo.blogspot.com/feeds/6914268501933755302/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-3.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/6914268501933755302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/6914268501933755302'/><link rel='alternate' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-3.html' title='Introduction to HLSL - Part 3'/><author><name>Jos van Ouwerkerk</name><uri>http://www.blogger.com/profile/06888254519257072619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-JL8qlZUf_JA/Tkl0FXCVYSI/AAAAAAAAAAU/Qw_zoHxrHUQ/s220/76818008_6_WFWh.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1788573719903725277.post-7509404686935890857</id><published>2011-08-16T10:59:00.000-07:00</published><updated>2011-08-18T11:59:02.855-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='first shader'/><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='HLSL'/><title type='text'>Introduction to HLSL - Part 2</title><content type='html'>&lt;ul&gt;&lt;li&gt;&lt;a href="http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-1.html"&gt;Part 1&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Our first shader&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;In this part we take the two critical lines of the last part (marked bold) and turn it into a complete HLSL shader. In this introduction I target Shader Model 3.0 which is compatible with DirectX 9.0c.&lt;br /&gt;&lt;blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #38761d;"&gt;// These are comments&lt;br /&gt;// 1: Application inputs&lt;/span&gt;&lt;/div&gt;&lt;div style="color: black; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: #134f5c;"&gt;float4x4&lt;/span&gt; object_to_clip: &lt;span style="color: #134f5c;"&gt;WORLDVIEWPROJECTION&lt;/span&gt;;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #38761d;"&gt;// 2: Structures&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;struct &lt;/span&gt;vs_in {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float4&lt;/span&gt; pos_object: &lt;span style="color: #134f5c;"&gt;POSITION&lt;/span&gt;;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;};&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;struct &lt;/span&gt;ps_in {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;float4 &lt;/span&gt;pos_clip: &lt;span style="color: #134f5c;"&gt;POSITION&lt;/span&gt;;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;};&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 3: Vertex Shaders&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ps_in vs_main(vs_in input) {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; ps_in output;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;output.pos_clip = &lt;span style="color: #134f5c;"&gt;mul&lt;/span&gt;(input.pos_object, object_to_clip);&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;return &lt;/span&gt;output;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 4: Pixel Shaders&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #134f5c;"&gt;float4 &lt;/span&gt;ps_main(ps_in input) : &lt;span style="color: #134f5c;"&gt;COLOR &lt;/span&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;return float4&lt;/span&gt;(1.f, 1.f, 1.f, 1.f); &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #38761d; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// 5: Techniques&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #134f5c;"&gt;technique &lt;/span&gt;main {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #134f5c;"&gt;pass &lt;/span&gt;p0 {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VertexShader = &lt;span style="color: #134f5c;"&gt;compile &lt;/span&gt;vs_3_0 vs_main();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PixelShader&amp;nbsp; = &lt;span style="color: #134f5c;"&gt;compile &lt;/span&gt;ps_3_0 ps_main();&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;The shader code consists of 5 parts. The application inputs, the structures used (for input and output), the vertex shader(s), the pixel shader(s) and the technique(s). The vertex shader is executed for each vertex in the model and does the minimum it has to do, transform the model into clip space. The pixel shader is executed for each pixel and simply returns a fully opaque white pixel in this case. In the next part we'll add some diffuse lighting.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-3.html"&gt;Part3&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1788573719903725277-7509404686935890857?l=shaderjvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shaderjvo.blogspot.com/feeds/7509404686935890857/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-2.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/7509404686935890857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/7509404686935890857'/><link rel='alternate' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-2.html' title='Introduction to HLSL - Part 2'/><author><name>Jos van Ouwerkerk</name><uri>http://www.blogger.com/profile/06888254519257072619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-JL8qlZUf_JA/Tkl0FXCVYSI/AAAAAAAAAAU/Qw_zoHxrHUQ/s220/76818008_6_WFWh.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1788573719903725277.post-1252449923618511815</id><published>2011-08-15T12:02:00.000-07:00</published><updated>2011-08-23T12:27:14.246-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><category scheme='http://www.blogger.com/atom/ns#' term='HLSL'/><category scheme='http://www.blogger.com/atom/ns#' term='naming conventions'/><title type='text'>Introduction to HLSL - Part 1</title><content type='html'>&lt;span style="font-size: large;"&gt;&lt;b&gt;Naming conventions&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/TmbFDTL1D84/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/TmbFDTL1D84?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/TmbFDTL1D84?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;In programming it's good practice to name your variables logically. Often I see this practice not executed in shader writing. That's why&lt;/span&gt; I'm starting with some variable naming conventions I like to adhere to. One of the most basic things a shader has to do is to transform the rendered object from object space into clip space. I'll come back to mathematics behind this, but for now it's enough to know that this transformation can be done by a single matrix multiplication. The matrix in question has the input semantic &lt;i&gt;WORLDVIEWPROJECTION&lt;/i&gt;. The code for the transformation is commonly written as:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;float4x4&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; wvp:&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt; WORLDVIEWPROJECTION;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;out.&lt;b style="color: #990000;"&gt;pos&lt;/b&gt; = mul(in.&lt;b style="color: #990000;"&gt;pos&lt;/b&gt;, wvp);&lt;/span&gt;&lt;/blockquote&gt;In this code we find two distinct variables that are both named &lt;i&gt;pos&lt;/i&gt;. The one in the &lt;i&gt;in&lt;/i&gt; structure is the position in object space, while the one in the &lt;i&gt;out&lt;/i&gt; structure is the position in clip space. &lt;b&gt;The first naming convention I adhere to is to add the space a vector is in as a suffix.&lt;/b&gt; So we update the transformation above into this one:&lt;br /&gt;&lt;blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;float4x4 &lt;b style="color: #990000;"&gt;wvp&lt;/b&gt;: WORLDVIEWPROJECTION;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: #990000;"&gt;out&lt;/b&gt;.&lt;b style="color: #38761d;"&gt;pos_clip&lt;/b&gt; = mul(&lt;b style="color: #990000;"&gt;in&lt;/b&gt;.&lt;b&gt;&lt;span style="color: #38761d;"&gt;pos_object&lt;/span&gt;&lt;/b&gt;, &lt;b style="color: #990000;"&gt;wvp&lt;/b&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;Next lets look at the variable &lt;i&gt;wvp&lt;/i&gt;. These three letters are a logical shorthand of &lt;u&gt;W&lt;/u&gt;orld&lt;u&gt;V&lt;/u&gt;iew&lt;u&gt;P&lt;/u&gt;rojection, but what is the function of this variable in our code? &lt;b&gt;We will almost always use this matrix to convert a vector from object space into clip space. So we'll call the variable &lt;i&gt;object_to_clip&lt;/i&gt; instead.&lt;/b&gt; We'll also lengthen &lt;i&gt;in&lt;/i&gt; and &lt;i&gt;out&lt;/i&gt; a little bit to &lt;i&gt;input&lt;/i&gt; and &lt;i&gt;output&lt;/i&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;float4x4 &lt;b style="color: #38761d;"&gt;object_to_clip&lt;/b&gt;: WORLDVIEWPROJECTION;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: #38761d;"&gt;output&lt;/b&gt;.&lt;b style="color: #38761d;"&gt;pos_clip&lt;/b&gt; = mul(&lt;b&gt;&lt;span style="color: #38761d;"&gt;input&lt;/span&gt;&lt;/b&gt;.&lt;b style="color: #38761d;"&gt;pos_object&lt;/b&gt;, &lt;b style="color: #38761d;"&gt;object_to_clip&lt;/b&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;This concludes the first part of the introduction to HLSL. In the next part we'll take this must have piece of code and extend it into our first full HLSL shader.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-2.html"&gt;Part 2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1788573719903725277-1252449923618511815?l=shaderjvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shaderjvo.blogspot.com/feeds/1252449923618511815/comments/default' title='Reacties plaatsen'/><link rel='replies' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-1.html#comment-form' title='0 reacties'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/1252449923618511815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1788573719903725277/posts/default/1252449923618511815'/><link rel='alternate' type='text/html' href='http://shaderjvo.blogspot.com/2011/08/introduction-to-hlsl-part-1.html' title='Introduction to HLSL - Part 1'/><author><name>Jos van Ouwerkerk</name><uri>http://www.blogger.com/profile/06888254519257072619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-JL8qlZUf_JA/Tkl0FXCVYSI/AAAAAAAAAAU/Qw_zoHxrHUQ/s220/76818008_6_WFWh.jpeg'/></author><thr:total>0</thr:total></entry></feed>
