diff --git a/ShadowEditor.Web/src/event/GPUPickEvent.js b/ShadowEditor.Web/src/event/GPUPickEvent.js index 75ca0555..9bf9c16f 100644 --- a/ShadowEditor.Web/src/event/GPUPickEvent.js +++ b/ShadowEditor.Web/src/event/GPUPickEvent.js @@ -64,7 +64,15 @@ GPUPickEvent.prototype.onAfterRender = function () { this.init = true; this.depthMaterial = new THREE.ShaderMaterial({ vertexShader: DepthVertexShader, - fragmentShader: DepthFragmentShader + fragmentShader: DepthFragmentShader, + uniforms: { + near: { + value: camera.near + }, + far: { + value: camera.far + } + } }); this.renderTarget = new THREE.WebGLRenderTarget(width, height); this.pixel = new Uint8Array(4); @@ -149,20 +157,22 @@ GPUPickEvent.prototype.onAfterRender = function () { renderer.render(scene, camera); renderer.readRenderTargetPixels(this.renderTarget, this.offsetX, height - this.offsetY, 1, 1, this.pixel); - let depth = (this.pixel[0] * 65535 + this.pixel[1] * 255 + this.pixel[2]) / 0xffffff; + let hex = (this.pixel[0] * 65535 + this.pixel[1] * 255 + this.pixel[2]) / 0xffffff; if (this.pixel[3] === 0) { - depth = -depth; + hex = -hex; } + let depth = hex * (camera.far - camera.near) + camera.near; + this.world.set( this.offsetX / width * 2 - 1, - this.offsetY / height * 2 + 1, - depth + hex ); this.world.unproject(camera); - console.log(`${this.pixel[0]}, ${this.pixel[1]}, ${this.pixel[2]}, ${depth}, ${this.world.x}, ${this.world.y}, ${this.world.z}`); + console.log(`${hex},${depth}, ${this.world.x}, ${this.world.y}, ${this.world.z}`); // 还原原来的属性 scene.background = oldBackground; diff --git a/ShadowEditor.Web/src/event/shader/depth_fragment.glsl b/ShadowEditor.Web/src/event/shader/depth_fragment.glsl index 7f197df9..36c02cc6 100644 --- a/ShadowEditor.Web/src/event/shader/depth_fragment.glsl +++ b/ShadowEditor.Web/src/event/shader/depth_fragment.glsl @@ -1,18 +1,20 @@ precision highp float; -uniform mat4 projectionMatrix; - -varying vec4 vTransformed; +uniform float near; +uniform float far; void main() { - float z = (projectionMatrix * vTransformed).z; + // 参考1:https://stackoverflow.com/questions/6408851/draw-the-depth-value-in-opengl-using-shaders + // 参考2:https://gamedev.stackexchange.com/questions/93055/getting-the-real-fragment-depth-in-glsl + float ndcDepth = (gl_FragCoord.z - near) / (far - near); + float clipDepth = ndcDepth / gl_FragCoord.w; - float hex = abs(clamp(z, -1.0, 1.0)) * 16777215.0; // 0xffffff + float hex = abs(clamp(clipDepth, -1.0, 1.0)) * 16777215.0; // 0xffffff float r = floor(hex / 65535.0); float g = floor((hex - r * 65535.0) / 255.0); float b = floor(hex - r * 65535.0 - g * 255.0); - float a = sign(z) >= 0.0 ? 1.0 : 0.0; // depth大于等于0,为1.0;小于0,为0.0。 + float a = sign(clipDepth) >= 0.0 ? 1.0 : 0.0; // depth大于等于0,为1.0;小于0,为0.0。 gl_FragColor = vec4(r / 255.0, g / 255.0, b / 255.0, a); } \ No newline at end of file diff --git a/ShadowEditor.Web/src/event/shader/depth_vertex.glsl b/ShadowEditor.Web/src/event/shader/depth_vertex.glsl index 2a35fb22..d2119de5 100644 --- a/ShadowEditor.Web/src/event/shader/depth_vertex.glsl +++ b/ShadowEditor.Web/src/event/shader/depth_vertex.glsl @@ -1,9 +1,5 @@ precision highp float; -varying vec4 vTransformed; - void main() { - vec4 transformed = modelViewMatrix * vec4(position, 1.0); - gl_Position = projectionMatrix * transformed; - vTransformed = transformed; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } \ No newline at end of file