Skip to content

Instantly share code, notes, and snippets.

@mattdesl
Created July 5, 2021 18:06
Show Gist options
  • Save mattdesl/84a400980eb923e1abf9e29488f46c9c to your computer and use it in GitHub Desktop.
Save mattdesl/84a400980eb923e1abf9e29488f46c9c to your computer and use it in GitHub Desktop.
import { vec3 } from 'gl-matrix';
/*
Construct a [ position, normal ] from parametric function and (u, v) coordinate.
Reference: ThreeJS.
*/
export function geometricNormal(fn, u, v) {
const EPS = 0.00001;
const pu = [];
const pv = [];
const p0 = fn(u, v);
if (u - EPS >= 0) {
const p1 = fn(u - EPS, v);
vec3.sub(pu, p0, p1);
} else {
const p1 = fn(u + EPS, v);
vec3.sub(pu, p1, p0);
}
if (v - EPS >= 0) {
const p1 = fn(u, v - EPS);
vec3.sub(pv, p0, p1);
} else {
const p1 = fn(u, v + EPS);
vec3.sub(pv, p1, p0);
}
// cross product of tangent vectors returns surface normal
const normal = vec3.cross([], pu, pv);
vec3.normalize(normal, normal);
vec3.normalize(pu, pu);
vec3.normalize(pv, pv);
return [p0, normal];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment