WebGL 如何在深度缓冲区中设置值? [英] How does WebGL set values in the depth buffer?

查看:56
本文介绍了WebGL 如何在深度缓冲区中设置值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 OpenGL 中,深度缓冲值是根据场景的近和远裁剪平面计算的.(参考:从深度缓冲区中获取真实的 z 值)

In OpenGL, depth buffer values are calculated based on the near and far clipping planes of the scene. (Reference: Getting the true z value from the depth buffer)

这在 WebGL 中是如何工作的?我的理解是 WebGL 不知道我的场景的远近裁剪平面.近剪裁平面和远剪裁平面用于计算我的投影矩阵,但我从不明确告诉 WebGL 它们是什么,因此它无法使用它们来计算深度缓冲区值.

How does this work in WebGL? My understanding is that WebGL is unaware of my scene's far and near clipping planes. The near and far clipping planes are used to calculate my projection matrix, but I never tell WebGL what they are explicitly so it can't use them to calculate depth buffer values.

渲染我的场景时,WebGL 如何在深度缓冲区中设置值?

How does WebGL set values in the depth buffer when my scene is rendered?

推荐答案

WebGL(如现代 OpenGL 和 OpenGL ES)从您提供给顶点着色器中的 gl_Position.z 的值中获取深度值(虽然您也可以使用某些扩展直接写入深度缓冲区,但这种情况很少见)

WebGL (like modern OpenGL and OpenGL ES) gets the depth value from the value you supply to gl_Position.z in your vertex shader (though you can also write directly to the depth buffer using certain extensions but that's far less common)

WebGL 和现代 OpenGL 中都没有场景.场景的概念是 90 年代初遗留下来的遗留 OpenGL 的一部分,并且早已被弃用.它不存在于 OpenGL ES(在 Android、iOS、ChromeOS、Raspberry PI、WebGL 等上运行的 OpenGL...)

There is no scene in WebGL nor modern OpenGL. That concept of a scene is part of legacy OpenGL left over from the early 90s and long since deprecated. It doesn't exist in OpenGL ES (the OpenGL that runs on Android, iOS, ChromeOS, Raspberry PI, WebGL etc...)

现代 OpenGL 和 WebGL 只是光栅化 API.您编写着色器,它们是在 GPU 上运行的小函数.您可以通过属性(每次迭代数据)、统一(全局变量)、纹理(2d/3d 数组)、变量(从顶点着色器传递到片段着色器的数据)为这些着色器提供数据.

Modern OpenGL and WebGL are just rasterization APIs. You write shaders which are small functions that run on the GPU. You provide those shaders with data through attributes (per iteration data), uniforms (global variables), textures (2d/3d arrays), varyings (data passed from vertex shaders to fragment shaders).

剩下的取决于您和您提供的着色器函数的作用.现代 OpenGL 和 WebGL 的所有意图和目的只是具有某些限制的通用计算引擎.要让它们执行任何操作,您需要提供着色器.

The rest is up to you and what your supplied shader functions do. Modern OpenGL and WebGL are for all intents and purposes just generic computing engines with certain limits. To get them to do anything is up to you to supply shaders.

有关更多信息,请参阅 webglfundamentals.org.

See webglfundamentals.org for more.

在您链接的问答中,程序员提供的着色器决定使用平截头体数学来决定如何设置 gl_Position.z.平截头体数学由程序员提供.WebGL/GL 不关心 gl_Position.z 是如何计算的,只是它是一个介于 -1.0 和 +1.0 之间的值,因此如何从深度缓冲区中获取一个值并返回 Z 完全是问题程序员首先决定如何计算它.

In the Q&A you linked to it's the programmer supplied shaders that decide to use frustum math to decide how to set gl_Position.z. The frustum math is supplied by the programmer. WebGL/GL don't care how gl_Position.z is computed, only that it's a value between -1.0 and +1.0 so how to take a value from the depth buffer and go back to Z is solely up to how the programmer decided to calculate it in the first place.

本文介绍了最常用的设置gl_Position.z 使用 WebGL/OpenGL 渲染 3d 时.根据您的问题,我建议您阅读前面链接的文章开头的文章.

This article covers the most commonly used math for setting gl_Position.z when rendering 3d with WebGL/OpenGL. Based on your question though I'd suggest reading the preceding articles linked at the beginning of that one.

至于将哪些实际值写入深度缓冲区

As for what actual values get written to the depth buffer it's

ndcZ = gl_Position.z / gl_Position.w;
depthValue = (far - near) / 2 * ndcZ + (near - far) / 2

nearfar 默认分别为 0 和 1,尽管您可以使用 gl.depthRange 设置它们,但假设它们是 0 和 1 那么

near and far default to 0 and 1 respectively though you can set them with gl.depthRange but assuming they are 0 and 1 then

ndcZ = gl_Position.z / gl_Position.w;
depthValue = .5 * ndcZ - .5

该 depthValue 将在 0 到 1 范围内,并转换为深度缓冲区的任何位深度.有一个 24 位深度的缓冲区是很常见的,所以

That depthValue would then be in the 0 to 1 range and converted to whatever bit depth the depth buffer is. It's common to have a 24bit depth buffer so

bitValue = depthValue * (2^24 - 1)

这篇关于WebGL 如何在深度缓冲区中设置值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆