Masking all visible texture pixels that face the camera and are located inside its viewing frustum.
A 2D volume is used to store the visibility of texture pixels. After adressing the camera path with chs('camera')
, the volume's bounding box is turned into uvw
coordinates spanning across the volume. Next, the uvw
coordinates distance to the UV corrdinates of the mesh is measured with uvdist
. The according primitives and intrinsic UV coordinates on the specific primitives are returned to int pr;
and vector uv;
After initializing the mask = 0
, we only draw to voxels that lie directly on the texture islands and not in the empty space between them by making sure the dist < 1e-3
.
We obtain world positions with primuv(1, 'P', pr, uv);
and normal devices coordinates with toNDC(cam, pos);
. Normal device coordinates show the point positions as seen by the camera projected to the screen. Then the texture pixels get filtered out by consecutive conditions regarding the cameras frustum: if(p.x..)
from the viewing area between left and right of the cameras, if(p.y..)
for below the top and above the bottom and if(p.z < 0.0)
for the area in front of the camera.
The last condition that needs to be met, in order for a texture pixel to be seen is the returned hit primitive number of an intersect
-ray that is shot towards the camera. If nothing is in the way from the surface towards it if(hit_pr < 0) then this pixel is going to be seen, hence mask = 1;
.
string cam = chs('camera');
vector bb = relbbox(0, v@P);
vector uvw = set(bb.x, bb.y, 0.0);
int pr;
vector uv;
float dist = uvdist(1, 'uv', uvw, pr, uv);
int mask = 0;
if(dist < 1e-3){
vector pos = primuv(1, 'P', pr, uv);
vector p = toNDC(cam, pos);
if(p.x > 0.0 && p.x < 1.0){
if(p.y > 0.0 && p.y < 1.0){
if(p.z < 0.0){
vector nml = primuv(1, 'N', pr, uv);
matrix xform_cam = optransform(cam);
vector pos_cam = cracktransform(0,0,0,0,0, xform_cam);
vector dir_cam = pos_cam - pos;
int hit_pr = intersect(1, pos + nml * 1e-3, dir_cam,
vector(0.0), vector(0.0));
if(hit_pr < 0){
mask = 1;
}
}
}
}
}
f@vis = mask;