From 6ecfd41cdb7a1c619b56ab6bcf4cb61e85d59667 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Mon, 13 May 2019 13:54:30 -0700 Subject: [PATCH] fix sphere impostors with orthographic camera --- src/mol-canvas3d/camera.ts | 6 ++--- src/mol-canvas3d/canvas3d.ts | 6 ++--- src/mol-gl/renderable/schema.ts | 3 +++ src/mol-gl/renderer.ts | 7 ++++++ src/mol-gl/shader/spheres.frag | 35 +++++++++++--------------- src/mol-gl/shader/spheres.vert | 17 +------------ src/mol-math/linear-algebra/3d/mat4.ts | 2 +- 7 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/mol-canvas3d/camera.ts b/src/mol-canvas3d/camera.ts index 6dbc0f8d9..bde9504bc 100644 --- a/src/mol-canvas3d/camera.ts +++ b/src/mol-canvas3d/camera.ts @@ -152,7 +152,7 @@ namespace Camera { /** * Sets an offseted view in a larger frustum. This is useful for * - multi-window or multi-monitor/multi-machine setups - * - jittering the camera position for + * - jittering the camera position for */ export interface ViewOffset { enabled: boolean, @@ -183,9 +183,9 @@ namespace Camera { target: Vec3.create(0, 0, 0), - near: 0.1, + near: 1, far: 10000, - fogNear: 0.1, + fogNear: 1, fogFar: 10000, fov: Math.PI / 4, diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index e380a6142..06bab863c 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -130,7 +130,7 @@ namespace Canvas3D { const depthTexture = createTexture(webgl, 'image-depth', 'depth', 'ushort', 'nearest') depthTexture.define(canvas.width, canvas.height) depthTexture.attachFramebuffer(drawTarget.framebuffer, 'depth') - + const postprocessingTarget = createRenderTarget(webgl, canvas.width, canvas.height) const postprocessing = getPostprocessingRenderable(webgl, drawTarget.texture, depthTexture, p.postprocessing) @@ -272,7 +272,7 @@ namespace Canvas3D { renderPostprocessing() } - // compose draw with hold target + // compose rendered scene with hold target composeTarget.bind() gl.viewport(0, 0, canvas.width, canvas.height) state.enable(gl.BLEND) @@ -291,7 +291,7 @@ namespace Canvas3D { ValueCell.update(compose.values.uWeight, 1.0) ValueCell.update(compose.values.tColor, composeTarget.texture) compose.update() - + webgl.unbindFramebuffer() gl.viewport(0, 0, canvas.width, canvas.height) state.disable(gl.BLEND) diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index cdc083cdb..492b5a513 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -155,11 +155,14 @@ export const GlobalUniformSchema = { uRoughness: UniformSpec('f'), uReflectivity: UniformSpec('f'), + uIsOrtho: UniformSpec('f'), uPixelRatio: UniformSpec('f'), uViewportHeight: UniformSpec('f'), uViewport: UniformSpec('v4'), uCameraPosition: UniformSpec('v3'), + uNear: UniformSpec('f'), + uFar: UniformSpec('f'), uFogNear: UniformSpec('f'), uFogFar: UniformSpec('f'), uFogColor: UniformSpec('v3'), diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 2c427b728..1561924f4 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -85,6 +85,7 @@ namespace Renderer { uModelViewProjection: ValueCell.create(modelViewProjection), uInvModelViewProjection: ValueCell.create(invModelViewProjection), + uIsOrtho: ValueCell.create(camera.state.mode === 'orthographic' ? 1 : 0), uPixelRatio: ValueCell.create(ctx.pixelRatio), uViewportHeight: ValueCell.create(viewport.height), uViewport: ValueCell.create(Viewport.toVec4(Vec4(), viewport)), @@ -97,6 +98,8 @@ namespace Renderer { uReflectivity: ValueCell.create(p.reflectivity), uCameraPosition: ValueCell.create(Vec3.clone(camera.state.position)), + uNear: ValueCell.create(camera.state.near), + uFar: ValueCell.create(camera.state.far), uFogNear: ValueCell.create(camera.state.fogNear), uFogFar: ValueCell.create(camera.state.fogFar), uFogColor: ValueCell.create(bgColor), @@ -162,7 +165,11 @@ namespace Renderer { ValueCell.update(globalUniforms.uModelViewProjection, Mat4.mul(modelViewProjection, modelView, camera.projection)) ValueCell.update(globalUniforms.uInvModelViewProjection, Mat4.invert(invModelViewProjection, modelViewProjection)) + ValueCell.update(globalUniforms.uIsOrtho, camera.state.mode === 'orthographic' ? 1 : 0) + ValueCell.update(globalUniforms.uCameraPosition, camera.state.position) + ValueCell.update(globalUniforms.uFar, camera.state.far) + ValueCell.update(globalUniforms.uNear, camera.state.near) ValueCell.update(globalUniforms.uFogFar, camera.state.fogFar) ValueCell.update(globalUniforms.uFogNear, camera.state.fogNear) diff --git a/src/mol-gl/shader/spheres.frag b/src/mol-gl/shader/spheres.frag index 0f0488b4f..f436e493e 100644 --- a/src/mol-gl/shader/spheres.frag +++ b/src/mol-gl/shader/spheres.frag @@ -12,14 +12,13 @@ precision highp int; #pragma glslify: import('./chunks/light-frag-params.glsl') uniform mat4 uProjection; -// uniform vec3 interiorColor; -// uniform float interiorDarkening; -vec3 interiorColor = vec3(1.0, 0.5, 0.5); -float interiorDarkening = 0.0; +// uniform vec3 uInteriorColor; +// uniform float uInteriorDarkening; +vec3 uInteriorColor = vec3(0.5, 0.5, 0.5); +float uInteriorDarkening = 0.0; -uniform float clipNear; -// uniform float ortho; -float ortho = 0.0; +uniform float uClipNear; +uniform float uIsOrtho; varying float vRadius; varying float vRadiusSq; @@ -38,16 +37,16 @@ float calcDepth(const in vec3 cameraPos){ } float calcClip(const in vec3 cameraPos) { - return dot(vec4(cameraPos, 1.0), vec4(0.0, 0.0, 1.0, clipNear - 0.5)); + return dot(vec4(cameraPos, 1.0), vec4(0.0, 0.0, 1.0, uClipNear - 0.5)); } bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){ vec3 cameraSpherePos = -vPointViewPosition; cameraSpherePos.z += vRadius; - vec3 rayOrigin = mix(vec3(0.0, 0.0, 0.0), vPoint, ortho); - vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), ortho); - vec3 cameraSphereDir = mix(cameraSpherePos, rayOrigin - cameraSpherePos, ortho); + vec3 rayOrigin = mix(vec3(0.0, 0.0, 0.0), vPoint, uIsOrtho); + vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), uIsOrtho); + vec3 cameraSphereDir = mix(cameraSpherePos, rayOrigin - cameraSpherePos, uIsOrtho); float B = dot(rayDirection, cameraSphereDir); float det = B * B + vRadiusSq - dot(cameraSphereDir, cameraSphereDir); @@ -58,8 +57,8 @@ bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){ } float sqrtDet = sqrt(det); - float posT = mix(B + sqrtDet, B + sqrtDet, ortho); - float negT = mix(B - sqrtDet, sqrtDet - B, ortho); + float posT = mix(B + sqrtDet, B + sqrtDet, uIsOrtho); + float negT = mix(B - sqrtDet, sqrtDet - B, uIsOrtho); cameraPos = rayDirection * negT + rayOrigin; @@ -85,10 +84,6 @@ bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){ return !interior; } -void main2(void){ - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); -} - void main(void){ bool flag = Impostor(cameraPos, cameraNormal); @@ -105,7 +100,7 @@ void main(void){ // make spheres with a greater radius occlude smaller ones #ifdef NEAR_CLIP if( flag2 ){ - gl_FragDepthEXT = max(0.0, calcDepth(vec3(-(clipNear - 0.5))) + (0.0000001 / vRadius)); + gl_FragDepthEXT = max(0.0, calcDepth(vec3(-(uClipNear - 0.5))) + (0.0000001 / vRadius)); }else if(gl_FragDepthEXT >= 0.0){ gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius); } @@ -136,9 +131,9 @@ void main(void){ if(interior){ #ifdef USE_INTERIOR_COLOR - gl_FragColor.rgb = interiorColor; + gl_FragColor.rgb = uInteriorColor; #endif - gl_FragColor.rgb *= 1.0 - interiorDarkening; + gl_FragColor.rgb *= 1.0 - uInteriorDarkening; } #pragma glslify: import('./chunks/apply-marker-color.glsl') diff --git a/src/mol-gl/shader/spheres.vert b/src/mol-gl/shader/spheres.vert index 656563543..0fc4e2c05 100644 --- a/src/mol-gl/shader/spheres.vert +++ b/src/mol-gl/shader/spheres.vert @@ -34,21 +34,6 @@ const mat4 D = mat4( 0.0, 0.0, 0.0, -1.0 ); -mat4 transpose2(in mat4 inMatrix) { - vec4 i0 = inMatrix[0]; - vec4 i1 = inMatrix[1]; - vec4 i2 = inMatrix[2]; - vec4 i3 = inMatrix[3]; - - mat4 outMatrix = mat4( - vec4(i0.x, i1.x, i2.x, i3.x), - vec4(i0.y, i1.y, i2.y, i3.y), - vec4(i0.z, i1.z, i2.z, i3.z), - vec4(i0.w, i1.w, i2.w, i3.w) - ); - return outMatrix; -} - /** * Compute point size and center using the technique described in: * "GPU-Based Ray-Casting of Quadratic Surfaces" http://dl.acm.org/citation.cfm?id=2386396 @@ -64,7 +49,7 @@ void quadraticProjection(const in float radius, const in vec3 position){ position.x, position.y, position.z, 1.0 ); - mat4 R = transpose2(uProjection * uModelView * aTransform * T); + mat4 R = transpose(uProjection * uModelView * aTransform * T); float A = dot(R[3], D * R[3]); float B = -2.0 * dot(R[0], D * R[3]); float C = dot(R[0], D * R[0]); diff --git a/src/mol-math/linear-algebra/3d/mat4.ts b/src/mol-math/linear-algebra/3d/mat4.ts index ed77c0c6c..ff0167e3f 100644 --- a/src/mol-math/linear-algebra/3d/mat4.ts +++ b/src/mol-math/linear-algebra/3d/mat4.ts @@ -833,7 +833,7 @@ namespace Mat4 { out[ 15 ] = 0; return out; } - + /** * Generates a orthogonal projection matrix with the given bounds */ -- GitLab