Will Octane Ever support/have a distance Map?

3D Studio Max Plugin (Export Script Plugins developed by [gk] and KilaD; Integrated Plugin developed by Karba)
Forum rules
Please post only in English in this subforum. For alternate language discussion please go here http://render.otoy.com/forum/viewforum.php?f=18
Post Reply
Shuggster
Licensed Customer
Posts: 3
Joined: Wed Oct 02, 2019 5:39 pm

This seems to be a commonly asked for addition with requests stretching back 7-8 years, is this ever going to be a feature for Octane? In the meantime I've found an .OSL implementation, it works well with Arnold/3ds max but doesn't seem to work with Octane, code below


void rng_seed(output int rng, int seed)
{
int chash = seed;
if (chash == 0) chash = 1;
rng = chash * 891694213;
}

float rng_uniform(output int rng)
{
float res = rng / float(2147483647) * 0.5 + 0.5;
rng *= 891694213;
return res;
}

void to_unit_disk(float x, float y, output float x_out, output float y_out)
{
float r, phi;
float a = 2.0 * x - 1.0;
float b = 2.0 * y - 1.0;

if(a > -b) {
if(a > b) {
r = a;
phi = M_PI_4 *(b/a);
}
else {
r = b;
phi = M_PI_4 *(2.0 - a/b);
}
}
else {
if(a < b) {
r = -a;
phi = M_PI_4 *(4.0 + b/a);
}
else {
r = -b;
if(b != 0.0) phi = M_PI_4 *(6.0 - a/b);
else phi = 0.0;
}
}
x_out = r * cos(phi);
y_out = r * sin(phi);
}

void make_orthonormals(vector N, output vector a, output vector b)
{
if(N[0] != N[1] || N[0] != N[2]) a = cross(vector(1, 1, 1), N);
else a = cross(vector(-1, 1, 1), N);

a = normalize(a);
b = cross(N, a);
}

vector sample_cos_hemisphere(vector N, float randu, float randv)
{
vector T, B;

make_orthonormals(N, T, B);
to_unit_disk(randu, randv, randu, randv);
float costheta = sqrt(max(1.0 - randu * randu - randv * randv, 0.0));

return randu * T + randv * B + costheta * N;
}

shader Distance(
float Distance = 0.2,
int Samples = 8,
int Backface = 0,
output float Fac = 0 )
{
int i, rng;
float f, randu, randv, ray_t, hits = 0;
vector ray_P, ray_R;
float Dist;
float FDist = Distance;

f = fmod(cellnoise(P*123456.0), 1.0);
rng_seed(rng, int(f * 2147483647));

for(i = 0; i < Samples; i++) {
randu = rng_uniform(rng);
randv = rng_uniform(rng);

ray_P = P;
ray_R = sample_cos_hemisphere(N, randu, randv);
ray_t = Distance;
if (Backface > 0){ ray_R = -ray_R;}
if(trace(ray_P, ray_R, "maxdist", ray_t)){
getmessage ("trace", "hitdist" , Dist );
}else {
Dist = Distance;
}

FDist = min(FDist, Dist);
}
Fac = FDist/Distance;
}



Is there any way to get this working? In my case even a solution that just sampled a point rather than an objects surface would be great to use to drive a material mix by distance. Any help would be greatly appreciated, thank you
User avatar
jobigoud
OctaneRender Team
Posts: 250
Joined: Sat Aug 15, 2015 1:28 pm

The `trace` function is not supported at the moment in Octane OSL so this script or variants of it that shoot secondary rays randomly from the shading position and find the closest hit cannot work.

Currently the only way is to convert the mesh into a Volume SDF (Mesh Volume SDF node) and then use the Volume to texture node to read the result. This will get you the distance to the mesh from the point that is evaluating the Volume to texture texture. However it will only work in the band of voxels generated around the original surface by the Mesh Volume SDF converter (parameter: Border thickness > outside).
Shuggster
Licensed Customer
Posts: 3
Joined: Wed Oct 02, 2019 5:39 pm

Thanks for the advice, not sure this would work for me as there is quite a lot of thin geo in the scene which I'm not sure will readily convert to sdf, this approach would be for octane standalone and not in max right?
Post Reply

Return to “Autodesk 3Ds Max”