Volume Analysis Terrain Curvature

   2200   1   1
User Avatar
Member
26 posts
Joined: Nov. 2008
Offline
I like the results of the curvature volume analysis that the “Heightfield Mask By Feature” computes when applied to a heightfield. Under the hood (i.e. “Allow Editing of Content”), I noticed Heightfield Mask By Feature uses the volume analysis SOP, measuring the curvature of the surface. I'd like to do something similar in a shader outside of Houdini.

There's a lot of online documentation about how laplacian is computed from a simple convolution of weights
[[1,1,1], [1,-8,1], [1,1,1]]
but I can't figure out how Houdini is computing curvature. Can someone shed some light on the way that houdini computes volume curvature? VDB curvature is computed differently than the volume analysis curvature, otherwise I could just inspect the OpenVDB code.

I've also tried to use the differential edge detection technique described here without success: https://en.wikipedia.org/wiki/Edge_detection [en.wikipedia.org] (Differential)
Edited by scottp - July 21, 2020 15:49:45
Scott Peterson, Machine Learning Graphics Engineer, Unity
User Avatar
Member
26 posts
Joined: Nov. 2008
Offline
I found a way to replicate curvature, in case anyone needs this. Curvature is basically planform curvature, or horizontal curvature in GIS systems. Planform curvature relates to the convergence and divergence of flow across a surface.

float s = ch("../heightfield1/gridspacing");
// https://www.microimages.com/documentation/TechGuides/70CurvScript.pdf
float z1 = volumesample(0, 0, @P + set(-s, 0, -s));
float z2 = volumesample(0, 0, @P + set(0, 0, -s));
float z3 = volumesample(0, 0, @P + set(s, 0, -s));
float z4 = volumesample(0, 0, @P + set(-s, 0, 0));
float z5 = volumesample(0, 0, @P + set(0, 0, 0));
float z6 = volumesample(0, 0, @P + set(s, 0, 0));
float z7 = volumesample(0, 0, @P + set(-s, 0, s));
float z8 = volumesample(0, 0, @P + set(0, 0, s));
float z9 = volumesample(0, 0, @P + set(s, 0, s));
float a2 = (z4 + z6) / (2 * s * s) - z5 / (s * s);
float b2 = (z2 + z8) / (2 * s * s) - z5 / (s * s);
float c = (z3 + z7 - z1 - z9)/(4 * s * s);
float d2 = (z6 - z4)/(2 * s);
float ee2 = (z2 - z8)/(2 * s);
float plndenom2 = pow(ee2*ee2 + d2*d2, 1.5);
// @height = -2 * (a * (d * d) + b * (ee * ee) + c * d * ee);
// Plan curvature (better)
// @height = -2 * (b * (d * d) + a * (ee * ee) - c * d * ee) / plndenom;
@height = -2 * (b2 * (d2 * d2) + a2 * (ee2 * ee2) - c * d2 * ee2) / plndenom2;
@height *= -1;
@height = clamp(@height, -5, 5);
Scott Peterson, Machine Learning Graphics Engineer, Unity
  • Quick Links