We run into float precision issues here, clamp the number of octaves to one less, which has little to no visual difference. This was empirically determined to work up to 16 before, but with additional inputs like roughness only 15 appears to work. Also adds misisng clamp for the geometry nodes implementation.
203 lines
4.5 KiB
C
203 lines
4.5 KiB
C
/*
|
|
* 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 "vector2.h"
|
|
#include "vector4.h"
|
|
|
|
#define vector3 point
|
|
|
|
float safe_noise(float p)
|
|
{
|
|
float f = noise("noise", p);
|
|
if (isinf(f))
|
|
return 0.5;
|
|
return f;
|
|
}
|
|
|
|
float safe_noise(vector2 p)
|
|
{
|
|
float f = noise("noise", p.x, p.y);
|
|
if (isinf(f))
|
|
return 0.5;
|
|
return f;
|
|
}
|
|
|
|
float safe_noise(vector3 p)
|
|
{
|
|
float f = noise("noise", p);
|
|
if (isinf(f))
|
|
return 0.5;
|
|
return f;
|
|
}
|
|
|
|
float safe_noise(vector4 p)
|
|
{
|
|
float f = noise("noise", vector3(p.x, p.y, p.z), p.w);
|
|
if (isinf(f))
|
|
return 0.5;
|
|
return f;
|
|
}
|
|
|
|
float safe_snoise(float p)
|
|
{
|
|
float f = noise("snoise", p);
|
|
if (isinf(f))
|
|
return 0.0;
|
|
return f;
|
|
}
|
|
|
|
float safe_snoise(vector2 p)
|
|
{
|
|
float f = noise("snoise", p.x, p.y);
|
|
if (isinf(f))
|
|
return 0.0;
|
|
return f;
|
|
}
|
|
|
|
float safe_snoise(vector3 p)
|
|
{
|
|
float f = noise("snoise", p);
|
|
if (isinf(f))
|
|
return 0.0;
|
|
return f;
|
|
}
|
|
|
|
float safe_snoise(vector4 p)
|
|
{
|
|
float f = noise("snoise", vector3(p.x, p.y, p.z), p.w);
|
|
if (isinf(f))
|
|
return 0.0;
|
|
return f;
|
|
}
|
|
|
|
/* The fractal_noise functions are all exactly the same except for the input type. */
|
|
float fractal_noise(float p, float details, float roughness)
|
|
{
|
|
float fscale = 1.0;
|
|
float amp = 1.0;
|
|
float maxamp = 0.0;
|
|
float sum = 0.0;
|
|
float octaves = clamp(details, 0.0, 15.0);
|
|
int n = (int)octaves;
|
|
for (int i = 0; i <= n; i++) {
|
|
float t = safe_noise(fscale * p);
|
|
sum += t * amp;
|
|
maxamp += amp;
|
|
amp *= clamp(roughness, 0.0, 1.0);
|
|
fscale *= 2.0;
|
|
}
|
|
float rmd = octaves - floor(octaves);
|
|
if (rmd != 0.0) {
|
|
float t = safe_noise(fscale * p);
|
|
float sum2 = sum + t * amp;
|
|
sum /= maxamp;
|
|
sum2 /= maxamp + amp;
|
|
return (1.0 - rmd) * sum + rmd * sum2;
|
|
}
|
|
else {
|
|
return sum / maxamp;
|
|
}
|
|
}
|
|
|
|
/* The fractal_noise functions are all exactly the same except for the input type. */
|
|
float fractal_noise(vector2 p, float details, float roughness)
|
|
{
|
|
float fscale = 1.0;
|
|
float amp = 1.0;
|
|
float maxamp = 0.0;
|
|
float sum = 0.0;
|
|
float octaves = clamp(details, 0.0, 15.0);
|
|
int n = (int)octaves;
|
|
for (int i = 0; i <= n; i++) {
|
|
float t = safe_noise(fscale * p);
|
|
sum += t * amp;
|
|
maxamp += amp;
|
|
amp *= clamp(roughness, 0.0, 1.0);
|
|
fscale *= 2.0;
|
|
}
|
|
float rmd = octaves - floor(octaves);
|
|
if (rmd != 0.0) {
|
|
float t = safe_noise(fscale * p);
|
|
float sum2 = sum + t * amp;
|
|
sum /= maxamp;
|
|
sum2 /= maxamp + amp;
|
|
return (1.0 - rmd) * sum + rmd * sum2;
|
|
}
|
|
else {
|
|
return sum / maxamp;
|
|
}
|
|
}
|
|
|
|
/* The fractal_noise functions are all exactly the same except for the input type. */
|
|
float fractal_noise(vector3 p, float details, float roughness)
|
|
{
|
|
float fscale = 1.0;
|
|
float amp = 1.0;
|
|
float maxamp = 0.0;
|
|
float sum = 0.0;
|
|
float octaves = clamp(details, 0.0, 15.0);
|
|
int n = (int)octaves;
|
|
for (int i = 0; i <= n; i++) {
|
|
float t = safe_noise(fscale * p);
|
|
sum += t * amp;
|
|
maxamp += amp;
|
|
amp *= clamp(roughness, 0.0, 1.0);
|
|
fscale *= 2.0;
|
|
}
|
|
float rmd = octaves - floor(octaves);
|
|
if (rmd != 0.0) {
|
|
float t = safe_noise(fscale * p);
|
|
float sum2 = sum + t * amp;
|
|
sum /= maxamp;
|
|
sum2 /= maxamp + amp;
|
|
return (1.0 - rmd) * sum + rmd * sum2;
|
|
}
|
|
else {
|
|
return sum / maxamp;
|
|
}
|
|
}
|
|
|
|
/* The fractal_noise functions are all exactly the same except for the input type. */
|
|
float fractal_noise(vector4 p, float details, float roughness)
|
|
{
|
|
float fscale = 1.0;
|
|
float amp = 1.0;
|
|
float maxamp = 0.0;
|
|
float sum = 0.0;
|
|
float octaves = clamp(details, 0.0, 15.0);
|
|
int n = (int)octaves;
|
|
for (int i = 0; i <= n; i++) {
|
|
float t = safe_noise(fscale * p);
|
|
sum += t * amp;
|
|
maxamp += amp;
|
|
amp *= clamp(roughness, 0.0, 1.0);
|
|
fscale *= 2.0;
|
|
}
|
|
float rmd = octaves - floor(octaves);
|
|
if (rmd != 0.0) {
|
|
float t = safe_noise(fscale * p);
|
|
float sum2 = sum + t * amp;
|
|
sum /= maxamp;
|
|
sum2 /= maxamp + amp;
|
|
return (1.0 - rmd) * sum + rmd * sum2;
|
|
}
|
|
else {
|
|
return sum / maxamp;
|
|
}
|
|
}
|
|
|
|
#undef vector3
|