Volume Analysis Terrain Curvature

   2573   1   1
User Avatar
Member
26 posts
Joined: 11月 2008
オフライン
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 - 2020年7月21日 15:49:45
Scott Peterson, Machine Learning Graphics Engineer, Unity
User Avatar
Member
26 posts
Joined: 11月 2008
オフライン
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