我是WebGL的新手,经过几天的搜索和实验,我找不到一个例子,或者至少是我正在寻找的部分片段:
我正在尝试为后期处理生成深度图,我将在其中重建实际的像素位置(世界空间)。
我设法找到从深度缓冲区提取值后重建实际深度的指南
但是,我找不到办法:
if event.unicode == "!":
print("!")
从深度纹理中提取此类数据WEBGL_depth_texture
我已经读过这些:
但他们都没有完全证明如何做到这一点。
请提供帮助,或者如果可能的话,请参考指导/指南/帮助解决此类问题的其他问题。
这是我迄今为止的最佳尝试: https://codepen.io/naoric/pen/yvYgrQ?editors=0010
readPixels
const $ = sel => document.querySelector(sel)
const $$ = sel => document.querySelectorAll(sel)
const content = sel => $(sel).textContent
const canvas = $('#canvas')
const gl = canvas.getContext('webgl')
window.ext = gl.getExtension('WEBGL_depth_texture')
gl.enable(gl.DEPTH_TEST);
const vertexShaderText = content('#vertex-shader')
const fragmentShaderText = content('#fragment-shader')
function createShader(gl, type, source) {
const shader = gl.createShader(type)
gl.shaderSource(shader, source)
gl.compileShader(shader)
const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS)
if (success) return shader
console.error(gl.getShaderInfoLog(shader))
gl.deleteShader(shader)
}
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram()
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
const success = gl.getProgramParameter(program, gl.LINK_STATUS)
if (success) return program
console.log(gl.getProgramInfoLog(program))
gl.deleteProgram(program)
}
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderText)
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderText)
const program = createProgram(gl, vertexShader, fragmentShader)
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position')
const depthTexturePositions = gl.getAttribLocation(program, 'tex_position')
const uSampler = gl.getUniformLocation(program, 'u_texture')
const positionBuffer = createPositionBuffer(gl)
const texCoordBuffer = createTextureBuffer(gl)
const {frameBuffer, depthTexture} = createFrameBuffer(gl, 256)
render(gl)
function render(gl) {
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)
gl.clearColor(0, 0, 0, 0)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.DEPTH_TEST);
gl.useProgram(program)
gl.enableVertexAttribArray(positionAttributeLocation)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
const size = 3,
type = gl.FLOAT,
normalize = false,
stride = 0,
offset = 0
gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset)
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
draw(gl)
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.vertexAttribPointer(depthTexturePositions, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(depthTexturePositions);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
gl.uniform1i(uSampler, 0);
// const pixels = readTexturePixels(depthTexture, 512, 512)
// console.log({pixels})
draw(gl)
// Unbind the framebuffer
setTimeout(() => render(gl), 1500)
}
function createTextureBuffer(gl) {
const texCoordBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer)
const positions = [
-1.0, 1.0,
1.0, 1.0,
1.0, -1.0,
-1.0, -1.0,
]
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
return texCoordBuffer
}
function createPositionBuffer(gl) {
const positionBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
const positions = [
0, -0.4, 0.1,
0, .5, 0.3,
.7, 0, 0.7
]
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
gl.bindBuffer(gl.ARRAY_BUFFER, null)
return positionBuffer
}
function createFrameBuffer(gl, size) {
const frameBuffer = gl.createFramebuffer()
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
const colorTexture = createTexture(gl, size)
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
const depthTexture = createDepthTexture(gl, size)
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
alert("framebuffer not complete");
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
return {frameBuffer, depthTexture}
}
function createDepthTexture(gl, size) {
var depthTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, size, size, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
// gl.bindTexture(gl.TEXTURE_2D, null)
return depthTexture
}
function createTexture(gl, size) {
const texture = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
// gl.bindTexture(gl.TEXTURE_2D, null)
return texture
}
function draw(gl) {
const primitiveType = gl.TRIANGLES,
offset = 0,
count = 3
gl.drawArrays(primitiveType, offset, count)
}