Moved and re-implemented gradient

This commit is contained in:
Martin Opat 2025-01-15 14:45:38 +01:00
parent b700216186
commit 7fa2954e17
2 changed files with 27 additions and 30 deletions

View File

@ -4,20 +4,6 @@
#include <stdio.h> #include <stdio.h>
// Samples the voxel nearest to the given coordinates.
__device__ float sampleVolumeNearest(float* volumeData, const int volW, const int volH, const int volD, int vx, int vy, int vz) {
// x <-> height, y <-> width, z <-> depth <--- So far this is the best one
if (vx < 0) vx = 0;
if (vy < 0) vy = 0;
if (vz < 0) vz = 0;
if (vx >= volH) vx = volH - 1;
if (vy >= volW) vy = volW - 1;
if (vz >= volD) vz = volD - 1;
int idx = vz * volW * volH + vx * volW + vy;
return volumeData[idx];
}
// tri-linear interpolation - ready if necessary (but no visible improvement for full volume) // tri-linear interpolation - ready if necessary (but no visible improvement for full volume)
__device__ float sampleVolumeTrilinear(float* volumeData, const int volW, const int volH, const int volD, float fx, float fy, float fz) { __device__ float sampleVolumeTrilinear(float* volumeData, const int volW, const int volH, const int volD, float fx, float fy, float fz) {
int ix = (int)floorf(fx); int ix = (int)floorf(fx);

View File

@ -1,29 +1,40 @@
#include "mat.h" #include "mat.h"
#include "consts.h"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
using namespace std; using namespace std;
__device__ Vec3 computeGradient(float* volumeData, const int volW, const int volH, const int volD, int x, int y, int z) { // Samples the voxel nearest to the given coordinates.
// Finite difference for partial derivatives. __device__ float sampleVolumeNearest(float* volumeData, const int volW, const int volH, const int volD, int vx, int vy, int vz) {
// For boundary voxels - clamp to the boundary. // For boundary voxels - clamp to the boundary.
if (vx < 0) vx = 0;
if (vy < 0) vy = 0;
if (vz < 0) vz = 0;
if (vx >= volH) vx = volH - 1;
if (vy >= volW) vy = volW - 1;
if (vz >= volD) vz = volD - 1;
int xm = max(x - 1, 0); // x <-> height, y <-> width, z <-> depth
int xp = min(x + 1, volH - 1); int idx = vz * volW * volH + vx * volW + vy;
int ym = max(y - 1, 0); return volumeData[idx];
int yp = min(y + 1, volW - 1); }
int zm = max(z - 1, 0);
int zp = min(z + 1, volD - 1);
// Note: Assuming data is linearized (idx = z * W * H + x * W + y;) TODO: Unlinearize if data not linear __device__ Vec3 computeGradient(float* volumeData, const int volW, const int volH, const int volD, int vx, int vy, int vz) {
float gx = volumeData[z * volW * volH + xp * volW + y] // Finite difference for partial derivatives.
- volumeData[z * volW * volH + xm * volW + y];
float gy = volumeData[z * volW * volH + x * volW + yp]
- volumeData[z * volW * volH + x * volW + ym];
float gz = volumeData[zp * volW * volH + x * volW + y ]
- volumeData[zm * volW * volH + x * volW + y ];
return Vec3::init(gx, gy, gz);
float dfdx = (sampleVolumeNearest(volumeData, VOLUME_WIDTH, VOLUME_HEIGHT, VOLUME_DEPTH, vx + 1, vy, vz) -
sampleVolumeNearest(volumeData, VOLUME_WIDTH, VOLUME_HEIGHT, VOLUME_DEPTH, vx - 1, vy, vz)) / (2.0f * DLAT); // x => height => lat
float dfdy = (sampleVolumeNearest(volumeData, VOLUME_WIDTH, VOLUME_HEIGHT, VOLUME_DEPTH, vx, vy + 1, vz) -
sampleVolumeNearest(volumeData, VOLUME_WIDTH, VOLUME_HEIGHT, VOLUME_DEPTH, vx, vy - 1, vz)) / (2.0f * DLON); // y => width => lon
float dfdz = (sampleVolumeNearest(volumeData, VOLUME_WIDTH, VOLUME_HEIGHT, VOLUME_DEPTH, vx, vy, vz + 1) -
sampleVolumeNearest(volumeData, VOLUME_WIDTH, VOLUME_HEIGHT, VOLUME_DEPTH, vx, vy, vz - 1)) / (2.0f * DLEV);
return Vec3::init(dfdx, dfdy, dfdz);
}; };
// TESTING: haven't tested this function at all tbh // TESTING: haven't tested this function at all tbh