| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964 |
- <html xmlns:MSHelp="http://msdn.microsoft.com/mshelp" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xanx="http://schemas.microsoft.com/developer/xanx/2005"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="save" content="history" /><title>Shader Series 1: VertexLighting Sample</title>
- <style><!--
- /***********************************************************
- * SCRIPT-SUPPORTING STYLES
- ***********************************************************/
- /* Defines the userData cache persistence mechanism. */
- .userDataStyle
- {
- behavior: url(#default#userData);
- }
- /* Used to save the scroll bar position when navigating away from a page. */
- div.saveHistory
- {
- behavior: url(#default#saveHistory);
- }
- /* Formats the expand/collapse images for all collapsible regions. */
- img.toggle
- {
- border: 0;
- margin-right: 5;
- }
- /* Formats the Language filter drop-down image. */
- img#languageFilterImage
- {
- border: 0;
- margin-left: 0;
- vertical-align: middle;
- }
- /* Formats the Members Options filter drop-down image. */
- img#membersOptionsFilterImage
- {
- border: 0;
- margin-left: 0;
- vertical-align: middle;
- }
- /* Formats the Collapse All/Expand All images. */
- img#toggleAllImage
- {
- margin-left: 0;
- vertical-align: middle;
- }
- /* Supports XLinks */
- MSHelp\:link
- {
- text-decoration: underline;
- color: #0000ff;
- hoverColor: #3366ff;
- filterString: ;
- }
- body
- {
- background: #FFFFFF;
- color: #000000;
- font-family: Verdana;
- font-size: medium;
- font-style: normal;
- font-weight: normal;
- margin-top: 0;
- margin-bottom: 0;
- margin-left: 0;
- margin-right: 0;
- width: 100%;
- /*font-size: 110%;*/
- }
- div.section
- {
- margin-left: 15px;
- }
- div.hxnx5
- {
- margin-left: 1.5em;
- }
- /* Font for all headings */
- h1, h2, h3, h4, h5, h6
- {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- margin-top: 18;
- margin-bottom: 8;
- font-weight: bold;
- }
- h1
- {
- font-size: 130%;
- color: #003399;
- }
- div#scrollyes h1 /* Changes font size for full-scrolling topic */
- {
- font-size: 150%;
- }
- h2
- {
- font-size: 122%;
- }
- h3
- {
- font-size: 115%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h4
- {
- font-size: 115%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h5
- {
- font-size: 100%;
- margin-top: 9;
- margin-bottom: 4;
- }
- h6
- {
- font-size: 100%;
- margin-top: 9;
- margin-bottom: 4;
- }
- ul p, ol p, dl p
- {
- margin-left: 0em;
- }
- p
- {
- margin-top: .6em;
- margin-bottom: .6em;
- }
-
- td p
- {
- margin-top: 0.0em;
- margin-bottom: 0.6em;
- }
- dd p
- {
- margin-top: 0.0em;
- margin-bottom: 0.6em;
- }
- .image
- {
- text-align: center;
- }
- dl
- {
- margin-top: 0em;
- margin-bottom: 1.3em;
- }
- dd
- {
- margin-bottom: 0em;
- margin-left: 1.5em;
- }
- dl.glossary dd
- {
- margin-bottom: 0em;
- margin-left: 1.5em;
- }
- dt
- {
- margin-top: .6em;
- margin-bottom: 1;
- }
- ul, ol
- {
- margin-top: 0.6em;
- margin-bottom: 0.6em;
- }
-
- ol
- {
- margin-left: 2.5em;
- }
-
- ul
- {
- list-style-type: disc;
- margin-left: 1.9em;
- }
- li
- {
- margin-bottom: 0.4em;
- }
- ul ol, ol ol
- {
- list-style-type: lower-alpha;
- }
- pre
- {
- margin-top: .6em;
- margin-bottom: .6em;
- font: 105% Lucida, mono;
- color: #000066;
- }
- code
- {
- font-family: Monospace, Courier New, Courier;
- font-size: 105%;
- color: #000066;
- }
- table.userdata td
- {
- background: #ffffff;
- background-color: #F5F5F5;
- border-color: #ffffff;
- border: none;
- }
- table.clsWarning
- {
- background: #ffffff;
- padding: 0px;
- margin: 0px;
- border: none;
- }
- table.clsWarning td
- {
- padding: 0px;
- margin: 0px;
- background: #ffffff;
- vertical-align: middle;
- font-size: 70%;
- }
- div#mainSection table
- {
- width: 95%;
- background: #ffffff;
- margin-top: 5px;
- margin-bottom: 5px;
- }
- div#mainSection table th
- {
- padding: 5px 6px;
- background: #EFEFF7;
- text-align: left;
- font-size: 70%;
- vertical-align: bottom;
- border-bottom: 1px solid #C8CDDE;
- }
- div#mainSection table td
- {
- padding: 5px 5px;
- background: #F7F7FF;
- vertical-align: top;
- font-size: 70%;
- border-bottom: 1px solid #D5D5D3;
- }
- div#syntaxCodeBlocks table th
- {
- padding: 1px 6px;
- color: #000066;
- }
- div#syntaxCodeBlocks table td
- {
- padding: 1px 5px;
- }
- /* Applies to the running header text in the first row of the upper table in the
- non-scrolling header region. */
- span#runningHeaderText
- {
- color: #003399;
- font-size: 90%;
- padding-left: 13;
- }
- /* Applies to the topic title in the second row of the upper table in the
- non-scrolling header region. */
- span#nsrTitle
- {
- color: #003399;
- font-size: 120%;
- font-weight: 600;
- padding-left: 13;
- }
- /* Applies to everything below the non-scrolling header region. */
- div#mainSection
- {
- font-size: 70%;
- width: 100%;
- }
- /* Applies to everything below the non-scrolling header region, minus the footer. */
- div#mainBody
- {
- font-size: 90%;
- margin-left: 15;
- margin-top: 10;
- padding-bottom: 20;
- }
- /* Adds right padding for all blocks in mainBody */
- div#mainBody p, div#mainBody ol, div#mainBody ul, div#mainBody dl
- {
- padding-right: 5;
- }
- div#mainBody div.alert, div#mainBody div.code, div#mainBody div.tableSection
- {
- width:98.9%;
- }
- div.alert p, div.code p
- {
- margin-top:5;
- margin-bottom:8;
- }
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- div#mainSection div.alert table
- {
- border: 0;
- }
- div#mainSection div.alert table th
- {
- padding-top: 0;
- padding-bottom: 0;
- padding-left: 5;
- padding-right: 5;
- }
- div#mainSection div.alert table td
- {
- padding-left: 5;
- padding-right: 5;
- }
- img.note
- {
- border: 0;
- margin-left: 0;
- margin-right: 3;
- }
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - End Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Non-scrolling Header Region Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
- /* Applies to the entire non-scrolling header region. */
- div#header
- {
- background-color: #D4DFFF;
- padding-top: 0;
- padding-bottom: 0;
- padding-left: 0;
- padding-right: 0;
- width: 100%;
- }
- /* Applies to both tables in the non-scrolling header region. */
- div#header table
- {
- margin-top: 0;
- margin-bottom: 0;
- border-bottom-color: #C8CDDE;
- border-bottom-style: solid;
- border-bottom-width: 1;
- background: #D4DFFF;
- width: 100%;
- }
- /* Applies to cells in both tables in the non-scrolling header region. */
- div#header table td
- {
- color: #0000FF;
- font-size: 70%;
- padding-right: 20;
- padding-top: 1;
- padding-bottom: 1;
- border: none;
- background: #D4DFFF;
- }
- /* Applies to the last row in the upper table of the non-scrolling header region. Text
- in this row includes See Also, Constructors, Methods, and Properties. */
- div#header table tr#headerTableRow3 td
- {
- padding-bottom: 2;
- padding-top: 5;
- padding-left: 15;
- }
- /* Applies to the lower table in the non-scrolling header region. Text in this table
- includes Collapse All/Expand All, Language Filter, and Members Options. */
- div#header table#bottomTable
- {
- border-top-color: #FFFFFF;
- border-top-style: solid;
- border-top-width: 1;
- text-align: left;
- padding-left: 15;
- }
- blockquote
- {
- margin-left: 3.8em;
- margin-right: 3.8em;
- margin-top: .6em;
- margin-bottom: .6em;
- }
- sup
- {
- text-decoration: none;
- font-size: smaller;
- }
- a:link
- {
- color: #0000FF;
- /* font-weight: bold */
- }
-
- a:visited
- {
- color: #0000AA;
- /* font-weight: bold */
- }
-
- a:hover
- {
- color: #3366FF;
- /* font-weight: bold */
- }
-
- .label
- {
- font-weight: bold;
- margin-top: 1em;
- margin-left: -26px;
- }
-
- .tl
- {
- margin-bottom: .75em;
- }
-
- .atl
- {
- padding-left: 1.5em;
- padding-bottom: .75em;
- }
-
- .cfe
- {
- font-weight: bold;
- }
-
- .mini
- {
- font-size: smaller;
- }
-
- .dt
- {
- margin-bottom: -.6em;
- }
-
- .indent
- {
- margin-left: 1.9em;
- margin-right: 1.9em;
- }
- .product
- {
- text-align: right;
- color: #333333;
- font-size: smaller;
- font-style: italic;
- }
- .buttonbarshade
- {
- position: relative;
- margin: 0;
- left: 0px;
- top: 2;
- width: 50%;
- height: 40px;
- }
- .buttonbartable
- {
- position: absolute;
- margin: 0;
- padding:0;
- border:0;
- left:0px;
- top: 2;
- width: 100%;
- height: 40px;
- }
- /* background color, font for header */
- table.buttonbartable td, table.buttonbarshade td
- {
- background: #ffffff; /*#5177B8; #80C615;*/
- border-left: 0px solid #80C615;
- margin: 0;
- padding: 0px 0px 0px 0px;
- font-family: Impact, sans-serif;
- font-size: 14pt;
- }
- table.buttonbartable td.button1
- {
- background: #5177B8; /*#80C615;*/;
- padding: 0;
- font-weight: bold;
- text-align: center;
- cursor: hand;
- }
- table.buttonbartable td.button2
- {
- background: #5177B8; /*#80C615;*/;
- font-weight: bold;
- text-align: center;
- }
- table.buttonbartable td.button3
- {
- background: #5177B8; /*#80C615;*/;
- font-weight: bold;
- text-align: center;
- }
- table.buttonbartable td.runninghead
- {
- padding-left: 0px;
- font-style: italic;
- text-align: left;
- }
- .version
- {
- text-align: left;
- color: #000000;
- margin-top: 3em;
- margin-left: -26px;
- font-size: smaller;
- font-style: italic;
- }
- .lang, .ilang
- {
- color: #0000ff;
- font: normal 7pt Arial, Helvetica, sans-serif;
- }
- div.langMenu
- {
- position: absolute;
- z-index: 1;
- width: 96pt;
- padding: 8pt;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- div.langMenu ul
- {
- padding-left: 2em;
- margin-left: 0;
- }
- div.filtered
- {
- margin: 4pt 0 8pt -26px;
- padding: 4px 4px 8px 26px;
- width: 100%;
- border: 2px solid #aaaacc;
- background: #ffffff;
- }
- div.filtered2
- {
- margin: 4pt 0 8pt -26px;
- padding: 4px 4px 8px 26px;
- width: 100%;
- border: none;
- background: #ffffff;
- }
- div.filtered h1, div.filtered h2, div.filtered h3, div.filtered h4
- {
- margin-left: -22px;
- }
- div.filtered span.lang
- {
- position: relative;
- left: -22px;
- }
- div.reftip
- {
- position: absolute;
- z-index: 1;
- padding: 8pt;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- a.synParam
- {
- color: #0000FF;
- /*color: #3F7800;*/
- /*color: #8DC54F;*/
- text-decoration: none;
- font-weight: normal;
- }
- a.synParam:hover
- {
- text-decoration: underline;
- font-weight: normal;
- }
- div.sapop
- {
- position: absolute;
- z-index: 1;
- left: 26px;
- width: 100%;
- padding: 10px 10px 10px 36px;
- visibility: hidden;
- border: 1px solid #000000;
- background: #ffffd0;
- }
- div.footer
- {
- width: 100%;
- border: none;
- background: #ffffff;
- margin-top: 18pt;
- padding-bottom: 12pt;
- color: #0000FF;
- /*color: #228B22; */
- text-align: center;
- font-size: 76%;
- }
- div.preliminary
- {
- margin-top: 8pt;
- padding-bottom: 12pt;
- color: #A0A0A0;
- }
- /* A procedure section. eg. 'To create a file', 'To add a value' */
- div.proc
- {
- margin-left: 0.5em;
- }
-
- /* The title of a 'procedure' section. */
- div.proc h3
- {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-weight: bold;
- font-size: 115%;
- margin-top: 1em;
- margin-bottom: 0.4em;
- margin-left: -0.5em;
- color: #003399;
- }
- div.proc ul
- {
- margin-left: 1.5em;
- }
- div.proc ol
- {
- margin-left: 2.0em;
- }
-
- .note
- {
- margin-left: 14pt;
- margin-right: 12pt;
- }
- .indent1
- {
- margin-left: 12pt;
- }
- .indent2
- {
- margin-left: 24pt;
- }
- .indent3
- {
- margin-left: 36pt;
- }
- p.proch
- {
- padding-left: 16px;
- }
- p.proch img
- {
- position: relative;
- vertical-align: top;
- left: -18px;
- margin-right: -14px;
- margin-bottom: -18px;
- }
-
- div.clsPlatSpec
- {
- background-color:#FFF8DC;
- border-style:solid;
- border-width:1pt 0pt 0pt 1pt;
- border-color:#ffE4C4;
- margin-top:0.6em;
- width:100%;
- }
- /* Applies to the language labels in the Language Filter drop-down list. */
- .languageFilter
- {
- color: #0000FF;
- cursor:hand;
- text-decoration:underline;
- padding-bottom:4;
- }
- /* Dropdown areas */
- #languageSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 70%;
- }
- #membersOptionsSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 70%;
- }
- --></style>
- <xml>
- <MSHelp:TOCTitle Title="Shader Series 1: VertexLighting Sample" />
- <MSHelp:RLTitle Title="Shader Series 1: VertexLighting Sample" />
- <MSHelp:Keyword Index="A" Term="O:Microsoft.Xna.VertexLighting" />
- <MSHelp:Keyword Index="A" Term="6d91bdce-ab7c-8b2e-3dba-22db4c9a008e" />
- <MSHelp:Keyword Index="K" Term="Shader Series 1: VertexLighting Sample" />
- <MSHelp:Attr Name="AssetID" Value="6d91bdce-ab7c-8b2e-3dba-22db4c9a008e" />
- <MSHelp:Attr Name="Locale" Value="en-us" />
- <MSHelp:Attr Name="CommunityContent" Value="1" />
- <MSHelp:Attr Name="TopicType" Value="kbOrient" />
- </xml>
- </head><body><div id="mainSection"><div id="mainBody">
- <h1>Shader Series 1: VertexLighting Sample</h1>
- This sample shows one of the most basic uses of shader effects—vertex lighting.
- <a id="ID2EN" name="ID2EN"> </a><h1 class="heading">Sample Overview</h1><div id="ID2EN" class="hxnx1">
-
- <p>This sample explores the diffuse and ambient lighting models and combines them into a simple first-step shader. Additionally, basic XNA Framework <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effect.aspx">Effect</a> code is explored to show how the C# source code interacts with the effect files.</p>
- <a id="ID2EX" name="ID2EX"> </a><h2 class="subHeading">Sample Controls</h2><div id="ID2EX" class="hxnx2">
-
- <p>This sample uses the following keyboard and gamepad controls.</p>
- <table>
- <tr>
- <th>Action</th>
- <th>Keyboard control</th>
- <th>Gamepad control</th>
- </tr>
- <tr>
- <td>Rotate the camera</td>
- <td>W, A, S, and D</td>
- <td>Right analog D-pad</td>
- </tr>
- <tr>
- <td>Rotate the mesh</td>
- <td>UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW</td>
- <td>Left analog D-pad</td>
- </tr>
- <tr>
- <td>Zoom in</td>
- <td>Z</td>
- <td><b>A</b></td>
- </tr>
- <tr>
- <td>Zoom out</td>
- <td>X</td>
- <td><b>B</b></td>
- </tr>
- <tr>
- <td>Toggle between flat shading and vertex lighting effects</td>
- <td>SPACEBAR</td>
- <td><b>Y</b></td>
- </tr>
- <tr>
- <td>Display a different 3D primitive</td>
- <td>TAB</td>
- <td><b>X</b></td>
- </tr>
- <tr>
- <td>Exit the sample</td>
- <td>ESC or ALT+F4</td>
- <td><b>BACK</b></td>
- </tr>
- </table>
- </div>
- </div>
- <a id="ID2EPD" name="ID2EPD"> </a><h1 class="heading">Using an Effect in Your Game</h1><div id="ID2EPD" class="hxnx1">
-
- <p>This sample contains two effects called "FlatShaded" and "VertexLighting." Each effect corresponds to its own file of the same name. The Content Pipeline handles the compilation and loading of effect files. In the code, Example 1.1 shows the various <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effect.aspx">Effect</a> types we use for the sample. Example 1.2 shows the initialization of these types. Like any other Content Pipeline type, they are loaded using the friendly name of the asset and are ready for use as soon as they have been loaded.</p>
- <p>Before effects become useful in any way, your application needs a way to provide data to them. These data fields are called <i>effect parameters</i>, and they correspond directly to variables in the shader code. Note that in Example 1.3, the <i>world</i>, <i>view</i>, and <i>projection</i> parameters are loaded by referring to the strings "world," "view," and "projection." If you then look at Example 2.1 in the FlatShaded.fx file, you'll see those same variables at a global scope. They represent uniform data that the shader needs to correctly position the vertices on the screen. These variables change no more than once per <b>Draw</b>—hence the term "uniform."</p>
- <p>The next thing to examine is where those effect parameters are set. In VertexLighting.cs Example 1.4 and Example 1.5, we're using <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effectparameter.setvalue.aspx">SetValue</a> to set the effect parameter to a value in the application. <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effectparameter.setvalue.aspx">SetValue</a> has several overloads to allow multiple kinds of data to be set. However, it is your responsibility to ensure that the type being set is the same type of data in the effect code. For example, the <i>world</i> parameter is a 4×4 <b>Matrix</b> type in the XNA Framework. In the HLSL effect code, a 4×4 <b>Matrix</b> is called a <b>float4x4</b>. Similarly, a <b>Vector3</b> in the XNA Framework is a <b>float3</b> in HLSL.</p>
- <p>The last interesting thing to look at in the source code deals with how we use the effect to draw primitives to the screen. Example 1.6 in the source code describes this in detail, but the steps are outlined here for completeness.</p>
- <ul>
- <li><p>Set up the geometry</p>
- <ul>
- <li>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.graphicsdevice.aspx">GraphicsDevice</a> vertex stream 0 is set to the mesh's vertex buffer.</li>
- <li>The <b>GraphicsDevice</b> indices are set to the mesh's indices.</li>
- </ul>
- </li>
- <li><p>Apply the effect</p>
- <ul>
- <li>Call <b>EffectPass.Apply</b> to set up the graphics device with the states defined by the selected <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effectpass.aspx">EffectPass</a>.</li>
- </ul>
- </li>
- <li>Draw the primitives</li>
-
- </ul>
- <p>What is happening under the hood is that the <b>Apply</b> function is setting states on the graphics device. If you've used the <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.basiceffect.aspx">BasicEffect</a> type, the pattern is probably pretty familiar. In fact, <b>BasicEffect</b> is simply an extension of <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effect.aspx">Effect</a> that has built-in shaders provided for some common lighting effects.</p>
- </div>
- <a id="ID2EWG" name="ID2EWG"> </a><h1 class="heading">FlatShaded Effect</h1><div id="ID2EWG" class="hxnx1">
-
- <p>The FlatShaded effect consists of a simple vertex and pixel shader pair. This effect is a great starting point for experimenting with shaders you create.</p>
- <p>Example 2.1 represents the uniform data supplied by the sample via <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effectparameter.aspx">EffectParameter</a> objects.</p>
- <p>Example 2.2 is the function body for the vertex shader function that positions the mesh vertices on the screen. When the mesh is drawn, this function is run once for each vertex in the scene. Each time the vertex shader function is run, the untransformed position parameter is transformed into a transformed position returned at the end of the function.</p>
- <p>This simple shader has only three lines of code. The first line concatenates the <i>world</i>, <i>view</i>, and <i>projection</i> matrices into a single matrix that applies all three transformations. The untransformed <i>position</i> parameter is then cast to a 4-component vector (with <b>w</b> equal to 1.0) and multiplied by the concatenated matrix. This transformation from model space to projection space is the basic requirement of all 3D rendering in XNA Game Studio, and it will appear again in varying forms throughout this series.</p>
- <p>The keyword <a href="http://msdn.microsoft.com/en-us/library/bb509628(v=VS.85).aspx">mul</a> is what is known as an <i>high-level shader language (HLSL) intrinsic function</i>. In this case, the function takes two matrix parameters and returns their product. However, in Example 2.4 the <b>mul</b> function takes a 4-component vector and a matrix. Most HLSL intrinsic functions are heavily overloaded for maximum flexibility. In this one function, <b>mul</b> is used to multiply (concatenate) matrices and multiply (transform) a coordinate by a matrix.</p>
- <p>You can find a complete list of HLSL intrinsic functions here: <a href="http://msdn.microsoft.com/en-us/library/ff471376(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ff471376(VS.85).aspx</a>.</p>
- <p>The next function (Example 2.5) is the pixel shader function, which is executed for each pixel covered by the transformed geometry. In most cases, the pixel shader returns a 4-component vector representing the output color. At this point there's no need for any additional information from Direct3D, the vertex shader, or the application, so the function has no parameters whatsoever. This shader simply returns a white color, represented in floating-point RGBA values as (1.0, 1.0, 1.0, 1.0).</p>
- <p>The last section in the FlatShaded.fx file (Example 2.6) is the code block specific to an effect file. Effect files differ slightly from straight HLSL because they define state for the 3D device. In this shader, the state section defines a <i>technique</i> and a <i>pass</i>, which correspond to the techniques and passes in the source code in Example 1.6. This structure is purely organizational; states that can be done on the device are replicated for effect files to simplify development. In the case of this effect, the pass <b>P0</b> defines the <b>VertexShader</b> state and the <b>PixelShader</b> state for the device when the pass is begun.</p>
- <p><b>VertexShader</b> is a keyword that represents the vertex shader on the graphics device. It is assigned to the vertex shader defined above. However, there are two special keywords exclusive to this state. The compile keyword is followed by <b>vs_2_0</b>. This indicates the shader model to which to compile the function. In this case, the function is compiled as a Vertex Shader Model 2.0 program. Shader models correspond to a "generation" of hardware feature sets that define such things as the supported number of operations per pass, intrinsic functions, and supported control statements.</p>
- <p>For the purposes of this sample, Shader Model 2.0 was chosen since it targets widely available computer hardware while giving a good deal of flexibility in expanding the effect without hitting premature hardware bottlenecks. The Xbox 360 platform is quite convenient in this respect, since it supports its own extended version of Shader Model 3.0 all the time, making it a well-known platform for experimentation.</p>
- <p>The <b>PixelShader</b> state is set the same way as the <b>VertexShader</b> state, but using the <b>ps_2_0</b> keyword to indicate that a pixel shader is being compiled.</p>
- </div>
- <a id="ID2EHBAC" name="ID2EHBAC"> </a><h1 class="heading">VertexLighting Effect</h1><div id="ID2EHBAC" class="hxnx1">
- <p>The vertex lighting effect has a few more effect parameters specific to the more complex effect. The <i>lightColor</i> and <i>lightDirection</i> parameters indicate the color and direction of the global light illuminating the geometry. We've also defined an ambient light color (Example 3.2) that represents a constant light scattered throughout the scene. Ambient light is not directional, so only the <i>color</i> parameter is required.</p>
- <p>To simplify the upcoming shader code, the effect defines a struct containing parameter information (Example 3.3). Notice that the <b>VertexShaderOutput</b> structure contains fields with semantics; this is a convenient way to clean up the function definition. Also notice that struct definitions in HLSL are terminated with a semicolon, which is a bit different than C#. There's no need to specify access modifiers on fields in HLSL—the entire language is implicitly public.</p>
- <p>This new structure represents the data to be returned from the vertex shader. This time, the shader will return both the required transformed position and the new COLOR0 semantic, representing a color at that vertex. </p>
- <p>The pixel shader now requires an input color to indicate what color to shade the destination pixels. A second structure is defined in Example 3.4 with the input color. All the lighting calculations are done in the vertex shader; the pixel shader simply returns the incoming color.</p>
- <p>Example 3.5 is the vertex shader function. Most of this is identical to FlatShaded.fx, but there are two new additions. First, there's the new parameter, <i>normal</i>, which indicates the unit normal direction of the vertex. A unit normal direction is required for the diffuse lighting equation. You can read more about normal vectors here: <a href="http://msdn2.microsoft.com/library/bb173380.aspx">http://msdn2.microsoft.com/library/bb173380.aspx</a>. The other new feature is that the function initializes an instance of the <b>VertexShaderOutput</b> structure defined above.</p>
- <p>Examples 3.6–3.8 are the math equations used to calculate a diffuse color for the vertex. A more complete discussion of this calculation is found in the next section of this document.</p>
- <p>The simple addition in Example 3.8 adds the global ambient color to the diffuse color calculated for the vertex. Since this sample doesn't account for transparency effects, the alpha component value is fixed at 1.0. You can access the individual components of a vector via RGBA or XYZW, similar to how you would reference component fields from the <b>Vector4</b> type in the XNA Framework.</p>
- <p>The pixel shader function is slightly more complicated than the function in FlatShaded.fx, since it returns the input color instead of simply returning white. This input color value is the interpolated value of the color at the pixel. It is "passed though" by the pixel shader.</p>
- <p>The interpolation of color values happens between the end of the vertex shader and the start of the pixel shader. When the triangles that make up a scene are set up from their constituent vertices, the 3D device translates the triangle positions to pixels. The color data returned from the vertex data is sent to the pixel shader interpolated with respect to the pixel's position between the vertices that define the triangle. Linear interpolation of color values creates the smooth shading effect known as <i>Gouraud Shading</i>.</p>
- </div>
-
- <a id="ID2E2CAC" name="ID2E2CAC"> </a><h1 class="heading">Explanation of the Diffuse Lighting Equation</h1><div id="ID2E2CAC" class="hxnx1">
- <p>The simplistic lighting used in the vertex shader function in VertexLighting.fx is called <i>Lambertian lighting</i> and represents the most simplistic way to calculate directional light.</p>
- <p>Lambertian lighting has uniform intensity irrespective of the distance away from the light. When the light hits the surface, the amount of light reflected is calculated by the angle of incidence the light has on the surface. When a light is shone perpendicular on a surface, it reflects all the light back, with maximum intensity. However, as the angle of incidence of the light is increased, the intensity of the light fades.</p>
-
- <img src="Lambertian.png" />
-
- <p>To calculate the intensity that a light has on a surface, you measure the angle between the light direction and the normal of the surface, which is defined as a vector perpendicular to the surface. You can measure this angle by using a <i>dot product</i>, which returns the projection of the light direction vector onto the normal.</p>
- <p>The <a href="http://msdn.microsoft.com/en-us/library/bb509594(v=VS.85).aspx">dot</a> intrinsic is one of the most important fundamental operations in 3D rendering, so understanding dot products is the key to developing lighting equations. Of key importance to diffuse lighting is that the dot product of two unit direction vectors yields the angle between them—the wider the angle, the less intense the light. Thus, the dot product of the normal and the light vector gives us the light intensity at that vertex.</p>
- <p>The light source used in this sample is only an approximation of directional lighting. The vector that describes the light source determines the direction of the light. Since it's an approximation, no matter where an object is, the direction in which the light shines toward it is the same. An example of this light source is the sun, which is always seen to be shining in the same direction for all objects in a scene. In addition, the intensity of the light on individual objects is not taken into consideration.</p>
- <p>Example 3.6 orients the normal direction into world space. This is done because the light direction is defined in world coordinate space, but the normal is still in model space. For the equation to make sense, both the normal and the light vector must be in the same coordinate space.</p>
- <p>Example 3.7 is the implementation of the dot-product function described above. The <b>dot</b> intrinsic speaks for itself: it returns the scalar dot product of two vectors. The <a href="http://msdn.microsoft.com/en-us/library/bb509645(v=VS.85).aspx">saturate</a> intrinsic is something new however. This intrinsic clamps the value of the parameter between 0.0 and 1.0. This primarily prevents the intensity of the light from becoming negative for normals that face away from the light source, resulting in physically impossible negative intensities.</p>
- <p>Example 3.8 calculates the diffuse color by multiplying the scalar intensity by the light's color.</p>
- </div>
-
- <a id="ID2EFEAC" name="ID2EFEAC"> </a><h1 class="heading">Extending the Sample</h1><div id="ID2EFEAC" class="hxnx1">
- <p>The shaders in this sample are a great jumping-off point for your experimentation. The following are some ideas for your exploration.</p>
- <ol>
- <li>In FlatShaded.fx, three matrices are set for each frame, but it might be more efficient to simply pass a pre-concatenated world-view-projection matrix to the function. Try creating a new <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.effectparameter.aspx">EffectParameter</a> and a new corresponding variable in the FlatShaded effect to facilitate the change.</li>
- <li>VertexLighting.fx defines a single global light source. Try adding more light sources, and if you are feeling adventurous, try adding a point light or a spot light.</li>
- <li>The pixel shaders in both FlatShaded.fx and VertexLighting.fx are not very interesting, and there are lots of places to experiment here. Try reversing some of the color components, or averaging the color components to create a gray scale image from the input colors.</li>
- </ol>
- </div>
-
- </div><div class="footer" id="footer"><p>© 2010 Microsoft Corporation. All rights reserved.<br />Send feedback to <a href="mailto:[email protected]?subject=Documentation Feedback: Shader Series 1: VertexLighting Sample">[email protected]</a>.</p></div></div></body></html>
|