NormalMappingEffect.htm 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  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>Normal Mapping Effect 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="Normal Mapping Effect Sample" />
  692. <MSHelp:RLTitle Title="Normal Mapping Effect Sample" />
  693. <MSHelp:Keyword Index="A" Term="O:Microsoft.Xna.NormalMappingEffect" />
  694. <MSHelp:Keyword Index="A" Term="f9d93db2-f058-34f5-9102-e106d7f56b4a" />
  695. <MSHelp:Keyword Index="K" Term="Normal Mapping Effect Sample" />
  696. <MSHelp:Attr Name="AssetID" Value="f9d93db2-f058-34f5-9102-e106d7f56b4a" />
  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>Normal Mapping Effect Sample</h1>
  703. <p>
  704. This sample builds on the concepts illustrated in the Custom Model Effect sample, and applies a normal mapping effect to a mesh. The sample also uses a custom content processor to demonstrate two additional concepts: adding and removing per vertex data from a mesh, and reading opaque data.
  705. </p>
  706. <a id="ID2EN" name="ID2EN"> </a><h1 class="heading">Sample Overview</h1><div id="ID2EN" class="hxnx1">
  707. <p>The sample demonstrates how to use a custom effect to render a model with a normal map, creating the appearance of a bumpy surface without needing to render additional geometry.</p>
  708. <p>A custom content pipeline processor applies the normal mapping effect to the model during the content build process. The processor also creates additional per-vertex data channels for the binormal and tangent information, which the normal mapping effect uses. Finally, the processor uses opaque data to determine which normal map to use, and then applies it to the material.</p>
  709. <p>To make rendering more efficient at run time, a second custom processor changes the normal map pixel format from an encoded unsigned format to a signed format.</p>
  710. <a id="ID2EX" name="ID2EX"> </a><h2 class="subHeading">Sample Controls</h2><div id="ID2EX" class="hxnx2">
  711. <p>This sample uses the following keyboard and gamepad controls.</p>
  712. <table>
  713. <tr>
  714. <th>Action</th>
  715. <th>Keyboard control</th>
  716. <th>Gamepad control</th>
  717. </tr>
  718. <tr>
  719. <td>Rotate the model</td>
  720. <td>
  721. <p>UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW or W, S, A, and D</p>
  722. </td>
  723. <td>Right thumb stick</td>
  724. </tr>
  725. <tr>
  726. <td>Zoom</td>
  727. <td>Z and X</td>
  728. <td>Triggers</td>
  729. </tr>
  730. <tr>
  731. <td>Pause or resume light animation.</td>
  732. <td>SPACEBAR</td>
  733. <td>
  734. <b>A</b>
  735. </td>
  736. </tr>
  737. <tr>
  738. <td>Reset.</td>
  739. <td>R</td>
  740. <td>Right thumb stick press</td>
  741. </tr>
  742. <tr>
  743. <td>Exit.</td>
  744. <td>ESC or ALT+F4</td>
  745. <td>
  746. <b>BACK</b>
  747. </td>
  748. </tr>
  749. </table>
  750. </div>
  751. </div>
  752. <a id="ID2EBD" name="ID2EBD"> </a><h1 class="heading">How the Sample Works</h1><div id="ID2EBD" class="hxnx1">
  753. <p>
  754. The <b>NormalMappingModelProcessor</b> derives from the built-in <b>ModelProcessor</b>, and overrides the <b>ConvertMaterial</b> method to pass all the materials on the model through to the custom <b>NormalMappingMaterialProcessor</b>.
  755. </p>
  756. <p>
  757. Additionally, the processor performs preprocessing on the vertex channels in the scene.
  758. The processor overrides the <b>GenerateTangentFrames</b> property, forcing it to always return true. This causes the base
  759. <b>ModelProcessor</b> to generate tangent and binormal information for a mesh. The normal mapping technique depends
  760. on the presence of this data. The processor also overrides <b>ProcessVertexChannel</b> to remove vertex channels
  761. that the normal mapping vertex shader does not use. This optimization makes the run-time vertex buffers
  762. smaller and makes them draw more quickly.
  763. </p>
  764. <p>
  765. The last functionality that the processor provides is to determine the normal map texture to use in the effect.
  766. The value could be hard-coded in the processor—as NormalMap.tga, for example—but this would not be
  767. a very flexible approach. The processor would work only in extremely simple cases. Instead, the processor uses
  768. opaque data to determine the path to the texture. Opaque data, also known as blind data and custom attributes,
  769. is data that can be applied to a mesh in a digital content creation (DCC) tool. 3ds Max, Maya, and the FBX file format support opaque data. The FBX importer that ships with XNA Game Studio reads this data and
  770. puts it into an <b>OpaqueDataDictionary</b>, which is a
  771. map from names to objects.
  772. </p>
  773. <p>
  774. For this sample, the artist created the lizard and rock in Maya. Before exporting to FBX, a custom attribute
  775. was applied to all meshes in the scene. The custom attribute is named <b>NormalMap</b>, and its
  776. value is a string containing the path to the texture, such as lizard_norm.tga, or rock_norm.tga. The processor
  777. looks for this attribute in every mesh's <b>OpaqueData</b> property,
  778. and adds the texture file that is found to the collection of textures to be processed. This approach is preferable to
  779. hard coding the file name in the processor, because it works on any number of meshes in a scene, and it gives control to the artist.
  780. </p>
  781. <p>
  782. To accomplish this, the function <b>LookUpNormalMapAndAddToTextures</b> is used to recurse through the scene hierarchy.
  783. Whenever a <b>MeshContent</b> object is found, the processor looks in that mesh's opaque data to find the normal map.
  784. </p>
  785. <p>
  786. The processor also provides a parameter that the user can set in the UI to "override" for the opaque data.
  787. If a value is specified in the property grid for <b>NormalMapTexture</b>, that value will be used as the normal map
  788. for all meshes, overriding what is specified in the opaque data. This is useful when using content-creation tools
  789. that do not support opaque data. However, this approach forces every mesh in the entire scene to share one normal
  790. map.
  791. </p>
  792. <p>
  793. The <b>NormalMappingMaterialProcessor</b>, which is used by the <b>NormalMappingModelProcessor</b>, is much simpler. It extends from the built-in <b>MaterialProcessor</b>, and overrides <b>MaterialProcessor.BuildTexture</b> to control the processor that is used to build textures. Normal maps are sent through the custom <b>NormalMapTextureProcessor</b>. All other textures are built as normal.
  794. </p>
  795. <p>
  796. Finally, the <b>NormalMapTextureProcessor</b> is used to process normal map textures. It takes input textures that contain encoded normals with unsigned RGB values ranging from 0 to 1. The textures are converted to the <b>Graphics.PackedVector.NormalizedByte4</b> format, a signed format designed for use with normal maps.
  797. </p>
  798. <p>
  799. Note that the textures and effects are not added to the Game Studio project file. These will be built automatically because they are referenced by the <b>NormalMappingModelProcessor</b>, so there is no need for them to be duplicated in the project itself.
  800. </p>
  801. </div>
  802. <a id="ID2ERF" name="ID2ERF"> </a><h1 class="heading">
  803. Converting to XNA Game Studio 2.0
  804. </h1><div id="ID2ERF" class="hxnx1">
  805. <p>
  806. The most extensive changes to this sample will be in the content processors. Let us cover the quick, cosmetic changes first. In this
  807. version of the sample, we have modified the <b>NormalMappingModelProcessor</b> <b>ContentProcessorAttribute</b>, giving it a <i>DisplayName</i>. This will make it
  808. appear more nicely in the property grid.
  809. </p>
  810. <p>
  811. Next, in XNA Game Studio 2.0, processors can be made to not show up in the UI by using the <b>DesignTimeVisibleAttribute</b>. The
  812. <b>NormalMappingMaterialProcessor</b> and <b>NormalMappingTextureProcessor</b> are ideal candidates for invisiblility because it does not make sense to
  813. use these processors on their own. They are only helper processors used by the <b>NormalMappingModelProcessor</b>.
  814. </p>
  815. <p>
  816. The final changes revolve around the use of XNA Game Studio 2.0 processor parameters feature. In XNA Game Studio 2.0, content processors can expose parameters
  817. that change the way they build content. Using those parameters, you can tweak the way that each piece of content is built. For example, the Model
  818. Processor exposes a scale parameter that can be used to rescale a model without having to edit the source file itself. It is not only built-in
  819. processors that have this ability, user-defined processors can do this as well.
  820. </p>
  821. <p>
  822. In the first version of this sample, the file name of the normal map was taken from the opaque data on the model. This is a very flexible
  823. and powerful solution, but not all content creation tools support opaque data. This meant, unfortunately, that they could not create data that would be compatible with this sample.
  824. </p>
  825. <p>
  826. Now that we have processor parameters, however, the story is a little different! By giving our <b>NormalMappingModelProcessor</b> a parameter
  827. of type string, we can give the users of our processor a way to specify the normal map without using opaque data. This is not the ideal solution because it will force all meshes in the scene to share the same normal map; for some users this may be good enough.
  828. </p>
  829. <p>
  830. Defining a parameter on a processor is easy: simply create a property on the processor with a public getter and setter. We have defined one
  831. on <b>NormalMappingModelProcessor</b> called "NormalMapTexture." Additionally, we can use attributes to feed some more information about our parameter
  832. to the UI. Specifically, we use <b>System.ComponentModel.DisplayNameAttribute</b> to control the name of the property in the UI,
  833. <b>System.ComponentModel.DescriptionAttribute</b> to control the description, and <b>System.ComponentModel.DefaultValueAttribute</b> to control the default
  834. value. Note that the default value specified in this attribute is only a hint to the UI, and is not used when building the content.
  835. </p>
  836. <p>
  837. Once the parameter has been defined, it can be used in the property grid. When the asset is built and the processor's Process method
  838. is called, the property's setter will be invoked and will be set to the correct value.
  839. </p>
  840. <p>
  841. While we are working with processor parameters, let us discuss another change in the <b>NormalMappingModelProcessor</b>. This processor inherits
  842. from <b>ModelProcessor</b>, which has been updated in XNA Game Studio 2.0 to have several parameters, including the scale parameter mentioned earlier. One
  843. of these in particular is interesting to us: <b>GenerateTangentFrames</b>. Tangent frames are a necessary piece of data to implement normal
  844. mapping. In the original version of this sample, we generated this data using <b>MeshHelper.CalculateTangentFrames</b>. Now, the base <b>ModelProcessor</b>
  845. can do this for us! To tell it to do so, we will override its <b>GenerateTangentFrames</b> property. Because this data is required for normal mapping
  846. and should not be optional, we will have the getter always return true and the setter do nothing. Also, we will use
  847. <b>System.ComponentModel.BrowsableAttribute</b> to specify to the UI that this property should not be displayed.
  848. </p>
  849. <p>
  850. Because the base <b>ModelProcessor</b> is generating tangent frames for us, we no longer need to do so in <b>PreprocessSceneHierarchy</b>. Removing
  851. <b>CalculateTangentFrames</b> from <b>PreprocessSceneHierarchy</b> leaves it looking rather bare: its only job is to recursively peruse the scene
  852. <b>LookUpNormalMapAndAddToTextures</b>. Instead of doing this, we just make <b>LookUpNormalMapAndAddToTextures</b> a recursive function and
  853. remove <b>PreprocessSceneHierarchy</b> entirely. In the process, we update the function <b>LookUpNormalMapAndAddToTextures</b> to use the user's
  854. value for <b>NormalMapTexture</b>, if one is specified.
  855. </p>
  856. </div>
  857. </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: Normal Mapping Effect Sample">[email protected]</a>.</p></div></div></body></html>