When rendering volume surfaces in unbounded worlds the volume stepping can produce large values. If used with a magic texture node the values can results in a Inf float which when used in a sin or cos produces a NaN. To fix this the input values are mapped into the periodic range of the sin and cos functions (-2*PI 2*PI) this stops the possibility of a Inf occurring and thus the NaN. It also improves the accuracy and smoothness of the result due to loss of precision when large values are summed with smaller ones effectively removing the parts of the smaller number (i.e. those in the -2PI to 2PI range) that result in variation of the output of sin and cos. Reviewed By: brecht Maniphest Tasks: T92036 Differential Revision: https://developer.blender.org/D12821
112 lines
2.6 KiB
Plaintext
112 lines
2.6 KiB
Plaintext
/*
|
|
* Copyright 2011-2013 Blender Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "stdcycles.h"
|
|
|
|
/* Magic */
|
|
color magic(point p, float scale, int n, float distortion)
|
|
{
|
|
float dist = distortion;
|
|
|
|
float a = mod(p.x * scale, M_2PI);
|
|
float b = mod(p.y * scale, M_2PI);
|
|
float c = mod(p.z * scale, M_2PI);
|
|
|
|
float x = sin((a + b + c) * 5.0);
|
|
float y = cos((-a + b - c) * 5.0);
|
|
float z = -cos((-a - b + c) * 5.0);
|
|
|
|
if (n > 0) {
|
|
x *= dist;
|
|
y *= dist;
|
|
z *= dist;
|
|
y = -cos(x - y + z);
|
|
y *= dist;
|
|
|
|
if (n > 1) {
|
|
x = cos(x - y - z);
|
|
x *= dist;
|
|
|
|
if (n > 2) {
|
|
z = sin(-x - y - z);
|
|
z *= dist;
|
|
|
|
if (n > 3) {
|
|
x = -cos(-x + y - z);
|
|
x *= dist;
|
|
|
|
if (n > 4) {
|
|
y = -sin(-x + y + z);
|
|
y *= dist;
|
|
|
|
if (n > 5) {
|
|
y = -cos(-x + y + z);
|
|
y *= dist;
|
|
|
|
if (n > 6) {
|
|
x = cos(x + y + z);
|
|
x *= dist;
|
|
|
|
if (n > 7) {
|
|
z = sin(x + y - z);
|
|
z *= dist;
|
|
|
|
if (n > 8) {
|
|
x = -cos(-x - y + z);
|
|
x *= dist;
|
|
|
|
if (n > 9) {
|
|
y = -sin(x - y + z);
|
|
y *= dist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dist != 0.0) {
|
|
dist *= 2.0;
|
|
x /= dist;
|
|
y /= dist;
|
|
z /= dist;
|
|
}
|
|
|
|
return color(0.5 - x, 0.5 - y, 0.5 - z);
|
|
}
|
|
|
|
shader node_magic_texture(int use_mapping = 0,
|
|
matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
int depth = 2,
|
|
float Distortion = 5.0,
|
|
float Scale = 5.0,
|
|
point Vector = P,
|
|
output float Fac = 0.0,
|
|
output color Color = 0.0)
|
|
{
|
|
point p = Vector;
|
|
|
|
if (use_mapping)
|
|
p = transform(mapping, p);
|
|
|
|
Color = magic(p, Scale, depth, Distortion);
|
|
Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
|
|
}
|