PerPixelLighting.htm 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. <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 3: Per-Pixel Lighting Sample</title>
  2. <style><!--
  3. /***********************************************************
  4. * SCRIPT-SUPPORTING STYLES
  5. ***********************************************************/
  6. /* Defines the userData cache persistence mechanism. */
  7. .userDataStyle
  8. {
  9. behavior: url(#default#userData);
  10. }
  11. /* Used to save the scroll bar position when navigating away from a page. */
  12. div.saveHistory
  13. {
  14. behavior: url(#default#saveHistory);
  15. }
  16. /* Formats the expand/collapse images for all collapsible regions. */
  17. img.toggle
  18. {
  19. border: 0;
  20. margin-right: 5;
  21. }
  22. /* Formats the Language filter drop-down image. */
  23. img#languageFilterImage
  24. {
  25. border: 0;
  26. margin-left: 0;
  27. vertical-align: middle;
  28. }
  29. /* Formats the Members Options filter drop-down image. */
  30. img#membersOptionsFilterImage
  31. {
  32. border: 0;
  33. margin-left: 0;
  34. vertical-align: middle;
  35. }
  36. /* Formats the Collapse All/Expand All images. */
  37. img#toggleAllImage
  38. {
  39. margin-left: 0;
  40. vertical-align: middle;
  41. }
  42. /* Supports XLinks */
  43. MSHelp\:link
  44. {
  45. text-decoration: underline;
  46. color: #0000ff;
  47. hoverColor: #3366ff;
  48. filterString: ;
  49. }
  50. body
  51. {
  52. background: #FFFFFF;
  53. color: #000000;
  54. font-family: Verdana;
  55. font-size: medium;
  56. font-style: normal;
  57. font-weight: normal;
  58. margin-top: 0;
  59. margin-bottom: 0;
  60. margin-left: 0;
  61. margin-right: 0;
  62. width: 100%;
  63. /*font-size: 110%;*/
  64. }
  65. div.section
  66. {
  67. margin-left: 15px;
  68. }
  69. div.hxnx5
  70. {
  71. margin-left: 1.5em;
  72. }
  73. /* Font for all headings */
  74. h1, h2, h3, h4, h5, h6
  75. {
  76. font-family: Verdana, Arial, Helvetica, sans-serif;
  77. margin-top: 18;
  78. margin-bottom: 8;
  79. font-weight: bold;
  80. }
  81. h1
  82. {
  83. font-size: 130%;
  84. color: #003399;
  85. }
  86. div#scrollyes h1 /* Changes font size for full-scrolling topic */
  87. {
  88. font-size: 150%;
  89. }
  90. h2
  91. {
  92. font-size: 122%;
  93. }
  94. h3
  95. {
  96. font-size: 115%;
  97. margin-top: 9;
  98. margin-bottom: 4;
  99. }
  100. h4
  101. {
  102. font-size: 115%;
  103. margin-top: 9;
  104. margin-bottom: 4;
  105. }
  106. h5
  107. {
  108. font-size: 100%;
  109. margin-top: 9;
  110. margin-bottom: 4;
  111. }
  112. h6
  113. {
  114. font-size: 100%;
  115. margin-top: 9;
  116. margin-bottom: 4;
  117. }
  118. ul p, ol p, dl p
  119. {
  120. margin-left: 0em;
  121. }
  122. p
  123. {
  124. margin-top: .6em;
  125. margin-bottom: .6em;
  126. }
  127. td p
  128. {
  129. margin-top: 0.0em;
  130. margin-bottom: 0.6em;
  131. }
  132. dd p
  133. {
  134. margin-top: 0.0em;
  135. margin-bottom: 0.6em;
  136. }
  137. .image
  138. {
  139. text-align: center;
  140. }
  141. dl
  142. {
  143. margin-top: 0em;
  144. margin-bottom: 1.3em;
  145. }
  146. dd
  147. {
  148. margin-bottom: 0em;
  149. margin-left: 1.5em;
  150. }
  151. dl.glossary dd
  152. {
  153. margin-bottom: 0em;
  154. margin-left: 1.5em;
  155. }
  156. dt
  157. {
  158. margin-top: .6em;
  159. margin-bottom: 1;
  160. }
  161. ul, ol
  162. {
  163. margin-top: 0.6em;
  164. margin-bottom: 0.6em;
  165. }
  166. ol
  167. {
  168. margin-left: 2.5em;
  169. }
  170. ul
  171. {
  172. list-style-type: disc;
  173. margin-left: 1.9em;
  174. }
  175. li
  176. {
  177. margin-bottom: 0.4em;
  178. }
  179. ul ol, ol ol
  180. {
  181. list-style-type: lower-alpha;
  182. }
  183. pre
  184. {
  185. margin-top: .6em;
  186. margin-bottom: .6em;
  187. font: 105% Lucida, mono;
  188. color: #000066;
  189. }
  190. code
  191. {
  192. font-family: Monospace, Courier New, Courier;
  193. font-size: 105%;
  194. color: #000066;
  195. }
  196. table.userdata td
  197. {
  198. background: #ffffff;
  199. background-color: #F5F5F5;
  200. border-color: #ffffff;
  201. border: none;
  202. }
  203. table.clsWarning
  204. {
  205. background: #ffffff;
  206. padding: 0px;
  207. margin: 0px;
  208. border: none;
  209. }
  210. table.clsWarning td
  211. {
  212. padding: 0px;
  213. margin: 0px;
  214. background: #ffffff;
  215. vertical-align: middle;
  216. font-size: 70%;
  217. }
  218. div#mainSection table
  219. {
  220. width: 95%;
  221. background: #ffffff;
  222. margin-top: 5px;
  223. margin-bottom: 5px;
  224. }
  225. div#mainSection table th
  226. {
  227. padding: 5px 6px;
  228. background: #EFEFF7;
  229. text-align: left;
  230. font-size: 70%;
  231. vertical-align: bottom;
  232. border-bottom: 1px solid #C8CDDE;
  233. }
  234. div#mainSection table td
  235. {
  236. padding: 5px 5px;
  237. background: #F7F7FF;
  238. vertical-align: top;
  239. font-size: 70%;
  240. border-bottom: 1px solid #D5D5D3;
  241. }
  242. div#syntaxCodeBlocks table th
  243. {
  244. padding: 1px 6px;
  245. color: #000066;
  246. }
  247. div#syntaxCodeBlocks table td
  248. {
  249. padding: 1px 5px;
  250. }
  251. /* Applies to the running header text in the first row of the upper table in the
  252. non-scrolling header region. */
  253. span#runningHeaderText
  254. {
  255. color: #003399;
  256. font-size: 90%;
  257. padding-left: 13;
  258. }
  259. /* Applies to the topic title in the second row of the upper table in the
  260. non-scrolling header region. */
  261. span#nsrTitle
  262. {
  263. color: #003399;
  264. font-size: 120%;
  265. font-weight: 600;
  266. padding-left: 13;
  267. }
  268. /* Applies to everything below the non-scrolling header region. */
  269. div#mainSection
  270. {
  271. font-size: 70%;
  272. width: 100%;
  273. }
  274. /* Applies to everything below the non-scrolling header region, minus the footer. */
  275. div#mainBody
  276. {
  277. font-size: 90%;
  278. margin-left: 15;
  279. margin-top: 10;
  280. padding-bottom: 20;
  281. }
  282. /* Adds right padding for all blocks in mainBody */
  283. div#mainBody p, div#mainBody ol, div#mainBody ul, div#mainBody dl
  284. {
  285. padding-right: 5;
  286. }
  287. div#mainBody div.alert, div#mainBody div.code, div#mainBody div.tableSection
  288. {
  289. width:98.9%;
  290. }
  291. div.alert p, div.code p
  292. {
  293. margin-top:5;
  294. margin-bottom:8;
  295. }
  296. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  297. div#mainSection div.alert table
  298. {
  299. border: 0;
  300. }
  301. div#mainSection div.alert table th
  302. {
  303. padding-top: 0;
  304. padding-bottom: 0;
  305. padding-left: 5;
  306. padding-right: 5;
  307. }
  308. div#mainSection div.alert table td
  309. {
  310. padding-left: 5;
  311. padding-right: 5;
  312. }
  313. img.note
  314. {
  315. border: 0;
  316. margin-left: 0;
  317. margin-right: 3;
  318. }
  319. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - End Note Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  320. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Begin Non-scrolling Header Region Styles - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  321. /* Applies to the entire non-scrolling header region. */
  322. div#header
  323. {
  324. background-color: #D4DFFF;
  325. padding-top: 0;
  326. padding-bottom: 0;
  327. padding-left: 0;
  328. padding-right: 0;
  329. width: 100%;
  330. }
  331. /* Applies to both tables in the non-scrolling header region. */
  332. div#header table
  333. {
  334. margin-top: 0;
  335. margin-bottom: 0;
  336. border-bottom-color: #C8CDDE;
  337. border-bottom-style: solid;
  338. border-bottom-width: 1;
  339. background: #D4DFFF;
  340. width: 100%;
  341. }
  342. /* Applies to cells in both tables in the non-scrolling header region. */
  343. div#header table td
  344. {
  345. color: #0000FF;
  346. font-size: 70%;
  347. padding-right: 20;
  348. padding-top: 1;
  349. padding-bottom: 1;
  350. border: none;
  351. background: #D4DFFF;
  352. }
  353. /* Applies to the last row in the upper table of the non-scrolling header region. Text
  354. in this row includes See Also, Constructors, Methods, and Properties. */
  355. div#header table tr#headerTableRow3 td
  356. {
  357. padding-bottom: 2;
  358. padding-top: 5;
  359. padding-left: 15;
  360. }
  361. /* Applies to the lower table in the non-scrolling header region. Text in this table
  362. includes Collapse All/Expand All, Language Filter, and Members Options. */
  363. div#header table#bottomTable
  364. {
  365. border-top-color: #FFFFFF;
  366. border-top-style: solid;
  367. border-top-width: 1;
  368. text-align: left;
  369. padding-left: 15;
  370. }
  371. blockquote
  372. {
  373. margin-left: 3.8em;
  374. margin-right: 3.8em;
  375. margin-top: .6em;
  376. margin-bottom: .6em;
  377. }
  378. sup
  379. {
  380. text-decoration: none;
  381. font-size: smaller;
  382. }
  383. a:link
  384. {
  385. color: #0000FF;
  386. /* font-weight: bold */
  387. }
  388. a:visited
  389. {
  390. color: #0000AA;
  391. /* font-weight: bold */
  392. }
  393. a:hover
  394. {
  395. color: #3366FF;
  396. /* font-weight: bold */
  397. }
  398. .label
  399. {
  400. font-weight: bold;
  401. margin-top: 1em;
  402. margin-left: -26px;
  403. }
  404. .tl
  405. {
  406. margin-bottom: .75em;
  407. }
  408. .atl
  409. {
  410. padding-left: 1.5em;
  411. padding-bottom: .75em;
  412. }
  413. .cfe
  414. {
  415. font-weight: bold;
  416. }
  417. .mini
  418. {
  419. font-size: smaller;
  420. }
  421. .dt
  422. {
  423. margin-bottom: -.6em;
  424. }
  425. .indent
  426. {
  427. margin-left: 1.9em;
  428. margin-right: 1.9em;
  429. }
  430. .product
  431. {
  432. text-align: right;
  433. color: #333333;
  434. font-size: smaller;
  435. font-style: italic;
  436. }
  437. .buttonbarshade
  438. {
  439. position: relative;
  440. margin: 0;
  441. left: 0px;
  442. top: 2;
  443. width: 50%;
  444. height: 40px;
  445. }
  446. .buttonbartable
  447. {
  448. position: absolute;
  449. margin: 0;
  450. padding:0;
  451. border:0;
  452. left:0px;
  453. top: 2;
  454. width: 100%;
  455. height: 40px;
  456. }
  457. /* background color, font for header */
  458. table.buttonbartable td, table.buttonbarshade td
  459. {
  460. background: #ffffff; /*#5177B8; #80C615;*/
  461. border-left: 0px solid #80C615;
  462. margin: 0;
  463. padding: 0px 0px 0px 0px;
  464. font-family: Impact, sans-serif;
  465. font-size: 14pt;
  466. }
  467. table.buttonbartable td.button1
  468. {
  469. background: #5177B8; /*#80C615;*/;
  470. padding: 0;
  471. font-weight: bold;
  472. text-align: center;
  473. cursor: hand;
  474. }
  475. table.buttonbartable td.button2
  476. {
  477. background: #5177B8; /*#80C615;*/;
  478. font-weight: bold;
  479. text-align: center;
  480. }
  481. table.buttonbartable td.button3
  482. {
  483. background: #5177B8; /*#80C615;*/;
  484. font-weight: bold;
  485. text-align: center;
  486. }
  487. table.buttonbartable td.runninghead
  488. {
  489. padding-left: 0px;
  490. font-style: italic;
  491. text-align: left;
  492. }
  493. .version
  494. {
  495. text-align: left;
  496. color: #000000;
  497. margin-top: 3em;
  498. margin-left: -26px;
  499. font-size: smaller;
  500. font-style: italic;
  501. }
  502. .lang, .ilang
  503. {
  504. color: #0000ff;
  505. font: normal 7pt Arial, Helvetica, sans-serif;
  506. }
  507. div.langMenu
  508. {
  509. position: absolute;
  510. z-index: 1;
  511. width: 96pt;
  512. padding: 8pt;
  513. visibility: hidden;
  514. border: 1px solid #000000;
  515. background: #ffffd0;
  516. }
  517. div.langMenu ul
  518. {
  519. padding-left: 2em;
  520. margin-left: 0;
  521. }
  522. div.filtered
  523. {
  524. margin: 4pt 0 8pt -26px;
  525. padding: 4px 4px 8px 26px;
  526. width: 100%;
  527. border: 2px solid #aaaacc;
  528. background: #ffffff;
  529. }
  530. div.filtered2
  531. {
  532. margin: 4pt 0 8pt -26px;
  533. padding: 4px 4px 8px 26px;
  534. width: 100%;
  535. border: none;
  536. background: #ffffff;
  537. }
  538. div.filtered h1, div.filtered h2, div.filtered h3, div.filtered h4
  539. {
  540. margin-left: -22px;
  541. }
  542. div.filtered span.lang
  543. {
  544. position: relative;
  545. left: -22px;
  546. }
  547. div.reftip
  548. {
  549. position: absolute;
  550. z-index: 1;
  551. padding: 8pt;
  552. visibility: hidden;
  553. border: 1px solid #000000;
  554. background: #ffffd0;
  555. }
  556. a.synParam
  557. {
  558. color: #0000FF;
  559. /*color: #3F7800;*/
  560. /*color: #8DC54F;*/
  561. text-decoration: none;
  562. font-weight: normal;
  563. }
  564. a.synParam:hover
  565. {
  566. text-decoration: underline;
  567. font-weight: normal;
  568. }
  569. div.sapop
  570. {
  571. position: absolute;
  572. z-index: 1;
  573. left: 26px;
  574. width: 100%;
  575. padding: 10px 10px 10px 36px;
  576. visibility: hidden;
  577. border: 1px solid #000000;
  578. background: #ffffd0;
  579. }
  580. div.footer
  581. {
  582. width: 100%;
  583. border: none;
  584. background: #ffffff;
  585. margin-top: 18pt;
  586. padding-bottom: 12pt;
  587. color: #0000FF;
  588. /*color: #228B22; */
  589. text-align: center;
  590. font-size: 76%;
  591. }
  592. div.preliminary
  593. {
  594. margin-top: 8pt;
  595. padding-bottom: 12pt;
  596. color: #A0A0A0;
  597. }
  598. /* A procedure section. eg. 'To create a file', 'To add a value' */
  599. div.proc
  600. {
  601. margin-left: 0.5em;
  602. }
  603. /* The title of a 'procedure' section. */
  604. div.proc h3
  605. {
  606. font-family: Verdana, Arial, Helvetica, sans-serif;
  607. font-weight: bold;
  608. font-size: 115%;
  609. margin-top: 1em;
  610. margin-bottom: 0.4em;
  611. margin-left: -0.5em;
  612. color: #003399;
  613. }
  614. div.proc ul
  615. {
  616. margin-left: 1.5em;
  617. }
  618. div.proc ol
  619. {
  620. margin-left: 2.0em;
  621. }
  622. .note
  623. {
  624. margin-left: 14pt;
  625. margin-right: 12pt;
  626. }
  627. .indent1
  628. {
  629. margin-left: 12pt;
  630. }
  631. .indent2
  632. {
  633. margin-left: 24pt;
  634. }
  635. .indent3
  636. {
  637. margin-left: 36pt;
  638. }
  639. p.proch
  640. {
  641. padding-left: 16px;
  642. }
  643. p.proch img
  644. {
  645. position: relative;
  646. vertical-align: top;
  647. left: -18px;
  648. margin-right: -14px;
  649. margin-bottom: -18px;
  650. }
  651. div.clsPlatSpec
  652. {
  653. background-color:#FFF8DC;
  654. border-style:solid;
  655. border-width:1pt 0pt 0pt 1pt;
  656. border-color:#ffE4C4;
  657. margin-top:0.6em;
  658. width:100%;
  659. }
  660. /* Applies to the language labels in the Language Filter drop-down list. */
  661. .languageFilter
  662. {
  663. color: #0000FF;
  664. cursor:hand;
  665. text-decoration:underline;
  666. padding-bottom:4;
  667. }
  668. /* Dropdown areas */
  669. #languageSpan {
  670. position: absolute;
  671. visibility: hidden;
  672. border-style: solid;
  673. border-width: 1px;
  674. border-color: #C8CDDE;
  675. background: #d4dfff;
  676. padding: 4px;
  677. font-size: 70%;
  678. }
  679. #membersOptionsSpan {
  680. position: absolute;
  681. visibility: hidden;
  682. border-style: solid;
  683. border-width: 1px;
  684. border-color: #C8CDDE;
  685. background: #d4dfff;
  686. padding: 4px;
  687. font-size: 70%;
  688. }
  689. --></style>
  690. <xml>
  691. <MSHelp:TOCTitle Title="Shader Series 3: Per-Pixel Lighting Sample" />
  692. <MSHelp:RLTitle Title="Shader Series 3: Per-Pixel Lighting Sample" />
  693. <MSHelp:Keyword Index="A" Term="O:Microsoft.Xna.PerPixelLighting" />
  694. <MSHelp:Keyword Index="A" Term="e4731cef-1585-bb70-7970-4fac71ee8bf1" />
  695. <MSHelp:Keyword Index="K" Term="Shader Series 3: Per-Pixel Lighting Sample" />
  696. <MSHelp:Attr Name="AssetID" Value="e4731cef-1585-bb70-7970-4fac71ee8bf1" />
  697. <MSHelp:Attr Name="Locale" Value="en-us" />
  698. <MSHelp:Attr Name="CommunityContent" Value="1" />
  699. <MSHelp:Attr Name="TopicType" Value="kbOrient" />
  700. </xml>
  701. </head><body><div id="mainSection"><div id="mainBody">
  702. <h1>Shader Series 3: Per-Pixel Lighting Sample</h1>
  703. <p>This sample explains how to move lighting calculations to the pixel shader for high-quality per-pixel lighting. Additionally, this sample uses Phong reflection to approximate specular light, creating "highlights" on the object. Specular highlights are light that is reflected directly to a viewer and can be simulated through a number of techniques.</p>
  704. <div class="alert"><table cellspacing="0" cellpadding="0"><tr><th>Note </th></tr><tr><td>
  705. <ul>
  706. <li>This is the third sample in the Shader Series. Before you begin, you should be familiar with the content of the previous entries in the series, as well as the Shader Primer article.</li>
  707. <li>The code for this sample is similar to the VertexLighting Sample. Refer to the VertexLighting Sample and associated document for more information about this code.</li>
  708. <li>The models presented in this sample are the same used in the VertexLighting Sample.</li>
  709. </ul>
  710. </td></tr></table></div>
  711. <a id="ID2EZ" name="ID2EZ"> </a><h1 class="heading">Sample Controls</h1><div id="ID2EZ" class="hxnx1">
  712. <p>This sample uses the following keyboard and gamepad controls.</p>
  713. <table>
  714. <tr>
  715. <th>Action</th>
  716. <th>Keyboard control</th>
  717. <th>Gamepad control</th>
  718. </tr>
  719. <tr>
  720. <td>Rotate the camera</td>
  721. <td>W, A, S, and D</td>
  722. <td>Right analog D-pad</td>
  723. </tr>
  724. <tr>
  725. <td>Rotate the mesh</td>
  726. <td>UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW</td>
  727. <td>Left analog D-pad</td>
  728. </tr>
  729. <tr>
  730. <td>Zoom in</td>
  731. <td>Z</td>
  732. <td>
  733. <b>A</b>
  734. </td>
  735. </tr>
  736. <tr>
  737. <td>Zoom out</td>
  738. <td>X</td>
  739. <td>
  740. <b>B</b>
  741. </td>
  742. </tr>
  743. <tr>
  744. <td>Use a different technique to render the current 3D primitive</td>
  745. <td>SPACEBAR</td>
  746. <td>
  747. <b>Y</b>
  748. </td>
  749. </tr>
  750. <tr>
  751. <td>Display a different 3D primitive</td>
  752. <td>TAB</td>
  753. <td>
  754. <b>X</b>
  755. </td>
  756. </tr>
  757. <tr>
  758. <td>Change the specular power constant for the material</td>
  759. <td>* or /</td>
  760. <td>D-pad Left/Right</td>
  761. </tr>
  762. <tr>
  763. <td>Change the specular intensity constant for the material</td>
  764. <td>+ or -</td>
  765. <td>D-pad Up/Down</td>
  766. </tr>
  767. <tr>
  768. <td>Exit the sample</td>
  769. <td>ESC or ALT+F4</td>
  770. <td>
  771. <b>BACK</b>
  772. </td>
  773. </tr>
  774. </table>
  775. </div>
  776. <a id="ID2EME" name="ID2EME"> </a><h1 class="heading">Separating the Light Components</h1><div id="ID2EME" class="hxnx1">
  777. <p>In the classic fixed-function graphics pipeline, the color of a primitive via illumination is a function called the "Phong Reflectance Model." This function can be written as:</p>
  778. <p>
  779. <b>Total Light = Ambient + Diffuse + Specular</b>
  780. </p>
  781. <p>The Phong model also provides definitions for each of these components.</p>
  782. <ul>
  783. <li><b>Diffuse</b> (also called <i>Lambertian</i>) is the easiest to understand. It is the light reflected by the object from a directional light source. Diffuse light is easy to calculate from the light direction and the normal vector of the primitive at a given vertex or pixel. The VertexLighting Sample (Shader Series 1) demonstrated how to compute diffuse lighting in the vertex shader.</li>
  784. <li><b>Ambient</b> is an approximation of scattered light in the scene. Scattered light comes from the real-world property of <i>diffuse interflection</i>. The light that leaves the surface of an object and enters your eye also bounces in all directions. Some of this scattered light will be reflected off of other objects toward the viewer. In this model, however, the scattered light is not directly modeled; instead, ambient light is added to all vertices or pixels in the scene uniformly. While this is not mathematically accurate, it adds some color to vertices or pixels that do not receive any diffuse light, which is typically more realistic than no illumination at all.</li>
  785. <li><b>Specular</b> is a component of the Phong model that may be unfamiliar. Specular reflectance can be thought of as "mirror-like" reflections, like the highlights you see in shiny substances such as glass and metal. This component gives the viewer a better idea of the kind of material being rendered. </li>
  786. </ul>
  787. <p>The reality is that light does not actually separate nicely into these components and actually combines properties of all three into the light that you see reflected from real-world materials. Shader programs give you the flexibility to add as much or as little accuracy as you would like. It also allows you to tailor your lighting model to suit your 3D application’s visual style and performance requirements.</p>
  788. </div>
  789. <a id="ID2EPF" name="ID2EPF"> </a><h1 class="heading">Specular Component</h1><div id="ID2EPF" class="hxnx1">
  790. <p>The specular component is dependent on a new variable—the viewer's <i>aspect</i>—the angle between the direction of the viewer and the surface. Specular light changes on a surface as a viewer's aspect to that surface changes. This is a key visual "hint" that a viewer is looking at something with specific reflective properties, particularly as the viewer rotates the camera. The diffuse-only versions of the Effects do not give this additional perspective when just moving the camera.</p>
  791. <p>When calculating diffuse light, we consider only a surface normal when determining the contribution of light to a surface. For view-dependent lighting, we need to relate that in some way to the viewer's aspect. To do so, Phong illumination considers how a light is reflected off of a surface. Let's suppose a ray of light strikes a point on a surface and reflects perfectly from that surface. The direction of reflection is known as a <i>reflection vector</i>.</p>
  792. <img src="Reflection.png" />
  793. <p>This reflection vector can be calculated with the following function.</p>
  794. <p>
  795. <b>vReflection = 2.0 * vNormal * ( vNormal • vLight ) − vLight</b>
  796. </p>
  797. <p>The proof of this equation is beyond the scope of this sample. Fortunately, HLSL provides a <b>reflect()</b> intrinsic function that does the same operation (see example 1.6 in VertexLighting.fx).</p>
  798. <p>The next step for Phong reflection is to relate the reflection vector to the view direction. Again, we use a dot product to determine the contribution of light at the point. Like diffuse lighting, a dot product is a convenient way of calculating fall-off by giving an angle between two vectors. For this part of the specular equation, we calculate the angle between the direction to the viewer and the light reflection to determine the intensity of the specular light.</p>
  799. <img src="Phong.png" />
  800. <p>The last component of specular light in the Phong model is a quantification of the "shininess" of a given material. This is done with a pair of constants known as <i>specular power</i> and <i>specular intensity</i>. The dot product of the reflection vector and the view direction vector are taken to the power of the specular power and multiplied by the specular intensity. The resulting equation looks like this:</p>
  801. <p><b>Specular = specularIntensity * (( vReflection • vViewDirection ) ^ specularPower)</b></p>
  802. <p>You can combine this value with the ambient and diffuse lighting values to complete the Phong equation.</p>
  803. </div>
  804. <a id="ID2EJH" name="ID2EJH"> </a><h1 class="heading">Per-Pixel Lighting</h1><div id="ID2EJH" class="hxnx1">
  805. <p>You may notice upon trying the sample for the first time that the per-vertex calculation for specular lighting doesn't look very good. This is because the lighting equation is evaluated at each vertex, and interpolated across each triangle via the Color semantic (as output from the vertex shader and input to the pixel shader). This interpolation does not necessarily match the value we would have at each individual pixel, particularly with respect to the specular component.</p>
  806. <p>We can achieve a much smoother visual effect by evaluating the specular lighting component at each pixel. Recalculating Phong illumination at each pixel is a technique known as <i>Phong shading</i> and is a great starting point for more elaborate lighting models. The sample also includes shaders that move the diffuse calculation to the pixel shader. While the benefit from computing diffuse lighting per-pixel is less dramatic than that of specular, there are fewer artifacts in the diffuse light.</p>
  807. </div>
  808. <a id="ID2EVH" name="ID2EVH"> </a><h1 class="heading">Implementation of Per-Vertex Phong Reflection</h1><div id="ID2EVH" class="hxnx1">
  809. <p>The first thing to notice in VertexLighting.fx is that it is fairly similar to the effect presented in Shader Series 1: VertexLighting Sample. There are, however, a few new constants. Example 1.1 declares the specular power and specular intensity of the material being rendered. Example 1.2 is a declaration of a camera position that also figures into the specular function. As always, these parameters are set by the sample application through <b>EffectParameters</b> in the C# source code.</p>
  810. <p>Example 1.3 shows a step required for many kinds of shader operations. The single light in the scene is represented in world-space coordinates. For the lighting equations to make sense, all of the other vector components must also be transformed to world space. This applies whether working in model space, world space, view space, or projection space.</p>
  811. <p>Example 1.4 is another common, important step: ensuring the coordinate is in homogenous space. This is typically necessary only when transforming positions, and is not necessary for the direction vectors in this effect.</p>
  812. <p>The first application of the previous discussion of specular highlighting can be found in Example 1.6. This section is the vertex shader implementation of the equation for determining a reflection vector from a point light source. Example 1.7 completes the Phong specular equation by taking the dot product of the view direction (the direction to the camera) and the reflection vector. Specular power and intensity are applied to give an overall specular contribution. This is multiplied by the color of the specular light to give the total specular color for the vertex. Note that the dot product is clamped from 0 to 1 by using the <b>saturate</b> intrinsic. This is done because, like diffuse intensity, negative values do not make sense, so they are omitted.</p>
  813. <p>Finally, in Example 1.8, the Phong reflection equation is completed by summing the ambient, diffuse, and specular components and storing them in the vertex color register. These colors are then interpolated into screen-space pixel values. The simplistic pixel shader simply returns the interpolated color.</p>
  814. </div>
  815. <a id="ID2ELAAC" name="ID2ELAAC"> </a><h1 class="heading">Implementation of Per-Pixel Phong Reflection</h1><div id="ID2ELAAC" class="hxnx1">
  816. <p>In Shader Series 2, TEXCOORD outputs were used to send interpolated texture coordinates to the pixel shader for use in looking up texture values at each pixel. It turns out that this linear interpolation makes the TEXCOORD registers far more flexible than their name suggests. These registers are used to send anything that can be sensibly linearly interpolated to pixels from the vertex shader.</p>
  817. <p>This is a tremendously powerful technique, and it will appear in all but the most basic shaders. Using the <b>texcoord</b> registers to store additional data about a pixel enables a wide range of data to be made available when the pixel shader is run on that pixel. In PerPixelLighting.fx, Example 2.1, the vertex shader output structure uses TEXCOORD registers 0 and 1 to store world normals and positions, respectively. The pixel shader inputs correspond to these <b>texcoord</b> registers and are named appropriately.</p>
  818. <p>The execution of this usage pattern can be seen in Example 2.2. The world normal and world position are set as outputs so they can be consumed at a per-pixel level in the pixel shader. Diffuse light is being calculated in the vertex shader and is added to the ambient component in Example 2.3.</p>
  819. <p>The pixel shader code in Example 2.4 is nearly identical to the per-vertex implementation of Phong specular, but it is being done with much higher granularity at the pixel level. Using the interpolated world positions and normals, calculating the lighting effect at each pixel gives a much more precise approximation of specular light. In Example 2.5, the specular component is added to the input color, which is the Gouraud shaded diffuse plus ambient components from the vertex shader.</p>
  820. <p>Starting with Example 2.6, some other per-pixel vertex and pixel shaders are introduced that move the entire lighting calculation to the pixel shader. The vertex shader simply acts as a setup step to create the proper inputs for the pixel shaders in Examples 2.8 and 2.9. Calculating diffuse light with per-pixel granularity gives less dramatic results than that of specular lighting, but there is a small image improvement.</p>
  821. <p>The drawback to moving calculations to the pixel shader is that there are far more pixels in our scene than vertices. Therefore, pixel-shader operations will be run more times than those in a vertex shader, and this solution may run slower than the per-vertex techniques. It is up to the developer to determine the performance versus quality tradeoff when developing lighting shaders.</p>
  822. <p>The <b>BasicEffect</b> class built into the framework implements a Phong lighting model with ambient, diffuse, and specular components by using the same computations described in this sample. By default, <b>BasicEffect</b> uses per-vertex lighting, but you can set the <b>BasicEffect.PreferPerPixelLighting</b> property to <b>true</b> to use per-pixel lighting instead.
  823. </p>
  824. </div>
  825. <a id="ID2EMBAC" name="ID2EMBAC"> </a><h1 class="heading">Extending the Sample</h1><div id="ID2EMBAC" class="hxnx1">
  826. <p><b>Specular Textures:</b> In Shader Series 2: Textures and Colors Sample, the concept of pixel-shader texturing was introduced. Armed with the ability to apply specular lighting, you can now create specular textures (also called <i>specular maps</i>) to add another dimension of detail to the geometry in the scene. Combining diffuse and specular textures can create very realistic lighting effects. It can also be applied to create fantastic or other-worldly lighting effects to represent non-realistic materials.</p>
  827. <p><b>Blinn-Phong Reflection:</b> A potentially more efficient and more physically accurate variation of Phong illumination is Blinn-Phong reflection. Try researching the Blinn-Phong shading model and modifying the sample to use Blinn-Phong. Hint: instead of passing a world position and world normal via <b>texcooord</b> registers, try passing the "half-vector" and the world normal.</p>
  828. </div>
  829. </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 3: Per-Pixel Lighting Sample">[email protected]</a>.</p></div></div></body></html>