Depth Buffer
Up until now there is only one type of output buffer you've made use of, the color buffer. This chapter will discuss two additional types, the depth buffer and the stencil buffer. For each of these a problem will be presented and subsequently solved with that specific buffer.
Preparations
To best demonstrate the use of these buffers, let's draw a cube instead of a flat shape. The vertex shader needs to be modified to accept a third coordinate:
in vec3 position;
...
gl_Position = proj * view * model * vec4(position, 1.0);
We're also going to need to alter the color again later in this chapter, so make sure the fragment shader multiplies the texture color by the color attribute:
vec4 texColor = mix(texture(texKitten, Texcoord),
texture(texPuppy, Texcoord), 0.5);
outColor = vec4(Color, 1.0) * texColor;
Vertices are now 8 floats in size, so you'll have to update the vertex attribute offsets and strides as well. Finally, add the extra coordinate to the vertex array:
float vertices[] = {
// X Y Z R G B U V
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f
};
Confirm that you've made all the required changes by running your program and checking if it still draws a flat spinning image of a kitten blended with a puppy. A single cube consists of 36 vertices (6 sides * 2 triangles * 3 vertices), so I will ease your life by providing the array here.
glDrawArrays(GL_TRIANGLES, 0, 36);
We will not make use of element buffers for drawing this cube, so you can use glDrawArrays to draw it. If you were confused by this explanation, you can compare your program to this reference code.
It immediately becomes clear that the cube is not rendered as expected when seeing the output. The sides of the cube are being drawn, but they overlap each other in strange ways! The problem here is that when OpenGL draws your cube triangle-by-triangle, it will simply write over pixels even though something else may have been drawn there before. In this case OpenGL will happily draw triangles in the back over triangles at the front.
Luckily OpenGL offers ways of telling it when to draw over a pixel and when not to. I'll go over the two most important ways of doing that, depth testing and stencilling, in this chapter.
Depth buffer
Z-buffering is a way of keeping track of the depth of every pixel on the screen. The depth is proportional to the distance between the screen plane and a fragment that has been drawn. That means that the fragments on the sides of the cube further away from the viewer have a higher depth value, whereas fragments closer have a lower depth value.
If this depth is stored along with the color when a fragment is written, fragments drawn later can compare their depth to the existing depth to determine if the new fragment is closer to the viewer than the old fragment. If that is the case, it should be drawn over and otherwise it can simply be discarded. This is known as depth testing.
OpenGL offers a way to store these depth values in an extra buffer, called the depth buffer, and perform the required check for fragments automatically. The fragment shader will not run for fragments that are invisible, which can have a significant impact on performance. This functionality can be enabled by calling glEnable.
glEnable(GL_DEPTH_TEST);
If you enable this functionality now and run your application, you'll notice that you get a black screen. That happens because the depth buffer is filled with 0 depth for each pixel by default. Since no fragments will ever be closer than that they are all discarded.
The depth buffer can be cleared along with the color buffer by extending the glClear call:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
The default clear value for the depth is 1.0f, which is equal to the depth of your far clipping plane and thus the furthest depth that can be represented. All fragments will be closer than that, so they will no longer be discarded.
With the depth test capability enabled, the cube is now rendered correctly. Just like the color buffer, the depth buffer has a certain amount of bits of precision which can be specified by you. Less bits of precision reduce the extra memory use, but can introduce rendering errors in more complex scenes.
Depth Buffer的更多相关文章
- [Zz] DX depth buffer
声明:本文完全翻译自DX SDK Documentation depth buffer,通常被称为z-buffer或者w-buffer,是设备的一个属性,用来存储深度信息,被D3D使用.当D3D渲染一 ...
- D3D depth buffer的预览
在使用D3D开发游戏的过程中,很多情况下都会用到depth buffer来完成特定的效果,比如DOF,Shadows,SSAO等等.在这些情况下我们就可能需要预览depth buffer来确定它是正确 ...
- 从depth buffer中构建view-space position
观察透视投影矩阵: 对于x和y,矩阵变换只是一个缩放系数,那么逆变换就是缩放系数的倒数,所以 设Xndc Yndc为NDC空间中的XY坐标,Xview Yview Zview为view space中的 ...
- 测试不同格式下depth buffer的精度
这篇文章主要是参考MJP的“Attack of The Depth Buffer”,测试不同格式下depth buffer的精度. 测试的depth buffer包含两类: 一是非线性的depth b ...
- Cesium 中由 Logarithmic Depth Buffer 引起的模型显示不完整的问题
当 Cesium 单个模型过长时,会遇到某些视角模型显示不完整的问题,如下图所示: 经过在官方论坛上询问,该问题由 viewer.scene.logarithmicDepthBuffer 开启造成,关 ...
- Vulkan SDK 之 Depth Buffer
深度缓冲是可选的,比如渲染一个3D的立方体的时候,就需要用到深度缓冲.Swapchain就算有多个images,此时深度缓冲区也只需要一个.vkCreateSwapchainKHR 会创建所有需要的i ...
- depth/stencil buffer的作用 ----------理解模板缓存 opengl
在D3D11中,有depth/stencil buffer,它们和framebuffer相对应,如下图所示,framebuffer中一个像素,有相对应的depth buffer和stencil buf ...
- 【D3D12学习手记】4.3.8 Create the Depth/Stencil Buffer and View
我们现在需要创建深度/模板缓冲区. 如§4.1.5所述,深度缓冲区只是一个2D纹理,用于存储最近的可见对象的深度信息(如果使用模板(stencil),则也会存储模板信息). 纹理是一种GPU资源,因此 ...
- Directx11教程(48) depth/stencil buffer的作用
原文:Directx11教程(48) depth/stencil buffer的作用 在D3D11中,有depth/stencil buffer,它们和framebuffer相对应,如下图所 ...
随机推荐
- 九度OJ 1147:Jugs(罐子) (模拟、游戏)
时间限制:1 秒 内存限制:32 兆 特殊判题:是 提交:243 解决:200 题目描述: In the movie "Die Hard 3", Bruce Willis and ...
- 九度OJ 1022:游船出租 (统计)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3670 解决:1444 题目描述: 现有公园游船租赁处请你编写一个租船管理系统.当游客租船时,管理员输入船号并按下S键,系统开始计时 ...
- plus.os.name 无法正确执行的问题
使用HTML5+开发App的时候, 如果碰到正确的代码却无法出现预期的执行效果, 请检查模块权限配置是否OK? 比如plus.os.name, 需要Device权限 ;
- SAP RFC 的介绍
第一部分 RFC技术 什么是RFC? RFC是SAP系统和其他(SAP或非SAP)系统间的一个重要而常用的双向接口技术,也被视为SAP与外部通信的基本协议.简单地说,RFC过程就是系统调用当前系统外的 ...
- 【zabbix】zabbix3.0部署手册
1.环境准备 Centos 6.X 2.数据库准备 默认centos yum源中mysql包的版本号为5.1,为了能使zabbix 3.0能达到最好的性能效果,安装最新版的mysql数据库. yum ...
- 《程序员代码面试指南》第八章 数组和矩阵问题 在数组中找到出现次数大于N/K 的数
题目 在数组中找到出现次数大于N/K 的数 java代码 package com.lizhouwei.chapter8; import java.util.ArrayList; import java ...
- Linux2.4文件系统中vfsmount、安装点的dentry、设备的dentry之间的关系【转】
本文转载自:https://blog.csdn.net/mishifangxiangdefeng/article/details/7566575 1.vfsmount.安装点的dentry.设备的de ...
- git删除远程分支【转】
本文转载自:https://my.oschina.net/tsingxu/blog/84601 如果不再需要某个远程分支了,比如搞定了某个特性并把它合并进了远程的 master 分支(或任何其他存放 ...
- 51Nod 1515 明辨是非 —— 并查集 + 启发式合并
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1515 1515 明辨是非 题目来源: 原创 基准时间限制:1 ...
- BZOJ 1193 [HNOI2006]马步距离:大范围贪心 小范围暴搜
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1193 题意: 给定起点(px,py).终点(sx,sy).(x,y < 100000 ...