Skip to content

Commit

Permalink
Render grid in ortho view (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
slimbuck authored Dec 18, 2024
1 parent 4946b36 commit f8a4c0e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 17 deletions.
15 changes: 14 additions & 1 deletion src/infinite-grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
DepthState,
Layer,
QuadRender,
Shader
Shader,
Vec3
} from 'playcanvas';

import { Element, ElementType } from './element';
Expand Down Expand Up @@ -52,6 +53,18 @@ class InfiniteGrid extends Element {
device.setDepthState(DepthState.WRITEDEPTH);
device.setStencilState(null, null);

// select the correctly plane in orthographic mode
const { camera } = this.scene;
if (camera.ortho) {
const cmp = (a:Vec3, b: Vec3) => 1.0 - Math.abs(a.dot(b)) < 1e-03;
const z = camera.entity.getWorldTransform().getZ();
const which = cmp(z, Vec3.RIGHT) ? 0 : (cmp(z, Vec3.BACK) ? 2 : 1);
device.scope.resolve('plane').setValue(which);
} else {
// default is xz plane
device.scope.resolve('plane').setValue(1);
}

this.quadRender.render();
}
});
Expand Down
50 changes: 34 additions & 16 deletions src/shaders/infinite-grid-shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ const fragmentShader = /* glsl*/ `
uniform mat4 matrix_viewProjection;
uniform sampler2D blueNoiseTex32;
uniform int plane; // 0: x (yz), 1: y (xz), 2: z (xy)
vec4 planes[3] = vec4[3](
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0, 0.0, 1.0, 0.0)
);
vec3 colors[3] = vec3[3](
vec3(1.0, 0.2, 0.2),
vec3(0.2, 1.0, 0.2),
vec3(0.2, 0.2, 1.0)
);
int axis0[3] = int[3](1, 0, 0);
int axis1[3] = int[3](2, 2, 1);
varying vec3 worldNear;
varying vec3 worldFar;
Expand Down Expand Up @@ -85,67 +102,68 @@ const fragmentShader = /* glsl*/ `
// intersect ray with the world xz plane
float t;
if (!intersectPlane(t, p, v, vec4(0, 1, 0, 0))) {
if (!intersectPlane(t, p, v, planes[plane])) {
discard;
}
// calculate grid intersection
vec3 pos = p + v * t;
vec2 ddx = dFdx(pos.xz);
vec2 ddy = dFdy(pos.xz);
vec3 worldPos = p + v * t;
vec2 pos = plane == 0 ? worldPos.yz : (plane == 1 ? worldPos.xz : worldPos.xy);
vec2 ddx = dFdx(pos);
vec2 ddy = dFdy(pos);
float epsilon = 1.0 / 255.0;
// calculate fade
float fade = 1.0 - smoothstep(400.0, 1000.0, length(pos - view_position));
float fade = 1.0 - smoothstep(400.0, 1000.0, length(worldPos - view_position));
if (fade < epsilon) {
discard;
}
vec3 levelPos;
vec2 levelPos;
float levelSize;
float levelAlpha;
// 10m grid with colored main axes
levelPos = pos * 0.1;
levelSize = 2.0 / 1000.0;
levelAlpha = pristineGrid(levelPos.xz, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
levelSize = 1.0 / 1000.0;
levelAlpha = pristineGrid(levelPos, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
if (levelAlpha > epsilon) {
vec3 color;
vec2 loc = abs(levelPos.xz);
vec2 loc = abs(levelPos);
if (loc.x < levelSize) {
if (loc.y < levelSize) {
color = vec3(1.0);
} else {
color = vec3(0.2, 0.2, 1.0);
color = colors[axis1[plane]];
}
} else if (loc.y < levelSize) {
color = vec3(1.0, 0.2, 0.2);
color = colors[axis0[plane]];
} else {
color = vec3(0.9);
}
gl_FragColor = vec4(color, levelAlpha);
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(pos) : 1.0;
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
return;
}
// 1m grid
levelPos = pos;
levelSize = 1.0 / 100.0;
levelAlpha = pristineGrid(levelPos.xz, ddx, ddy, vec2(levelSize)) * fade;
levelAlpha = pristineGrid(levelPos, ddx, ddy, vec2(levelSize)) * fade;
if (levelAlpha > epsilon) {
gl_FragColor = vec4(vec3(0.7), levelAlpha);
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(pos) : 1.0;
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
return;
}
// 0.1m grid
levelPos = pos * 10.0;
levelSize = 1.0 / 100.0;
levelAlpha = pristineGrid(levelPos.xz, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
levelAlpha = pristineGrid(levelPos, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
if (levelAlpha > epsilon) {
gl_FragColor = vec4(vec3(0.7), levelAlpha);
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(pos) : 1.0;
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
return;
}
Expand Down

0 comments on commit f8a4c0e

Please sign in to comment.