gpt4 book ai didi

algorithm - webgl(和 threejs)中的深度剥离不变性

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:39:31 27 4
gpt4 key购买 nike

我在看我认为的 the first paper for depth peeling (the simplest algorithm?)我想用 webgl 实现它,使用 three.js

我想我理解了这个概念并且能够制作几个果皮,一些逻辑看起来像这样:

render(scene, camera) {

const oldAutoClear = this._renderer.autoClear
this._renderer.autoClear = false

setDepthPeelActive(true) //sets a global injected uniform in a singleton elsewhere, every material in the scene has onBeforeRender injected with additional logic and uniforms

let ping
let pong

for (let i = 0; i < this._numPasses; i++) {
const pingPong = i % 2 === 0

ping = pingPong ? 1 : 0
pong = pingPong ? 0 : 1

const writeRGBA = this._screenRGBA[i]
const writeDepth = this._screenDepth[ping]

setDepthPeelPassNumber(i) //was going to try increasing the polygonOffsetUnits here globally,

if (i > 0) {
//all but first pass write to depth
const readDepth = this._screenDepth[pong]
setDepthPeelFirstPass(false)
setDepthPeelPrevDepthTexture(readDepth)
this._depthMaterial.uniforms.uFirstPass.value = 0
this._depthMaterial.uniforms.uPrevDepthTex.value = readDepth
} else {
//first pass just renders to depth
setDepthPeelFirstPass(true)
setDepthPeelPrevDepthTexture(null)
this._depthMaterial.uniforms.uFirstPass.value = 1
this._depthMaterial.uniforms.uPrevDepthTex.value = null
}

scene.overrideMaterial = this._depthMaterial

this._renderer.render(scene, camera, writeDepth, true)

scene.overrideMaterial = null
this._renderer.render(scene, camera, writeRGBA, true)
}

this._quad.material = this._blitMaterial
// this._blitMaterial.uniforms.uTexture.value = this._screenDepth[ping]
this._blitMaterial.uniforms.uTexture.value = this._screenRGBA[
this._currentBlitTex
]

console.log(this._currentBlitTex)

this._renderer.render(this._scene, this._camera)

this._renderer.autoClear = oldAutoClear
}

我正在使用 gl_FragCoord.z 进行测试,并将深度打包到一个 8 位 RGBA 纹理中,使用如下所示的着色器:

float depth = gl_FragCoord.z;

vec4 pp = packDepthToRGBA( depth );

if( uFirstPass == 0 ){

float prevDepth = unpackRGBAToDepth( texture2D( uPrevDepthTex , vSS));

if( depth <= prevDepth + 0.0001) {
discard;
}

}

gl_FragColor = pp;

变化的 vSS 在顶点着色器中计算,在投影之后:

vSS.xy = gl_Position.xy * .5 + .5;

基本想法似乎可行,我得到了果皮,但前提是我使用软糖因素。看起来它失败了,但随着角度变得更钝(这就是为什么 polygonOffset 需要因子和单位来解释斜率?)。

一直没看懂不变性是怎么解决的。我不明白提到的扩展是如何被使用的,除了它似乎覆盖了片段深度,但是用什么?

我必须承认,我什至不确定这里指的是哪个插值,因为每个像素都是对齐的,我只是使用最近的过滤。

我确实看到了一些关于深度缓冲区精度的提示,但并没有真正理解这个问题,我想尝试将深度打包到三个 channel 中,看看会发生什么。

有这么小的软糖因素让它有点工作告诉我很可能所有这些采样和计算的深度似乎确实存在于同一个空间中。但这似乎与使用 gl.EQUAL 进行深度测试是同一个问题?对于狗屎和咯咯笑声,我试图在打包后立即用未打包的深度覆盖深度,但它似乎没有做任何事情。

编辑

增加每次剥离的多边形偏移量似乎已经成功。虽然我在线条上遇到了一些问题,但我认为这是因为我已经在使用偏移来绘制它们并且我需要将其包含在剥离偏移中。我仍然很想更多地了解这个问题。

最佳答案

深度缓冲区存储深度 :) 根据“远”和“近”平面,透视投影倾向于设置“堆叠”在缓冲区的一小部分中的点的深度。它在 z 中不是线性的。您可以根据深度自己设置不同的颜色并渲染一些占用大部分近远距离的三角形。

阴影贴图存储深度(到光的距离)......在投影后计算。稍后,在第二遍或后续遍中,您将比较那些“堆叠”的深度,这使得一些比较失败,因为它们的值非常相似:危险差异。

您可以使用更细粒度的深度缓冲区,24 位而不是 16 或 8 位。这可能会解决部分问题。

还有另一个问题:透视分割 或 z/w,需要获得归一化设备坐标 (NDC)。它发生在顶点着色器之后,因此 gl_FragDepth = gl_FragCoord.z 受到影响。

另一种方法是将计算出的深度存储在某个不受“堆叠”或透视分割影响的空间中。相机空间是一个。换句话说,你可以在vertex shader中计算depth undoing projection。

您链接到的文章适用于旧的固定管道,没有着色器。它显示了处理这些差异的 NVIDIA 扩展。

关于algorithm - webgl(和 threejs)中的深度剥离不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46475653/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com