1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"[]> 2<html xml:lang="en-US" lang="en-US"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <meta http-equiv="Content-Style-Type" content="text/css" /> 6 <link rel="stylesheet" href="../../css/document.css" type="text/css" /> 7 <title>Optimization Tips</title> 8 </head> 9 <body> 10 <h1 id="newlist2_0_0">Added and Revised Items in 2.0.0</h1> 11 <ul> 12 13 <!-- 2.0.0 で追加・修正された項目 --> 14 15 <!-- <GFX> --> 16 <!-- </GFX> --> 17 <!-- <ANIM> --> 18 <!-- </ANIM> --> 19 20 </ul> 21 <h1>CPU/GPU Optimization</h1> 22 <ul> 23 24 <!-- <GFX> --> 25 26 <li><a href="#document">Reading the Optimization Document</a></li> 27 <li><a href="#option">Enabling Optimization Options</a></li> 28 <li><a href="#vram">Loading Vertex data and Textures in VRAM</a></li> 29 <li><a href="#doublecmdlist">Duplicating Command Lists</a></li> 30 <li><a href="#glclear">Avoiding Calls to <CODE>glClear</CODE></a></li> 31 <li><a href="#share_same_shaders">Sharing the Same Shaders</a></li> 32 33 <!-- </GFX> --> 34 35 </ul> 36 <h1>CPU Optimization</h1> 37 <ul> 38 39 <!-- <GFX> --> 40 <li><a href="#material_id">Calculating Material IDs</a></li> 41 <li><a href="#customrendersort">Customizing Sort Algorithms for the Render Queue</a></li> 42 <li><a href="#optimizerenderkey">Optimizing Render Queue Key Creation</a></li> 43 <li><a href="#shared_skeleton">Sharing Skeletons</a></li> 44 <li><a href="#shared_material">Sharing Materials</a></li> 45 <li><a href="#traverse">Executing Traverses Only when the Scene Tree Structure Changes</a></li> 46 <li><a href="#skip_update">Partially Omitting Traverses and Updates</a></li> 47 <li><a href="#savedcmdlist">Reusing Command Lists when Displaying in 3D</a></li> 48 <li><a href="#build_option">Disabling Features Not Required by the Build Options</a></li> 49 <li><a href="#optimaize_resource_setup">Optimizing Resource Setup (VRAM Transfers)</a></li> 50 <li><a href="#optimaize_scene_object_creation">Speeding Up the Creation of Scene Objects</a></li> 51 <!-- </GFX> --> 52 53 <!-- <ANIM> --> 54 <li><a href="#frame_format">Using Frame-Format Animation Data</a></li> 55 <li><a href="#full_baked">Using Fully-Baked Format Animation Data</a></li> 56 <li><a href="#change_anim">Reusing <CODE>AnimEvaluator</CODE> when Switching Animations</a></li> 57 <li><a href="#anim_cache">Using Animation Caches Appropriately</a></li> 58 <li><a href="#delete_anim_member">Deleting Unnecessary Animation Members</a></li> 59 <li><a href="#delete_anim_member_auto">Automatically Deleting Unnecessary Animation Members</a></li> 60 <li><a href="#disable_anim">Disabling <CODE>AnimBinding</CODE> for Unanimated Nodes</a></li> 61 <li><a href="#remove_useless_anim">Deleting Alpha Value Animations Unused by Standard Features</a></li> 62 <!-- </ANIM> --> 63 64 </ul> 65 <h1>Vertex Process Optimization</h1> 66 <ul> 67 68 <!-- <GFX> --> 69 <li><a href="#shader_program">Selecting a Shader Program According to the Number of Textures</a></li> 70 <li><a href="#light_off">Turning Off Unnecessary Lights</a></li> 71 <li><a href="#light_write">Baking Lights to Vertex Colors</a></li> 72 <li><a href="#user_shader">Using User Shaders</a></li> 73 <!-- </GFX> --> 74 75 </ul> 76 <hr /> 77 78 <!-- <GFX> --> 79 <h2 id="document">Reading the Optimization Document</h2> 80 <div class="section"> 81 Read the optimization document included with the SDK.<br /> Note that these optimization tips are not contained in the SDK documentation.<br /> 82 </div> 83 <h2 id="option">Enabling Optimization Options</h2> 84 <div class="section"> 85 Enable the optimization options of the export plug-in.<br /> In some cases, this may have a significant effect on performance. 86 </div> 87 <h2 id="vram">Loading Vertex data and Textures in VRAM</h2> 88 <div class="section"> 89 Load vertex data and textures in VRAM.<br /> As shown below, transfer reservations can be made when initializing resources by configuring memory locations at the graphics file level. 90 <p class="info"> 91 <CODE>ResGraphicsFile::ForeachTexture(nw::gfx::TextureLocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));<br /> ResGraphicsFile::ForeachIndexStream(nw::gfx::IndexStreamLocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));<br /> ResGraphicsFile::ForeachVertexStream(nw::gfx::VertexStreamLocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));<br /></CODE> 92 </p> 93 </div> 94 <h2 id="doublecmdlist">Duplicating Command Lists</h2> 95 <div class="section"> 96 Duplicate command lists to allow for simultaneous command generation and execution. However, you might get display tearing if buffers are not swapped correctly, as transfers from the render buffer to the display buffer are also accumulated as commands.<br /> In the demo library, the <a href="../../nw/demo/CommandListSwapper/Overview.html"><CODE>CommandListSwapper</CODE></a> class duplicates command lists. 97 </div> 98 <h2 id="glclear">Avoiding Calls to <CODE>glClear</CODE></h2> 99 <div class="section"> 100 The <CODE>glClear</CODE> function affects calculations and other processes because it generates CPU interrupts even if the <CODE>RenderBuffer</CODE> is located in VRAM.<br /> If possible, render starting from the most distant on-screen items in order clear the screen without calling <CODE>glClear</CODE>.<br /> You can do this in NW4C by configuring the mesh materials of the most distant display items as follows.<br /> 101 <ul> 102 <li>Depth test: Always pass (Always)</li> 103 <li>Color depth buffer: Update </li> 104 <li>Use layer IDs and render priorities to render the most distant model first.</li> 105 </ul> 106 Also set <CODE>LayerId</CODE> for <CODE>SubmitView</CODE> to prioritize rendering of the celestial sphere, as done in the <CODE>gfx</CODE> demo. Whichever approach you take, the most distant model must lie between the near and far clipping planes. 107 </div> 108 <h2 id="shared_skeleton">Sharing Skeletons</h2> 109 <div class="section"> 110 When creating characters that share motions, share skeletons between the characters to reduce the number calculations required.<br /> For details on sharing skeletons, see <a href="./Coordinate.html#shared_skeleton">Sharing Skeletons</a>. 111 </div> 112 <h2 id="shared_material">Sharing Materials</h2> 113 <div class="section"> 114 When creating models that use the same materials, share materials between the models to omit redundant material setup.<BR> To share a material, configure the source model to be shared in a <a href="../../nw/gfx/SceneBuilder/SharedMaterialModel.html"><CODE>SharedMaterialModel</CODE></a> object. When destroying objects that use shared materials, you must first destroy all models using the shared materials before destroying the shared model itself. 115 </div> 116 <h2 id="traverse">Executing Traverses and Initializing Only when the Scene Tree Structure Changes</h2> 117 <div class="section"> 118 Only execute a traverse or initialize when the tree structure has changed, such as when a child has been added to or removed from the <CODE>SceneNode</CODE>, by calling <a href="../../nw/gfx/SceneTraverser/Overview.html"><CODE>SceneTraverser</CODE></a> or <a href="../../nw/gfx/SceneInitializer/Overview.html"><CODE>SceneInitializer</CODE></a> respectively on a <a href="../../nw/gfx/SceneNode/Accept.html"><CODE>SceneNode::Accept</CODE></a> object. You do not need to do this again when the <CODE>Visible</CODE> property changes. 119 </div> 120 <h2 id="skip_update">Partially Omitting Traverses and Updates</h2> 121 <div class="section"> 122 If you want to omit running <a href="../../nw/gfx/SceneUpdater/UpdateAll.html"><CODE>SceneUpdater::UpdateAll</CODE></a> or traverses for a particular node, prepare multiple instances of the <a href="../../nw/gfx/SceneContext/Overview.html"><CODE>SceneContext</CODE></a> class to allow you to skip some traverse and update processing. For example, you can collect traverse results for each individual <a href="../../nw/gfx/SceneContext/Overview.html"><CODE>SceneContext</CODE></a> by separating the group of nodes you want to update and the ones you don't into separate branches, and then traverse only some of the branches. Alternately, split them into separate scene trees and then traverse only some of the trees. Reduce the processing load by skipping traverses and updates for <a href="../../nw/gfx/SceneContext/Overview.html"><CODE>SceneContext</CODE></a> instances that are collections of nodes whose status does not change. Use functions such as <a href="../../nw/gfx/SceneUpdater/SubmitView.html"><CODE>SceneUpdater::SubmitView</CODE></a> or <a href="../../nw/gfx/BasicRenderQueue/EnqueueModel.html"><CODE>RenderQueue::EnqueueModel</CODE></a> to place multiple instances of <a href="../../nw/gfx/SceneContext/Overview.html"><CODE>SceneContext</CODE></a> in a single <a href="../../nw/gfx/RenderQueue.html"><CODE>RenderQueue</CODE></a>. 123 </div> 124 <h2 id="material_id">Calculating Material IDs</h2> 125 <div class="section"> 126 The default sorting algorithm sorts materials using the material IDs. Use the <a href="../../nw/gfx/IMaterialIdGenerator/Overview.html"><CODE>IMaterialIdGenerator</CODE></a> function to calculate material IDs. Set the material IDs of materials with the same or similar settings to values that are close to each other in order to reduce the CPU load during rendering. To calculate material IDs, pass a <CODE>IMaterialIdGenerator</CODE> instance to the <a href="../../nw/gfx/SceneInitializer/Overview.html"><CODE>SceneInitializer</CODE></a> function, and then call, in order, the <a href="../../nw/gfx/SceneInitializer/Begin.html"><CODE>SceneInitializer::Begin</CODE></a>, <a href="../../nw/gfx/SceneNode/Accept.html"><CODE>SceneNode::Accept</CODE></a>, and <a href="../../nw/gfx/SceneInitializer/End.html"><CODE>SceneInitializer::End</CODE></a> functions. You can customize the material ID generator algorithm by inheriting from the <CODE>IMaterialIdGenerator</CODE> class. Refer to <a href="../../nw/gfx/SortingMaterialIdGenerator/Overview.html"><CODE>SortingMaterialIdGenerator</CODE></a> when implementing your customized algorithm. 127 </div> 128 <h2 id="customrendersort">Customizing Sort Algorithms for the Render Queue</h2> 129 <div class="section"> 130 Customize the sort algorithm by customizing <a href="../../nw/gfx/RenderElementCompare/Overview.html"><CODE>RenderElementCompare</CODE></a> and <a href="../../nw/gfx/BasicRenderKeyFactory/Overview.html"><CODE>BasicRenderKeyFactory</CODE></a>. 131 </div> 132 <h2 id="optimizerenderkey">Optimizing Render Queue Key Creation</h2> 133 <div class="section"> 134 If you do not need to sort by depth, such as when using non-translucent meshes, you can omit depth-related calculations when generating keys or when caching key generation results. Skip these calculations by using the <a href="../../nw/gfx/ISceneUpdater/SetDepthSortMode.html"><CODE>ISceneUpdater::SetDepthSortMode</CODE></a> function to set <CODE>SORT_DEPTH_OF_TRANSLUCENT_MESH</CODE> for depth-related calculations and then using the key factory created by <a href="../../nw/gfx/CreatePriorMaterialAndZeroDepthRenderKeyFactory.html"><CODE>CreatePriorMaterialAndZeroDepthRenderKeyFactory</CODE></a>. Enable the key cache by passing <CODE>true</CODE> in the <SPAN class="argument">cacheEnabled</SPAN> argument to the <a href="../../nw/gfx/BasicRenderQueue/Reset.html"><CODE>RenderQueue::Reset</CODE></a> function. Disable the caching of sort keys saved for each mesh by calling <a href="../../nw/gfx/Model/InvalidateRenderKeyCache.html"><CODE>InvalidateRenderKeyCache</CODE></a>. You can also disable sort key caching on a per mesh basis by using the <CODE>ResMesh::SetFlags</CODE> function directly to set the <CODE>ResMesh::FLAG_VALID_RENDER_KEY_CACHE</CODE> flag to <CODE>0</CODE>. 135 </div> 136 <h2 id="savedcmdlist">Reusing Command Lists when Displaying in 3D</h2> 137 <div class="section"> 138 When displaying in 3D, you can cut down on command generation by generating one command list and re-using it for both left and right eyes, instead of generating a separate command list for the left and right eyes. The demo library renders 3D displays using the <a href="../../nw/demo/RenderSystem/RenderStereoScene.html"><CODE>RenderStereoScene</CODE></a> function, which uses the <a href="../../nw/demo/CommandListSwapper/Overview.html"><CODE>CommandListSwapper</CODE></a> class to save and reuse the command list. For the process flow, see <a href="./AdvancedFeature.html#stereo">Normal Rendering and Stereoscopic Rendering</a>. 139 </div> 140 <h2 id="build_option">Disabling Features Not Required by the Build Options</h2> 141 <div class="section"> 142 You can skip unnecessary determination and other processing by using the build options to disable unneeded features. For details, see <a href="./../macros.html">Macro List</a> 143 </div> 144 145 <h2 id="share_same_shaders">Sharing the Same Shaders</h2> 146 <div class="section"> 147 <p> 148 Load shared shaders ahead of time from the binary files. 149 </p> 150 <p> 151 Use <a href="../../nw/gfx/res/ResGraphicsFile/Setup.html"><CODE>nw::gfx::ResGraphicsFile::Setup</CODE></a> or a similar function to set up the models and other binary file resources. In such cases as when the function call returns <CODE>nw::gfx::RESOURCE_RESULT_NOT_FOUND_SHADER</CODE>, you can share a single shader by setting up the binary resource for the loaded shader again. 152 </p> 153 <p> 154 See <a href="demo/ResourceDemo.html"><CODE>ResourceDemo</CODE></a> for specific examples. 155 </p> 156 </div> 157 158 <h2 id="optimaize_resource_setup">Optimizing Resource Setup (VRAM Transfers)</h2> 159 <div class="section"> 160 <p> 161 See <a href="BinaryResource.html#transfer_vram">Users Handling VRAM Transfers</a>. 162 </p> 163 </div> 164 165 <h2 id="optimaize_scene_object_creation">Speeding Up the Creation of Scene Objects</h2> 166 <div class="section"> 167 <p> 168 Call <a href="../../nw/gfx/SceneBuilder/GetMemorySize.html"><CODE>nw::gfx::SceneBuilder::GetMemorySize</CODE></a> or a similar function to calculate the amount of memory required to create objects, and then allocate all the required memory at once to speed up object creation. 169 </p> 170 <p> 171 Manage such memory by using an allocator class that inherits from <a href="../../nw/os/IAllocator/Overview.html"><CODE>os::IAllocator</CODE></a> (herein called a "suballocator"). Configure the created suballocator as an allocator for creating objects. 172 </p> 173 <p> 174 For speedier object creation, use classes such as the SDK's <CODE>FrameHeap</CODE> class when implementing your suballocator. 175 </p> 176 </div> 177 178 <!-- </GFX> --> 179 180 <!-- <ANIM> --> 181 <h2 id="frame_format">Using Frame-Format Animation Data</h2> 182 <div class="section"> 183 <p> 184 Use frame-format animation data to reduce the processing load of evaluating animations. Only skeletal animations can currently be output in frame format. 185 </p> 186 <p> 187 The drawback to frame format is larger data sizes. The accuracy of evaluating fractional frames also declines when the playback speed is changed. 188 </p> 189 </div> 190 191 <h2 id="full_baked">Using Fully-Baked Format Animation Data</h2> 192 <div class="section"> 193 <p> 194 Use fully baked animation data to reduce the processor load for skeletal animation evaluation compared to frame format. 195 </p> 196 <p> 197 See <a href="anim/AdvancedFeature.html#full_baked">Advanced Features</a> for details on usage and disadvantages. 198 </p> 199 </div> 200 201 <h2 id="change_anim">Reusing <CODE>AnimEvaluator</CODE> when Switching Animations</h2> 202 <div class="section"> 203 <p> 204 Use <a href="../../nw/gfx/AnimEvaluator/ChangeAnim.html"><CODE>ChangeAnim</CODE></a> when switching animations for a single model. 205 </p> 206 <p> 207 This is faster than re-creating an <a href="../../nw/gfx/AnimEvaluator/Overview.html"><CODE>AnimEvaluator</CODE></a> instance and then executing <a href="../../nw/gfx/AnimEvaluator/Bind.html"><CODE>Bind</CODE></a> again. 208 </p> 209 </div> 210 211 <h2 id="anim_cache">Using Animation Caches Appropriately</h2> 212 <div class="section"> 213 <p> 214 Using an evaluation result cache is a fast approach when applying animation results to more than one model. Meanwhile, this also increases the overhead if enabled when the cache is not needed. For more details, see <a href="anim/AdvancedFeature.html#anim_cache">Advanced Features</a>. 215 </p> 216 </div> 217 218 <h2 id="delete_anim_member">Deleting Unnecessary Animation Members</h2> 219 <div class="section"> 220 <p> 221 You can delete animation members when exporting models and other data from CreativeStudio to binary format. Delete any unnecessary animation members to speed up animation evaluation and blends in particular. Be careful not to delete any necessary animation members. 222 </p> 223 <p> 224 The following examples show a filter definition file and a script file for binary output of a model where only material constant colors <CODE>0</CODE> and <CODE>1</CODE> can be animated. 225 </p> 226 <h3>OptimizeFilter.xml</h3> 227 <pre> 228<?xml version="1.0" encoding="utf-8"?> 229<OptimizeAnimationMemberSettings> 230 </span><Filters Mode="positive"> 231 </span><Path>Materials["*"].MaterialColor.Constant0</Path> 232 </span><Path>Materials["*"].MaterialColor.Constant1</Path> 233 </span></Filters> 234</OptimizeAnimationMemberSettings></pre> 235 <h3>Binarize.py</h3> 236 <p> 237 You must save the script file encoded in UTF-16 with BOM. 238 </p> 239 <pre> 240CreativeStudio.Execute("FileLoad", "human.cmdl") 241CreativeStudio.Execute("FileLoad", "human_all.ctex") 242CreativeStudio.Execute("OptimizeAnimationMember", "-sf=OptimizeFilter.xml") 243CreativeStudio.Execute("FileSave", "-o=human.bcres", "-t=nw4cBinary")</pre> 244 <p> 245 Run a command similar to the following in the CreativeStudio console to output to binary. 246 </p> 247 <pre>NW4C_CreativeStudioConsole.exe -s=Binarize.py</pre> 248 <p> 249 The following definition file example shows the opposite scenario, where instead of only keeping the specified members, we only delete the specified members. Note here that the <CODE>Mode</CODE> attribute of the <CODE>Filters</CODE> member is set to <CODE>negative</CODE>. 250 </p> 251 <pre> 252<?xml version="1.0" encoding="utf-8"?> 253<OptimizeAnimationMemberSettings> 254 </span><Filters Mode="negative"> 255 </span><Path>IsVisible</Path> 256 </span><Path>Meshes["*"].IsVisible</Path> 257 </span><Path>MeshNodeVisibilities["*"].IsVisible</Path> 258 </span></Filters> 259</OptimizeAnimationMemberSettings></pre> 260 <p> 261 The <CODE>reset</CODE> value for the <CODE>Mode</CODE> attribute is new starting from version 1.2.0. Although the binary export works basically the same for both <CODE>positive</CODE> or <CODE>reset</CODE>, specifying <CODE>reset</CODE> will re-enable the specified members if they have already been deleted and disabled. 262 </p> 263 <p> 264 The example here uses a script file, but you can also run a binary export from the console panel. 265 </p> 266 </div> 267 268 <h2 id="delete_anim_member_auto">Automatically Deleting Unnecessary Animation Members</h2> 269 <div class="section"> 270 <p> 271 CreativeStudio version 1.2.0 and later include an operation to extract necessary members from animation data while also automatically deleting unnecessary members. The following example shows the main way of using this feature. Note that this example also outputs an intermediate file containing information about which members were deleted (disabled). As of version 1.2.0, you cannot check from within CreativeStudio whether a member is enabled or disabled. 272 </p> 273 <h3>Optimizing Loaded Content</h3> 274 <ol> 275 <li>Load all objects and animations to optimize.</li> 276 <li>Select the objects to optimize. If no selection is made, all objects will be optimized.</li> 277 <li>Enter and execute the following command on the console panel. 278 <pre>CreativeStudio.Execute("OptimizeUnusedAnimationMember")</pre> 279 </li> 280 <li>This will optimize the relevant items and display the results on the console panel.</li> 281 </ol> 282 <h3>Creating a Definition File</h3> 283 <ol> 284 <li>Load all animations to optimize.</li> 285 <li>Note that all animations will be optimized regardless of the selection you make.</li> 286 <li>Enter and execute the following command on the console panel. 287 <pre>CreativeStudio.Execute("OptimizeUnusedAnimationMember")</pre> 288 or 289 <pre>CreativeStudio.Execute("OptimizeUnusedAnimationMember", "-sf=[definition_file_name]")</pre> 290 </li> 291 <li>This saves a definition file.</li> 292 <li>Close all animations and load the objects to optimize.</li> 293 <li>Select the objects to optimize. If no selection is made, all objects will be optimized.</li> 294 <li>Enter and execute the following command on the console panel. 295 <pre>CreativeStudio.Execute("OptimizeAnimationMember")</pre> 296 or 297 <pre>CreativeStudio.Execute("OptimizeAnimationMember", "-sf=[definition_file_name]")</pre> 298 </li> 299 <li>This will optimize the relevant items and display the results on the console panel.</li> 300 </ol> 301 <p> 302 You can also use the definition file created by this procedure from a script file, as described in <a href="#delete_anim_member">Deleting Unnecessary Animation Members</a>. 303 </p> 304 </div> 305 306 <h2 id="disable_anim">Disabling <CODE>AnimBinding</CODE> for Unanimated Nodes</h2> 307 <div class="section"> 308 <p> 309 If you know at time of creation that a model will not be animated, you can create nodes with animation disabled. This avoids unnecessary processing during scene updates. 310 </p> 311 <p> 312 For details, see <a href="../../nw/gfx/SceneBuilder/IsAnimationEnabled.html"><CODE>SceneBuilder::IsAnimationEnabled</CODE></a>. 313 </p> 314 </div> 315 316 <h2 id="remove_useless_anim">Deleting Alpha Value Animations Unused by Standard Features</h2> 317 <div class="section"> 318 <p> 319 Deleting the following material animations unused by standard features can reduce memory sizes and improve runtime efficiency. 320 <ul> 321 <li>Emission alpha colors</li> 322 <li>Specular 0,1 alpha values</li> 323 </ul> 324 You can also automatically delete these items, similar to the script shown in <a href="#delete_anim_member">Deleting Unnecessary Animation Members</a>. 325 <pre> 326CreativeStudio.Execute("FileLoad", "human.cmata") 327<font color="blue">CreativeStudio.Execute("RemoveUselessAlphaAnimation")</font> 328CreativeStudio.Execute("FileSave", "-o=human.bcres", "-t=nw4cBinary")</pre> 329 </p> 330 </div> 331 332 <!-- </ANIM> --> 333 334 <!-- <GFX> --> 335 <h2 id="shader_program">Selecting a Shader Program According to the Number of Textures</h2> 336 <div class="section"> 337 When using the default shader, you can select a shader program according to the number of textures.<br /> Configure this automatic shader program selection as follows.<br /> 338 <p class="info"> 339 ResGraphicsFile::ForeachModelMaterial(nw::gfx::DefaultShaderAutoSelector()); 340 </p> 341 </div> 342 <h2 id="light_off">Turning Off Unnecessary Lights</h2> 343 <div class="section"> 344 When not using fragment lights, disable material fragment lighting settings instead of just turning out lights. Also disable settings for vertex and hemispherical lights. You can skip quaternion calculation by the vertex shader by disabling fragment lighting. Normals are not included in exports from CreativeStudio when all lights are disabled. 345 </div> 346 <h2 id="light_write">Baking Lights to Vertex Colors</h2> 347 <div class="section"> 348 If vertex processing is the bottleneck, bake vertex lights to the vertex color. If fill is the bottleneck, bake fragment lights to the vertex color. This should improve both vertex and fill processing. 349 </div> 350 <h2 id="user_shader">Using User Shaders</h2> 351 <div class="section"> 352 When rendering models with an extremely large number of vertices, use a custom shader to improve processing. However, changing shaders increases the CPU load, so you must make offsetting adjustments to keep the CPU load from increasing, such as applying the custom shader to the background model only and using render priority to render that first. For information on user-defined shaders, see <a href="UserShader.html">Creating Shaders</a>. 353 </div> 354 <!-- </GFX> --> 355 <hr><p>CONFIDENTIAL</p></body> 356</html>