Computer Graphics�Behind the Smoke and Mirrors
ARMAN PAPIKAN
Technical Lead
Introduction
Worked On:
credit: Branch Education youtube channel
Rasterization
Rasterization
Rendering order
credit: Adrian Courrèges
https://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study
Base
+ Water
+ Fog
Fog + Sky
Fog + Sky + Clouds
Deferred rendering
Forward vs Deferred
Prepass
Material + Lighting
Final
Prepass
Final
Material
Lighting
Forward vs Deferred vs VisBuffer
Prepass
Material + Lighting
Final
Prepass
Final
Material
Lighting
Prepass
Final
Visibility
Vis Mat +
Lighting
Instance ID,
Primitive ID,
Barycentric Coord,
Depth
Material ID
VisBuffer
G-Buffer vs VisBuffer
Forward vs Deferred vs VisBuffer
Prepass
Material + Lighting
Final
Prepass
Final
Material
Lighting
Prepass
Final
Visibility
Vis Mat +
Lighting
Instance ID,
Primitive ID,
Barycentric Coord,
Depth
Material ID
6 – 10 bytes pp
16 – 32 bytes pp
0 bytes pp
Trade offs / Comparison
�Where h = screen height, w = screen width,�objN = number of objects affected by lights, �lightN = number of lights.
Red Line – signal to be captured
Blue Line – sampling
Blue Dots – sampled points
The signal frequency is higher than the sampling frequency, so we lose information because we are lacking enough resolution to capture the full signal.
Anti-Aliasing Algorithm (MSAA / FXAA)
MSAA – hardware accelerated, works on edges after raster step
FXAA – post processing shader
MSAA + Cheaper, works well with Forward
MSAA – doesn’t work with Deferred
FXAA works on the final frame
Temporal Anti-Aliasing (TAA)
Stepping back in time
Want to correlate current frame pixel with pixel from previous frame(s)
Need some spatial translation to work
Static: introduce jitter,
Temporal Anti-Aliasing (TAA)
Stepping back in time
Want to correlate current frame pixel with pixel from previous frame(s)
Need some spatial translation to work
Static: introduce jitter,
Temporal Anti-Aliasing (TAA)
Stepping back in time
Want to correlate current frame pixel with pixel from previous frame(s)
Need some spatial translation to work
Static: introduce jitter,
Dynamic: calculate motion vectors and reproject
Temporal Anti-Aliasing (TAA)
Stepping back in time
Blend:
Ex: 0.9 * cur – 0.1 * prev
+TAA: Quality, Works well with deferred rendering.
-TAA: Requires higher memory bandwidth and computations.
�Has bad edge cases.
Temporal Anti-Aliasing (TAA)
Dynamic objects
Result
TAA in Doom 2016
TAA in Doom 2016
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
�vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
�vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
�vkCmdBindVertexBuffers(commandBuffer, 0, 1, &_vertexBuffer, _offsets);
vkCmdBindIndexBuffer(commandBuffer, _indexBuffer, 0, VK_INDEX_TYPE_UINT32);
�vkCmdDrawIndexed(commandBuffer, _index_count, 1, 0, 0, 1);
�vkCmdEndRenderPass(commandBuffer);
VkResult result = vkEndCommandBuffer(commandBuffer);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
�glUseProgram(shaderProgram);
�glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
�glBindVertexArray(VAO);
�glDrawElements(GL_TRIANGLES, _index_count, GL_UNSIGNED_INT, 0);
Graphics API (OpenGL / Vulkan)
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
Set up the frame
Graphics API (OpenGL / Vulkan)
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
�vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
�glUseProgram(shaderProgram);
Use shader
Graphics API (OpenGL / Vulkan)
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
�vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
�vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
�glUseProgram(shaderProgram);
�glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
Use Texture
Graphics API (OpenGL / Vulkan)
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
�vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
�vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
�vkCmdBindVertexBuffers(commandBuffer, 0, 1, &_vertexBuffer, _offsets);
vkCmdBindIndexBuffer(commandBuffer, _indexBuffer, 0, VK_INDEX_TYPE_UINT32);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
�glUseProgram(shaderProgram);
�glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
�glBindVertexArray(VAO);
Use vertex & index buffers
Graphics API (OpenGL / Vulkan)
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
�vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
�vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
�vkCmdBindVertexBuffers(commandBuffer, 0, 1, &_vertexBuffer, _offsets);
vkCmdBindIndexBuffer(commandBuffer, _indexBuffer, 0, VK_INDEX_TYPE_UINT32);
�vkCmdDrawIndexed(commandBuffer, _index_count, 1, 0, 0, 1);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
�glUseProgram(shaderProgram);
�glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
�glBindVertexArray(VAO);
�glDrawElements(GL_TRIANGLES, _index_count, GL_UNSIGNED_INT, 0);
Draw call
Graphics API (OpenGL / Vulkan)
vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
�vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
�vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
�vkCmdBindVertexBuffers(commandBuffer, 0, 1, &_vertexBuffer, _offsets);
vkCmdBindIndexBuffer(commandBuffer, _indexBuffer, 0, VK_INDEX_TYPE_UINT32);
�vkCmdDrawIndexed(commandBuffer, _index_count, 1, 0, 0, 1);
�vkCmdEndRenderPass(commandBuffer);
VkResult result = vkEndCommandBuffer(commandBuffer);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
�glUseProgram(shaderProgram);
�glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
�glBindVertexArray(VAO);
�glDrawElements(GL_TRIANGLES, _index_count, GL_UNSIGNED_INT, 0);
Finish
Graphics API (OpenGL / Vulkan)
Each GPU comes with a driver, that exposes the function pointers for supported Graphics APIs
Graphics API helps standardize access to GPUs
Centralized way of sending commands to GPU from CPU
Engine / Graphics programmers use the Graphics API to implement the desired features and techniques
Graphics API (OpenGL / Vulkan)
So many interesting things to cover
General areas in Graphics Programming�and required skills
References
THANK YOU FOR THE ATTENTION!
Tonemap Doom 2016
Tonemap Doom 2016
Color Grading Metal Gear Solid V
Color Grading Metal Gear Solid V