虽然Octane有flakes的OSL预设,不过默认的不能控制flakes贴图的投射模式。

新建一个OSL节点,并把以下代码复制替换进去,然后点击上方的Compile按钮即可。

shader flakes
(
    point position = P,
    float scale = 1 [[ float min = 1e-4, float max = 1e3, float sliderexponent = 4 ]],
    float flake_size = 0.5 [[ string description = "Relative size of the flakes",
        float min = 0, float max = 10 ]],
    float flake_size_variance = 0.0 [[ string description = "0.0 makes all flakes the same size, 1.0 assigns random size between 0 and the given flake size",
        float min = 0, float max = 1 ]],
    float strength = 0.3 [[ string description = "The strength of the normal map",
        float min = 0, float max = .5 ]],
	output color cOut = color(0.5, 0.5, 1.0)
)
{
    point uvw = position / scale;
    float safe_flake_size_variance = clamp(flake_size_variance, 0, 1.0);
    point base = floor(uvw);

    point nearestFlakePos = point(0.0, 0.0, 1.0);
    float bestDistance = 99;
    for (float cellx = -1.5; cellx < 1; cellx += 1.0)
    {
        for (float celly = -1.5; celly < 1; celly += 1.0)
        {
            for (float cellz = -1.5; cellz < 1; cellz += 1.0)
            {
                point cellCenter = base + point(cellx, celly, cellz);

                cellCenter += (vector) cellnoise(cellCenter);

                float cellDistance = distance(uvw, cellCenter);
                float maxDistance = flake_size;
                if (cellDistance < maxDistance)
                {
                    float uSize = cellnoise(cellCenter + vector(-600, 600, 600));
                    maxDistance -= flake_size_variance * uSize * flake_size;
                    if (cellDistance < maxDistance)
                    {
                        if (cellDistance < flake_size && cellDistance < bestDistance)
                        {
                            bestDistance = cellDistance;
                            nearestFlakePos = cellCenter;
                        }
                    }
                }
            }
        }
    }

    if (bestDistance != 99)
    {
        vector random = cellnoise(nearestFlakePos);
        float ang = random[0] * M_PI * 2;
        // sample disk, non-uniform: more densely near the origin
        vector distortion = vector(sin(ang), cos(ang), 0)
                            * sqrt(-2 * log(1 - .999 * random[1]));
        cOut = normalize(vector(0, 0, 1) + distortion * strength) * .5 + .5;
    }
}

 

参考:

https://render.otoy.com/forum/viewtopic.php?f=9&t=75761&p=389476&hilit=osl#p389476
https://docs.chaosgroup.com/display/OSLShaders/Flakes+normal+map