<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Yuriy O&#039;Donnell&#039;s blog &#187; Graphics</title>
	<atom:link href="http://kayru.org/entry/category/graphics/feed" rel="self" type="application/rss+xml" />
	<link>http://kayru.org</link>
	<description>computer graphics, gamedev, etc.</description>
	<lastBuildDate>Sun, 27 Jun 2010 01:09:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Register assignment in HLSL</title>
		<link>http://kayru.org/entry/89</link>
		<comments>http://kayru.org/entry/89#comments</comments>
		<pubDate>Sun, 27 Jun 2010 01:08:32 +0000</pubDate>
		<dc:creator>kayru</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Graphics]]></category>

		<guid isPermaLink="false">http://kayru.org/?p=89</guid>
		<description><![CDATA[When you are manually assigning shader constants to registers (using a &#8216;register&#8217; keyword), those registers are also taken out of the automatic assignment pool. This means that constants that don&#8217;t have explicit registers will never overlap with ones that do even if latter are not used in the shader. And so code like this: float4 [...]]]></description>
			<content:encoded><![CDATA[<p>When you are manually assigning shader constants to registers (using a &#8216;register&#8217; keyword), those registers are also taken out of the automatic assignment pool.<br />
This means that constants that don&#8217;t have explicit registers will never overlap with ones that do even if latter are not used in the shader.<br />
And so code like this:<br />
<code>float4 c0 : register(c0);<br />
float4 c1 : register(c2);<br />
float4 c2;<br />
float4 main():POSITION<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;return c2;<br />
}</code></p>
<p>Will compile into this:<br />
<code>vs_2_0<br />
mov oPos, <b>c1</b></code></p>
<p>This is a pretty small thing, but still quite convenient and useful to know.</p>
]]></content:encoded>
			<wfw:commentRss>http://kayru.org/entry/89/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spherical Harmonics in games</title>
		<link>http://kayru.org/entry/75</link>
		<comments>http://kayru.org/entry/75#comments</comments>
		<pubDate>Sat, 19 Jun 2010 19:13:50 +0000</pubDate>
		<dc:creator>kayru</dc:creator>
				<category><![CDATA[Graphics]]></category>

		<guid isPermaLink="false">http://kayru.org/?p=75</guid>
		<description><![CDATA[Here is everything you really need to know about spherical harmonics to use them in games: 0. Spherical Harmonics are not scary at all :) 1. An Efficient Representation for Irradiance Environment Maps 2. Spherical Harmonics in Actual Games 3. Spherical Harmonic Lighting: The Gritty Details 4. DirectX SDK samples contain all the C++ and [...]]]></description>
			<content:encoded><![CDATA[<p>Here is everything you really need to know about spherical harmonics to use them in games:</p>
<p>0. Spherical Harmonics are not scary at all :)<br />
1. <a href="http://graphics.stanford.edu/papers/envmap/envmap.pdf">An Efficient Representation for Irradiance Environment Maps</a><br />
2. <a href="http://www.henjeon.com/pds/dev/doc/Spherical%20Harmonics%20GDCE%20PPT97.ppt">Spherical Harmonics in Actual Games</a><br />
3. <a href="http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf">Spherical Harmonic Lighting: The Gritty Details</a><br />
4. DirectX SDK samples contain all the C++ and HLSL code that you might need to get started.</p>
<p>C++ code to calculate shader constants for evaluation on GPU:<br />
<code>IrradianceVolume\PRTMesh.cpp, CPRTMesh::ComputeSHIrradEnvMapConstants()</code></p>
<p>HLSL code to evaluate SH for a given normal:<br />
<code>IrradianceVolume\SHIrradianceEnvMap.fx</code></p>
<p>Also, DirectX SDK comes with a bunch of functions to get you going quickly. For example there is D3DXSHProjectCubeMap(), which generates spherical harmonic coefficients from a given cubemap.</p>
<p>PS: There one thing to keep in mind, though: SH are not the only option for storing lighting information. One great alternative is <a href="http://www.valvesoftware.com/publications/2006/SIGGRAPH06_Course_ShadingInValvesSourceEngine_Slides.pdf">Valve&#8217;s Ambient Cube (page 28)</a>, which gives quality somewhere between 2-band and 3-band SH.</p>
]]></content:encoded>
			<wfw:commentRss>http://kayru.org/entry/75/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Defferred dynamic lighting using light volumes</title>
		<link>http://kayru.org/entry/11</link>
		<comments>http://kayru.org/entry/11#comments</comments>
		<pubDate>Sat, 14 Mar 2009 20:55:11 +0000</pubDate>
		<dc:creator>kayru</dc:creator>
				<category><![CDATA[Graphics]]></category>

		<guid isPermaLink="false">http://kayru.org/?p=11</guid>
		<description><![CDATA[Background When it comes to dynamic lighting, there are two common approaches: - loop inside pixel shader, calculating contribution of each light; - render the same geometry multiple times (for each light) using additive blend; Normally, number of lights that affect a mesh is limited to something like 4 or 8 to save shader instructions [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Background</strong></p>
<p>When it comes to dynamic lighting, there are two common approaches:<br />
- loop inside pixel shader, calculating contribution of each light;<br />
- render the same geometry multiple times (for each light) using additive blend;</p>
<p>Normally, number of lights that affect a mesh is limited to something like 4 or 8 to save shader instructions or render passes.<br />
Therefore, for each mesh one must calculate which lights can affect it. This can be tricky when dealing with large meshes, like terrain.<br />
When large number of lights affect the same mesh, there can also be a problem with light flickering (when one light is replaced by another).</p>
<p>Deferred shading provides a nice and simple alternative (admittedly at a cost of different kind of problems, described later).<br />
It works by performing lighting after all geometry is rendered. Hence the name.<br />
All lighting function inputs are rendered into several buffers (in a single pass, using multiple render targets) which are then sampled by the light shader.</p>
<p><strong>Implementation details</strong></p>
<p>In the demo, I&#8217;m using four fp16 textures with this layout:</p>
<p>RT0: RGB &#8211; unlit diffuse colour, Alpha &#8211; specular level<br />
RT1: RGB &#8211; light accumulation, Alpha &#8211; nothing<br />
RT2: RGB &#8211; world-space normal, Alpha &#8211; nothing<br />
RT3: RGB &#8211; world-space, not normalized view vector, Alpha &#8211; nothing</p>
<p>RT1  starts off with light contribution from main ambient and directional sources (sun).</p>
<p>Once we rendered our scene into MRTs, we can start applying dynamic lights.</p>
<p>To cull all unaffected pixels, lights are rendered as a convex 3d volumes. Only point lights are shown in the demo, they are rendered as low-poly spheres.  Spot lights are also possible, using cones.</p>
<p>It is also possible for each light to cast a shadow. I will explore this topic in the future articles.</p>
<p><strong>Stencil and Z culling</strong></p>
<p>Each light volume is rendered it two passes:</p>
<p>Pass 1:<br />
- Front faces only;<br />
- Colour write disabled;<br />
- No Z-write;<br />
- Z function = Less/Equal;<br />
- Z-Fail writes non-zero value to stencil buffer (increment-saturate);<br />
- Stencil pass &amp; fail don&#8217;t modify stencil buffer;</p>
<p>This pass creates a stencil mask for the areas of the light volume that are not occluded by scene geometry.</p>
<p>Pass 2:<br />
- Back-faces only;<br />
- Colour write enabled;<br />
- No Z-write;<br />
- Z function = Greater/Equal;<br />
- Stencil function = Equal (stencil ref = zero);<br />
- Always writes zeo to stencil;</p>
<p>This pass is where lighting actually happens. Every pixel that passes Z and Stencil tests is then added to light accumulation buffer (RT1). Standard Phong function is used in the demo.</p>
<p>Diagram below shows effects of Z and Stencil tests:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-13" title="Light Z and Stencil culling" src="http://kayru.org/wp-content/uploads/2009/03/lighting_diagram1.png" alt="Light Z and Stencil culling" width="512" height="256" /><em>Blue &#8211; pixels which passes Z test in Pass 1 and have left the stencil buffer intact.<br />
Red &#8211; pixels which passed Z test in Pass 2.<br />
Green &#8211; pixels which passed Stencil test in Pass 2.</em></p>
<p>- Light 1 is culled by Z test in Pass 2.<br />
- Light 2 will fail Z test in Pass 1, write to Stencil buffer and then will fail Stencil test in Pass 2.<br />
- Light 3 will partially pass both tests  and will go into the pixel shader.</p>
<p>After all lights have been rendered in this way, RT1 contains fully lit scene. It can now be used in post-process effects (like bloom).</p>
<p>That&#8217;s it.</p>
<p><strong>Downsides</strong></p>
<p>- Transparent geometry can not be lit in this way. All alpha-blended objects must be rendered into RT1 after deferred dynamic lighting pass, before post-processing. Standard dynamic lighting must be applied to it (loop in the shader and/or multipass).<br />
- No hardware antialiasing.<br />
- High video memory requirements &#8211; 4x 64 bits per pixel (fp16) textures at high resolutions is very expensive.<br />
- High bandwidth requirements &#8211; a product of the previous point. Each pixel writes 4x data. Each light also samples from 3 textures.<br />
This is especially noticeable when camera is close to a surface with high number(say, 50+) of overlapping lights.<br />
- Requires  fp16 blending support.</p>
<p>Some of those problems are possible to solve at some quality cost. I will come back this in the future articles.</p>
<p><strong>Demo &#8211; 1024 point lights</strong></p>
<p style="text-align: center;"><a href="http://kayru.org/wp-content/uploads/2009/03/light_demo_screenshot.jpg"><img class="aligncenter size-medium wp-image-24" title="Light Demo Screenshot" src="http://kayru.org/wp-content/uploads/2009/03/light_demo_screenshot-300x217.jpg" alt="Light Demo Screenshot" width="300" height="217" /></a></p>
<p style="text-align: center;"><a href="http://kayru.org/wp-content/uploads/2009/03/light_demo.zip">[Download]</a></p>
<p>Demo controls:<br />
WASD &#8211; up/down/left/right<br />
EQ &#8211; forward/back<br />
ZX &#8211; rotate<br />
Arrows/Left mouse button &#8211; look around<br />
Space &#8211; animate lights</p>
<p>No source code, but demo is NVPerfHud-friendly.</p>
]]></content:encoded>
			<wfw:commentRss>http://kayru.org/entry/11/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
