Skip to content

Commit

Permalink
Fix edge and polyline z (#1059)
Browse files Browse the repository at this point in the history
* fix z for edges and polylines

* rush change

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 029cc47)
  • Loading branch information
MarcNeely authored and mergify-bot committed Mar 29, 2021
1 parent aaa093a commit eb37a74
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@bentley/imodeljs-frontend",
"comment": "fixed z for edges and polylines when extended behind the eye",
"type": "none"
}
],
"packageName": "@bentley/imodeljs-frontend",
"email": "36053767+MarcNeely@users.noreply.github.com"
}
17 changes: 9 additions & 8 deletions core/frontend/src/render/webgl/glsl/Edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { addShaderFlags } from "./Common";
import { addWhiteOnWhiteReversal } from "./Fragment";
import { addAdjustWidth, addLineCode } from "./Polyline";
import { octDecodeNormal } from "./Surface";
import { addLineWeight, addModelViewMatrix, addNormalMatrix, addProjectionMatrix } from "./Vertex";
import { addLineWeight, addModelViewMatrix, addModelViewProjectionMatrix, addNormalMatrix, addProjectionMatrix } from "./Vertex";
import { addModelToWindowCoordinates, addViewport } from "./Viewport";

const decodeEndPointAndQuadIndices = `
Expand Down Expand Up @@ -62,16 +62,15 @@ const computePosition = `
vec4 other = g_otherPos;
float miterAdjust = 0.0;
float weight = computeLineWeight();
float clipDist;
g_windowPos = modelToWindowCoordinates(rawPos, other, clipDist);
vec4 pos;
g_windowPos = modelToWindowCoordinates(rawPos, other, pos, v_eyeSpace);
if (g_windowPos.w == 0.0) // Clipped out.
return g_windowPos;
vec4 clipPos = rawPos + clipDist * (other - rawPos);
vec4 pos = MAT_MVP * clipPos;
vec4 projOther = modelToWindowCoordinates(other, rawPos, clipDist);
vec4 otherPos;
vec3 otherMvPos;
vec4 projOther = modelToWindowCoordinates(other, rawPos, otherPos, otherMvPos);
g_windowDir = projOther.xy - g_windowPos.xy;
Expand Down Expand Up @@ -117,9 +116,10 @@ function createBase(isSilhouette: boolean, instanced: IsInstanced, isAnimated: I
vert.addGlobal("lineCodeEyePos", VariableType.Vec4);
vert.addGlobal("lineCodeDist", VariableType.Float, "0.0");

addModelToWindowCoordinates(vert); // adds u_mvp, u_viewportTransformation
addModelToWindowCoordinates(vert); // adds u_mvp, u_viewportTransformation, and sets g_eyeSpace
addProjectionMatrix(vert);
addLineCode(builder, lineCodeArgs);
builder.addVarying("v_eyeSpace", VariableType.Vec3);
vert.set(VertexShaderComponent.ComputePosition, computePosition);
builder.addVarying("v_lnInfo", VariableType.Vec4);
addAdjustWidth(vert);
Expand All @@ -131,6 +131,7 @@ function createBase(isSilhouette: boolean, instanced: IsInstanced, isAnimated: I

if (isSilhouette) {
addNormalMatrix(vert);
addModelViewProjectionMatrix(vert);
vert.set(VertexShaderComponent.CheckForEarlyDiscard, checkForSilhouetteDiscard);
vert.addFunction(octDecodeNormal);
}
Expand Down
14 changes: 7 additions & 7 deletions core/frontend/src/render/webgl/glsl/Polyline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ function addCommon(prog: ProgramBuilder) {
addLineWeight(vert);

vert.addGlobal("miterAdjust", VariableType.Float, "0.0");
prog.addVarying("v_eyeSpace", VariableType.Vec3);
vert.set(VertexShaderComponent.ComputePosition, computePosition);
prog.addVarying("v_lnInfo", VariableType.Vec4);
addAdjustWidth(vert);
Expand Down Expand Up @@ -232,14 +233,11 @@ const computePosition = `
v_lnInfo = vec4(0.0, 0.0, 0.0, 0.0); // init and set flag to false
vec4 next = g_nextPos;
float clipDist;
g_windowPos = modelToWindowCoordinates(rawPos, next, clipDist);
vec4 pos;
g_windowPos = modelToWindowCoordinates(rawPos, next, pos, v_eyeSpace);
if (g_windowPos.w == 0.0)
return g_windowPos;
vec4 clipPos = rawPos + clipDist * (next - rawPos);
vec4 pos = MAT_MVP * clipPos;
float param = a_param;
float weight = computeLineWeight();
float scale = 1.0, directionScale = 1.0;
Expand All @@ -257,7 +255,9 @@ const computePosition = `
param -= kNegatePerp;
}
vec4 projNext = modelToWindowCoordinates(next, rawPos, clipDist);
vec4 otherPos;
vec3 otherMvPos;
vec4 projNext = modelToWindowCoordinates(next, rawPos, otherPos, otherMvPos);
g_windowDir = projNext.xy - g_windowPos.xy;
if (param < kJointBase) {
Expand All @@ -269,7 +269,7 @@ const computePosition = `
if (kNone != param) {
vec2 delta = vec2(0.0);
vec4 prev = g_prevPos;
vec4 projPrev = modelToWindowCoordinates(prev, rawPos, clipDist);
vec4 projPrev = modelToWindowCoordinates(prev, rawPos, otherPos, otherMvPos);
vec2 prevDir = g_windowPos.xy - projPrev.xy;
float thisLength = sqrt(g_windowDir.x * g_windowDir.x + g_windowDir.y * g_windowDir.y);
const float s_minNormalizeLength = 1.0E-5; // avoid normalizing zero length vectors.
Expand Down
27 changes: 16 additions & 11 deletions core/frontend/src/render/webgl/glsl/Viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { ShaderBuilder, VariableType, VertexShaderBuilder } from "../ShaderBuilder";
import { addRenderPass } from "./RenderPass";
import { addModelViewProjectionMatrix } from "./Vertex";
import { addModelViewMatrix, addProjectionMatrix } from "./Vertex";

/** @internal */
export function addViewport(shader: ShaderBuilder) {
Expand All @@ -29,32 +29,36 @@ export function addViewportTransformation(shader: ShaderBuilder) {
}

const modelToWindowCoordinates = `
vec4 modelToWindowCoordinates(vec4 position, vec4 next, out float clipDist) {
clipDist = 0.0;
vec4 modelToWindowCoordinates(vec4 position, vec4 next, out vec4 clippedMvpPos, out vec3 clippedMvPos) {
if (kRenderPass_ViewOverlay == u_renderPass || kRenderPass_Background == u_renderPass) {
vec4 q = MAT_MVP * position;
vec4 q = MAT_MV * position;
clippedMvPos = q.xyz;
q = u_proj * q;
clippedMvpPos = q;
q.xyz /= q.w;
q.xyz = (u_viewportTransformation * vec4(q.xyz, 1.0)).xyz;
return q;
}
// Negative values are in front of the camera (visible).
float s_maxZ = -u_frustum.x; // use -near (front) plane for segment drop test since u_frustum's near & far are pos.
vec4 q = MAT_MV * position; // eye coordinates.
vec4 q = MAT_MV * position; // eye coordinates.
vec4 n = MAT_MV * next;
if (q.z > s_maxZ) {
if (n.z > s_maxZ)
return vec4(0.0, 0.0, 1.0, 0.0); // Entire segment behind eye.
return vec4(0.0, 0.0, 1.0, 0.0); // Entire segment behind front clip plane.
clipDist = (s_maxZ - q.z) / (n.z - q.z);
float t = (s_maxZ - q.z) / (n.z - q.z);
q.x += clipDist * (n.x - q.x);
q.y += clipDist * (n.y - q.y);
q.z = s_maxZ; // q.z + (s_maxZ - q.z) * (s_maxZ - q.z) / n.z - q.z
q.x += t * (n.x - q.x);
q.y += t * (n.y - q.y);
q.z = s_maxZ; // q.z + (s_maxZ - q.z) / (n.z - q.z) * (n.z - q.z) = s_maxZ
}
clippedMvPos = q.xyz;
q = u_proj * q;
clippedMvpPos = q;
q.xyz /= q.w; // normalized device coords
q.xyz = (u_viewportTransformation * vec4(q.xyz, 1.0)).xyz; // window coords
return q;
Expand All @@ -63,7 +67,8 @@ vec4 modelToWindowCoordinates(vec4 position, vec4 next, out float clipDist) {

/** @internal */
export function addModelToWindowCoordinates(vert: VertexShaderBuilder) {
addModelViewProjectionMatrix(vert);
addModelViewMatrix(vert);
addProjectionMatrix(vert);
addViewportTransformation(vert);
addRenderPass(vert);
vert.addFunction(modelToWindowCoordinates);
Expand Down

0 comments on commit eb37a74

Please sign in to comment.