Computer Graphics

Chapter 12
GPU Architecture and Real-Time Graphics

Post Graduate Program in Computer Science Engineering
Computer Graphics   •   Post Graduate

12. GPU Architecture and Real-Time Graphics

Introduction and Context

Real-time computer graphics is the discipline of generating images within a strict time budget. A rendered frame is useful only when it is produced quickly enough to support interactive input, animation, simulation, or display refresh. At 60 Hz, a system has approximately 16.67 milliseconds per frame; at 120 Hz, the budget falls to approximately 8.33 milliseconds. This constraint makes real-time graphics fundamentally different from offline rendering, where an image may be computed for minutes or hours.

The modern graphics processing unit (GPU) is a highly parallel processor designed to execute large numbers of similar operations on streams of data. Its effectiveness arises not merely from having many arithmetic units, but from a complete architecture involving command processing, programmable shader stages, memory hierarchies, rasterization, texture sampling, synchronization, and specialized fixed-function hardware. Understanding these relationships is essential for designing efficient rendering pipelines.

This chapter examines programmable GPU architecture and the methods used to construct and optimize real-time graphics systems. It connects shader programming with parallel execution, memory behavior, rendering architecture, level-of-detail selection, profiling, and the quality–latency–energy trade-off. The discussion assumes familiarity with transformations, lighting, rasterization, and basic graphics APIs.

Learning Objectives

After studying this chapter, the student should be able to:

1. Explain the organization and execution model of a contemporary programmable GPU.

2. Distinguish graphics-pipeline stages from compute-oriented execution.

3. Design shader-based rendering techniques using appropriate data and synchronization models.

4. Compare forward, deferred, and hybrid rendering architectures.

5. Apply profiling methods to identify CPU, GPU, memory, and synchronization bottlenecks.

6. Select level-of-detail and culling strategies for large interactive scenes.

7. Evaluate rendering decisions in terms of image quality, latency, throughput, and energy.

8. Discuss professional, ethical, and emerging issues in GPU-based visual computing.

From Graphics Commands to Parallel Execution

A GPU does not normally decide what to render. The CPU-side application constructs command buffers containing operations such as binding resources, selecting shaders, setting constants, and issuing draw or dispatch commands. A driver and graphics API translate these commands into a form understood by the GPU. The GPU then schedules work across its execution resources.

A contemporary GPU is usually composed of several classes of hardware. A command processor receives and interprets work. Multiple compute units, streaming multiprocessors, or similar execution clusters perform arithmetic and logical operations. Rasterization hardware converts triangles into fragments, while texture units perform filtered accesses to images and samplers. Output or render-backend hardware performs depth and stencil tests, blending, and storage of final pixels. A hierarchy of caches and device memory supplies data to these units.

The terminology differs among vendors, but the architectural principles are similar. A GPU contains many lightweight execution lanes and is optimized for throughput rather than the low-latency execution of one sequential thread. It hides memory latency by maintaining many active groups of work. If one group waits for a memory access, another can occupy the execution units.

The SIMT Execution Model

Most programmable GPUs use an execution model commonly described as single instruction, multiple threads (SIMT). A shader invocation appears to the programmer as an independent thread, but hardware groups invocations into warps, wavefronts, or equivalent units. Threads in a group generally execute the same instruction together. When threads follow different branches, the hardware may execute each branch path separately and mask inactive lanes. This phenomenon is called control-flow divergence.

Divergence is not always harmful. A short conditional with balanced paths may have little practical cost, whereas a branch that causes half of a large group to remain inactive can substantially reduce utilization. Data-dependent loops, irregular ray traversal, and heterogeneous material programs require particular care. Shader specialization, coherent data layout, and sorting objects by material can reduce divergence.

The unit of synchronization is important. A barrier that is valid within a workgroup does not necessarily synchronize all workgroups. Similarly, memory visibility and execution completion are distinct concerns. A program may need both a barrier to order execution and a memory barrier to ensure that writes become visible to later operations.

Memory Hierarchy and Locality

GPU performance is often limited by data movement rather than arithmetic. Device memory provides large capacity but relatively high latency. Caches are smaller and faster, and programmer-managed shared or local memory can provide efficient communication among threads in a workgroup. Registers are the fastest storage available to an invocation, but excessive register use can reduce the number of simultaneously resident groups.

Two forms of locality are especially important. Spatial locality means that nearby threads access nearby memory addresses, enabling efficient transactions and cache-line use. Temporal locality means that data reused soon after its first access remains available in a cache or local store. Vertex buffers arranged for sequential access, coherent texture coordinates, and compact material records generally improve locality.

Memory layout also affects bandwidth. An array-of-structures layout is convenient when a complete object is consumed together; a structure-of-arrays layout can be more efficient when a kernel processes one attribute across many objects. Alignment, padding, compression, and resource residency must be considered in large scenes. A mathematically simple shader may perform poorly if it repeatedly fetches scattered data.

The Programmable Rendering Pipeline

The traditional pipeline is a sequence of conceptual stages, although modern GPUs may execute and overlap them internally. Vertex processing transforms object-space positions into clip space and computes per-vertex attributes. Primitive assembly forms points, lines, or triangles. Clipping removes portions outside the viewing volume, and rasterization determines which sample locations are covered by each primitive. Fragment or pixel shading evaluates material and lighting equations. Tests and blending determine whether and how the result contributes to the framebuffer.

The vertex shader is responsible for transformations and often for preparing normals, texture coordinates, tangents, and other attributes. A typical transformation is represented by

p_clip = P V M p_object,

where M is the model transformation, V is the view transformation, and P is the projection transformation. Correct coordinate-space conventions are essential because lighting and visibility calculations may occur in object, world, view, tangent, or screen space.

The fragment shader operates on interpolated values and usually performs texture sampling, normal mapping, lighting, material evaluation, and output generation. Interpolation is perspective-correct by default for many attributes, but some quantities may require flat or explicitly controlled interpolation. Early depth testing can reject hidden fragments before expensive shading, but certain shader operations, such as depth modification or some forms of discard, may prevent early rejection.

Modern APIs also expose tessellation and geometry stages, although their use must be justified by workload characteristics. Tessellation can generate view-dependent detail, while geometry shaders can amplify or modify primitives. Both may introduce bottlenecks if they create excessive primitive counts or limit parallel efficiency.

Compute shaders generalize GPU programming beyond rasterization. They operate on explicitly defined workgroups and can implement particle systems, image filters, light culling, animation, simulation, post-processing, and acceleration-structure construction. A compute dispatch usually specifies a three-dimensional grid of workgroups. Within a workgroup, invocations can cooperate through shared memory and barriers. Between dispatches, ordering is established through API commands and resource barriers.

Shader Design as Parallel Algorithm Design

A shader is not merely a small program attached to a graphical object. It is a parallel algorithm whose cost depends on invocation count, instruction complexity, memory behavior, register pressure, and divergence. The same fragment shader may be inexpensive for a small object but dominant when applied to millions of visible fragments.

A useful design process begins by identifying the dominant data dimension. Vertex-heavy work suggests reducing vertex count, improving vertex reuse, or simplifying vertex processing. Fragment-heavy work suggests reducing overdraw, lowering shading cost, improving early depth rejection, or using a lower-resolution intermediate buffer. Compute-heavy work may benefit from tiling, shared-memory reuse, and workgroup-size experimentation.

Uniform or constant data, such as camera matrices and exposure values, should be separated from frequently changing per-object data. Resource binding systems often group resources according to update frequency. Material textures and samplers may be shared across many draws, while object transforms change every object. This organization reduces CPU overhead and improves cache behavior.

A shader should also define numerical behavior carefully. Floating-point precision, especially in world-space coordinates far from the origin, can produce visible jitter. Half-precision or lower precision may save bandwidth and energy where error tolerance permits, but it should not be used indiscriminately in transformations, depth calculations, or temporal accumulation. Robust shader design balances precision with cost.

Choosing a Rendering Architecture

Forward Rendering

In forward rendering, each visible object is shaded while its fragments are generated. The method is conceptually direct and often efficient for scenes with few lights, transparent materials, or strong use of multisampling. However, if many lights affect many objects, the same lighting information may be evaluated repeatedly for different fragments.

Forward-plus or tiled forward rendering improves scalability by dividing the screen or view frustum into tiles or clusters. A compute pass determines which lights influence each tile, and the forward shader evaluates only that local list. This approach preserves many advantages of forward shading while reducing unnecessary light tests.

Deferred Rendering

Deferred rendering separates visibility from lighting. The geometry pass writes a set of screen-space buffers, commonly called a G-buffer, containing data such as depth, normals, albedo, material parameters, and motion vectors. A later lighting pass reads these buffers and computes illumination for visible pixels.

The principal advantage is that lighting is decoupled from geometric complexity. Multiple lights can be processed over the screen without repeatedly transforming and rasterizing every object. The costs are substantial bandwidth, storage, and management of G-buffer formats. Transparency, hair, particles, and multisample rendering do not fit naturally into a basic deferred architecture.

Hybrid and Modern Approaches

Practical engines frequently combine methods. Opaque geometry may use deferred shading, while transparent objects use forward shading. Decals, volumetric effects, screen-space reflections, and post-processing may use compute passes. Clustered lighting, virtualized geometry, and selective ray tracing can coexist with rasterization.

The choice should be based on measured workload rather than fashion. Important variables include the number and type of lights, screen resolution, material diversity, transparency, bandwidth, target hardware, and latency requirements.

Visibility, Level of Detail, and Work Reduction

The cheapest operation is one that is never executed. Visibility algorithms therefore have a central role in real-time graphics. Frustum culling rejects objects outside the camera volume. Back-face culling rejects triangles whose orientation indicates that they face away from the camera. Occlusion culling attempts to reject objects hidden behind nearer geometry. Hierarchical bounding volumes allow large groups of objects to be tested before individual geometry.

Level of detail (LOD) replaces an object with a representation appropriate to its projected importance. A distant building may use a simplified mesh and lower-resolution textures; an object occupying many pixels may require detailed geometry and material features. Screen-space error is a useful basis for selection because it relates representation error to visible image size.

Continuous LOD methods modify geometry gradually, reducing visible popping. Geomorphing blends between representations, while screen-space or cluster-based systems select groups of triangles according to projected error. LOD must also account for animation, silhouettes, shadows, reflections, and temporal stability. A mesh that appears acceptable in the main view may still produce noticeable errors in a shadow map.

Texture streaming is a related resource-management problem. Only the mip levels required by current views should be resident at full quality. Anisotropic filtering improves oblique texture quality but consumes bandwidth. Virtual texturing can manage very large texture spaces by loading visible pages on demand, although page faults and feedback latency must be controlled.

Performance Engineering and Profiling

Optimization without measurement is unreliable. A frame-time budget should first be divided among simulation, visibility, command submission, geometry, shading, post-processing, presentation, and synchronization. Profilers then determine which category actually consumes time.

GPU occupancy indicates how effectively execution resources are populated, but high occupancy alone does not guarantee high performance. A kernel may have high occupancy and still be limited by memory bandwidth, instruction latency, atomic contention, or divergence. Conversely, lower occupancy may be acceptable when each invocation has strong locality and substantial register use.

Common diagnostic experiments include reducing resolution, disabling shadows, replacing materials with a constant shader, reducing object count, and varying the number of lights. If frame time changes strongly with resolution, fragment or post-processing work is likely important. If it changes with object count but not resolution, CPU submission, vertex processing, or visibility may dominate. If neither changes, synchronization or a fixed-cost pass may be responsible.

GPU timestamps measure intervals on the GPU timeline, whereas CPU timers measure application-side behavior. Both are necessary. Pipeline bubbles may occur when the CPU waits for the GPU, when the GPU waits for resource availability, or when barriers prevent overlap. Excessive synchronization reduces parallelism and increases latency.

Frame pacing matters as much as average frame rate. A system producing 60 frames per second with periodic 40-millisecond spikes feels worse than one with stable 17-millisecond frames. Double or triple buffering, queue depth, asynchronous compute, and presentation mode influence latency and smoothness. More buffering can improve throughput but may increase input-to-photon delay.

Quality, Latency, and Energy as a Design Problem

Real-time graphics involves competing objectives. Higher resolution, complex shadows, volumetric effects, and accurate reflections improve visual quality but increase work. Lower quality can reduce latency and energy consumption, but excessive reduction harms usability and visual credibility.

The trade-off is not simply a choice between beautiful and fast images. Temporal reconstruction can produce high apparent resolution from lower-resolution rendering, but it may introduce ghosting, disocclusion errors, or instability. Dynamic resolution scaling adjusts rendering resolution to maintain a frame-time target. Foveated rendering allocates more samples to the viewer’s fixation region, particularly in head-mounted displays, but depends on reliable gaze information and acceptable peripheral degradation.

Energy is an engineering and environmental concern. A mobile or embedded system may be thermally constrained even when its instantaneous frame rate appears adequate. Bandwidth reduction, shader simplification, compressed resources, reduced overdraw, and adaptive quality can lower energy use. In a professional production environment, quality settings should be specified with measurable targets such as frame time, power envelope, visual error, and latency.

A useful decision framework is to identify a target service level, measure the baseline, locate the dominant bottleneck, select the least damaging optimization, and validate both performance and visual quality. Optimizing a non-dominant pass may improve benchmark numbers without improving user experience.

Applied Case: An Illustrative Virtual-Reality Training Simulator

Background

Consider an illustrative training simulator for industrial maintenance. It displays a detailed factory environment in a head-mounted display and must maintain a high and stable refresh rate to reduce discomfort. The scene contains thousands of static components, dynamic tools, transparent safety equipment, multiple shadow-casting lights, and animated workers.

Situation and Problem

The initial implementation uses forward shading with one draw call per object. Each material performs normal mapping, physically based lighting, and several shadow lookups. Profiling shows that the application misses its frame-time target. Average frame rate is acceptable in an empty factory but falls sharply in dense areas. Users report occasional stutter when moving the camera.

Analysis

The first analysis separates CPU and GPU time. CPU time is high because of repeated state changes and visibility checks. GPU time is dominated by fragment shading and shadow sampling. Overdraw is especially severe around transparent equipment and layered industrial geometry. The scene also loads high-resolution textures for objects that occupy only a few pixels.

Approach and Strategy

The team adopts a staged solution. Static geometry is grouped into spatial clusters with hierarchical bounds. Frustum and occlusion culling are performed on clusters, followed by GPU-driven indirect drawing for visible groups. Mesh LODs are selected using projected screen-space error. Material parameters are reorganized so that objects sharing shaders and textures are rendered together.

Opaque lighting is changed to clustered forward rendering. A compute pass constructs light lists for view-space clusters, avoiding tests against lights that cannot affect a fragment. Transparent objects remain in a separate forward pass. Shadow maps use lower resolution for distant lights, while the main light retains higher quality near the user.

Dynamic resolution scaling is introduced with a frame-time controller. Texture streaming supplies suitable mip levels rather than keeping every asset at maximum resolution. Profiling is repeated after each change rather than at the end of the project.

Outcome

The revised design reduces CPU submission overhead, limits fragment work, and stabilizes frame time in dense views. Visual quality is preserved where it matters most: near the user and on important training components. Minor reductions in distant shadow detail are less noticeable than the original stutter. The result demonstrates that performance improvement came from coordinated changes in visibility, architecture, resource management, and quality policy rather than from a single shader micro-optimization.

Learning Points

The case illustrates five principles. First, frame-time analysis must distinguish CPU and GPU causes. Second, reducing work before shading is often more effective than optimizing arithmetic inside a shader. Third, rendering architecture should reflect material and transparency requirements. Fourth, quality should be allocated according to perceptual and operational importance. Finally, stable frame pacing is a user-facing requirement, not merely a benchmark statistic.

Challenges, Risks, and Common Mistakes

A frequent mistake is assuming that more GPU parallelism automatically produces better performance. Excessive workgroup sizes, high register use, or large shared-memory allocations can reduce the number of resident groups. Another mistake is optimizing arithmetic while ignoring memory traffic and overdraw.

Uncontrolled shader permutations create long compilation times, large pipelines, and difficult testing. They should be managed through carefully chosen specialization dimensions, material classification, and fallback paths. Binding and resource lifetime errors can cause stalls, incorrect images, or device loss. In explicit APIs, barriers must express genuine hazards without conservatively blocking unrelated work.

Deferred rendering can consume excessive bandwidth through oversized G-buffers. Forward rendering can become expensive with many lights. Compute algorithms may suffer from atomic contention or non-coherent access patterns. Temporal techniques may accumulate ghosting, while aggressive LOD may cause popping or incorrect silhouettes. Every optimization should therefore be evaluated in representative camera paths, not only in a favorable test scene.

Professional, Ethical, and Governance Considerations

Graphics engineers increasingly work with visual systems used in training, medicine, engineering, entertainment, and public communication. Rendering choices can affect interpretation. A medical visualization should distinguish measured data from enhancement; a simulation should document approximations that influence decisions. Reproducibility requires recording hardware, driver, API, quality settings, and timing methodology.

Energy-aware rendering is part of responsible engineering. Developers should avoid treating excessive power consumption as an invisible cost, particularly in mobile, cloud, and large-scale visualization deployments. Asset provenance, licensed textures and models, accessibility settings, and protection of gaze or biometric data in immersive systems also require governance.

Current Developments and Emerging Directions

GPU architectures continue to add specialized hardware for ray traversal, matrix operations, video processing, and AI inference. Real-time ray tracing can improve reflections, shadows, and global illumination, but hybrid systems usually combine rasterization with selective ray-based effects because of cost. Denoising and temporal reuse are central to making ray-traced results practical.

Mesh and task shading models move more control over primitive generation and culling to programmable stages. They can support fine-grained visibility and geometry amplification, but they require new workload and debugging models. GPU-driven rendering reduces CPU submission overhead by allowing the GPU to generate or filter draw commands.

Neural rendering and reconstruction techniques use learned models to infer detail, denoise samples, or upscale images. Their benefits depend on training behavior, temporal stability, hardware support, and failure cases. WebGPU and similar portable APIs broaden access to modern GPU computation, while cloud rendering introduces concerns about bandwidth, latency, cost, and data locality.

Best Practices for Advanced Rendering Systems

A robust real-time renderer should establish explicit frame-time and latency budgets before implementation. It should use data-oriented layouts, minimize unnecessary synchronization, batch compatible work, and profile representative scenes. Visibility, LOD, texture residency, and shader complexity should be treated as coordinated controls.

Shader code should be tested across vendors and quality settings. Numerical precision, resource lifetime, and barrier correctness deserve automated validation. Visual regression tests can detect changes in silhouettes, shadows, temporal stability, and color. Performance tests should report distributions and frame-time spikes, not only average frames per second.

Finally, optimization should remain reversible and evidence-based. Maintain a baseline, change one major factor at a time where possible, document the expected benefit, and verify that an improvement on one device does not create unacceptable behavior on another. The best renderer is not the one with the most sophisticated techniques; it is the one that consistently meets its visual, latency, energy, and maintainability objectives.

Chapter Summary

A GPU is a throughput-oriented parallel processor whose performance depends on execution groups, memory locality, scheduling, and specialized graphics hardware. Programmable shaders provide flexibility, but they must be designed as parallel algorithms with attention to divergence, bandwidth, register pressure, and synchronization. Rasterization pipelines can be organized as forward, deferred, clustered, or hybrid architectures according to lighting, material, transparency, and bandwidth requirements.

Visibility culling, level of detail, texture streaming, and GPU-driven submission reduce work before expensive shading occurs. Profiling must distinguish CPU, GPU, memory, synchronization, and frame-pacing problems. Real-time rendering is an optimization problem involving visual quality, latency, throughput, and energy. Dynamic resolution, temporal reconstruction, foveation, and selective ray tracing are examples of controlled trade-offs. Effective professional practice combines measurement, visual validation, portability, responsible energy use, and clear documentation.

Key Terms

GPU: A parallel processor optimized for high-throughput graphics and data-parallel computation.

SIMT: An execution model in which groups of threads execute a common instruction stream across multiple lanes.

Warp/Wavefront: A hardware-scheduled group of shader invocations executed together.

Shader: A programmable GPU function used for graphics processing or general computation.

Workgroup: A cooperating collection of compute-shader invocations that can share memory and synchronize.

Occupancy: The ability of a GPU execution unit to keep multiple workgroups resident and available.

Divergence: Different execution lanes taking different control-flow paths within a SIMD group.

Rasterization: Conversion of geometric primitives into covered samples or fragments.

G-buffer: A collection of screen-space buffers storing geometry and material data for deferred lighting.

Forward rendering: A method that shades visible geometry during or soon after rasterization.

Deferred rendering: A method that stores visibility information before performing lighting in a later pass.

Overdraw: Repeated shading or writing of samples that will be hidden or overwritten.

Culling: Removal of objects or primitives that cannot contribute to the current view.

Level of detail: Selection of a representation according to projected importance or error.

Frame time: The time required to produce one complete frame.

Latency: Delay between input, computation, and displayed output.

Memory bandwidth: The rate at which data can be transferred through a memory system.

Dynamic resolution scaling: Runtime adjustment of rendering resolution to satisfy a performance target.

GPU-driven rendering: Rendering in which the GPU performs visibility selection or generates draw commands.

Temporal reconstruction: Use of information from multiple frames to produce a higher-quality current image.

Review Questions

Short Answer Questions

1. Why does control-flow divergence reduce the efficiency of SIMT execution?

2. Distinguish occupancy from memory bandwidth utilization.

3. What information is commonly stored in a G-buffer?

4. How does screen-space error support level-of-detail selection?

5. Why is frame pacing important even when average frame rate is high?

Long Answer Questions

1. Explain the major stages of a programmable GPU rendering pipeline and the role of vertex and fragment shaders.

2. Compare forward, deferred, clustered forward, and hybrid rendering with respect to lighting, bandwidth, transparency, and scalability.

3. Discuss how memory hierarchy, data layout, register use, and synchronization influence shader performance.

4. Explain a systematic profiling workflow for determining whether a renderer is CPU-bound, fragment-bound, memory-bound, or synchronization-bound.

5. Discuss the quality–latency–energy trade-off in real-time rendering and evaluate dynamic resolution, temporal reconstruction, and foveated rendering as possible responses.

Analytical / Application Questions

1. A scene has few objects but thousands of dynamic lights and a large opaque surface area. Which rendering architecture would you investigate first, and what measurements would guide the decision?

2. A VR application has acceptable average frame rate but frequent long frame-time spikes when the camera enters dense geometry. Design a sequence of profiling experiments and optimizations.

3. A mobile renderer must reduce energy consumption without visibly degrading nearby objects. Propose a coordinated policy involving LOD, texture streaming, shading quality, and resolution, and explain how you would validate it.

22. Multiple Choice Questions with Answers

Question 1

A fragment shader becomes much slower as screen resolution increases, while changing the number of objects has little effect. Which bottleneck is most likely dominant?

A. CPU command submission

B. Fragment or post-processing workload

C. Vertex buffer construction

D. Object-space animation updates

Correct Answer: B. Fragment or post-processing workload

Question 2

Why can a divergent branch reduce GPU efficiency in a SIMT execution group?

A. It forces all textures to use nearest filtering

B. Different branch paths may be executed serially with inactive lanes masked

C. It disables depth testing for the entire frame

D. It prevents the CPU from submitting commands

Correct Answer: B. Different branch paths may be executed serially with inactive lanes masked

Question 3

Which characteristic most directly distinguishes deferred rendering from forward rendering?

A. Deferred rendering stores visibility and material data before a later lighting pass

B. Deferred rendering cannot use textures

C. Forward rendering always requires compute shaders

D. Forward rendering performs no depth testing

Correct Answer: A. Deferred rendering stores visibility and material data before a later lighting pass

Question 4

A compute shader needs threads in the same workgroup to observe shared-memory writes in a defined order. What is generally required?

A. Only a larger register allocation

B. A workgroup execution and memory synchronization operation

C. A second graphics card

D. Disabling all texture caches

Correct Answer: B. A workgroup execution and memory synchronization operation

Question 5

Which optimization most directly reduces work before expensive fragment shading?

A. Increasing material branch complexity

B. Frustum and occlusion culling

C. Adding more shadow samples

D. Using larger G-buffer formats

Correct Answer: B. Frustum and occlusion culling

Question 6

What is a principal cost of a deferred renderer with a large G-buffer?

A. It cannot render opaque geometry

B. Increased memory storage and bandwidth traffic

C. It eliminates all lighting scalability

D. It prevents use of depth information

Correct Answer: B. Increased memory storage and bandwidth traffic

Question 7

A renderer has high occupancy but poor performance because neighboring threads access unrelated memory locations. Which issue is most plausible?

A. Insufficient spatial locality

B. Excessive back-face culling

C. Too few shader invocations

D. An absence of projection matrices

Correct Answer: A. Insufficient spatial locality

Question 8

Why might dynamic resolution scaling be used in a real-time application?

A. To maintain a frame-time target by adjusting rendering workload

B. To guarantee that every texture remains at maximum resolution

C. To remove the need for visibility culling

D. To make CPU simulation deterministic

Correct Answer: A. To maintain a frame-time target by adjusting rendering workload

Question 9

In the illustrative VR simulator, clustered forward rendering was selected primarily to:

A. Replace all transparent materials with opaque ones

B. Limit lighting calculations to lights affecting each view-space cluster

C. Increase the number of shadow samples for every object

D. Move all simulation logic to the CPU

Correct Answer: B. Limit lighting calculations to lights affecting each view-space cluster

Question 10

Which statement best describes a sound optimization practice?

A. Optimize the most complex-looking shader without profiling

B. Maximize average FPS while ignoring frame-time spikes

C. Measure representative workloads and validate both performance and visual quality

D. Use the same quality settings on every hardware platform

Correct Answer: C. Measure representative workloads and validate both performance and visual quality

Computer Graphics
Chapter 12 of 15