An X-Ray shader for OSL using an edge detection node

In this attempt to create an X-ray shader that highlights object edges we profit form the built-in facilities of OSL to compute derivatives.

The X-ray effect in the picture is mostly achieved by letting the meshes emit some light but more from their contours as seen from the camera.

(note that with all that transparency we need an awfull lot of samples to get a noise free result: even with 500 samples there is still noise visible in the image)

In order to determine what the contours are, we make use of OSLs built-in functions Dx() and Dy() that compute the derivatives of a function. The idea is that the derivatives for the current shading possition as seen from the camera change fastest at the contours of objects. This of course will only work reasonably well for curved objects. In the picture below we have a simple diffuse that is red when the sum of the derivatives is large. The small cube on the left has sharp edges that case an abrupt change that we cannot capture this way. The cube on the right has a bevel and a subsurface modifier added and does show edges.


shader der(
point Pos = P,
output vector dx =0,
output vector dy =0,
output float Lx = 0,
output float Ly = 0,
output float R = 0
){
dx = Dx(Pos);
dy = Dy(Pos);
Lx= length(dx);
Ly= length(dy);
R = Lx + Ly;
}

Sample node setup

The x-ray image at the beginning of this post was created with the following node setup:

Beside a mix of shaders the most important part is the texture coordinate that we take as input: Camera space is selected here. The add and multiplication nodes are there just to give us some control over the noise we want to mix in.

No comments:

Post a Comment