Node: Gabor Noise Texture #110802

Open
Charlie Jolly wants to merge 68 commits from CharlieJolly/blender:gabor into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 106 additions and 109 deletions
Showing only changes of commit 0a7de0bda7 - Show all commits

View File

@ -26,7 +26,7 @@
#define GABOR_SEED 11939
struct GaborParams {
float base_frequency;
float frequency;
float gain;
float radius;
float impulses;
@ -70,46 +70,46 @@ vector3 gabor_kernel(GaborParams gp, point omega, float phi, point position, flo
float h;
if (gp.mode == "gabor") { /* SHD_GABOR_MODE_GABOR */
h = gp.base_frequency * dot(omega, position) + phi;
h = gp.frequency * dot(omega, position) + phi;
r = vector3(cos(h), 0.0, 0.0);
}
else if (gp.mode == "phasor") { /* SHD_GABOR_MODE_PHASOR */
h = gp.base_frequency * dot(omega, position) + phi;
h = gp.frequency * dot(omega, position) + phi;
r = vector3(cos(h), sin(h), 0.0);
}
else if (gp.mode == "gabor_cross") { /* SHD_GABOR_MODE_CROSS */
h = gp.base_frequency * length(omega * position) + phi;
h = gp.frequency * length(omega * position) + phi;
r = vector3(cos(h), 0.0, 0.0);
}
else if (gp.mode == "phasor_cross") { /* SHD_GABOR_MODE_PHASOR_CROSS */
h = gp.base_frequency * length(omega * position) + phi;
h = gp.frequency * length(omega * position) + phi;
r = vector3(cos(h), sin(h), 0.0);
}
else if (gp.mode == "gabor_ring") { /* SHD_GABOR_MODE_RING */
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * length(position) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * length(position) + phi);
r = vector3(h, 0.0, 0.0) * 0.5;
;
}
else if (gp.mode == "phasor_ring") { /* SHD_GABOR_MODE_PHASOR_RING */
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * length(position) + phi);
float h2 = sin(gp.base_frequency * dot(omega, position) + phi) +
sin(gp.base_frequency * length(position) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * length(position) + phi);
float h2 = sin(gp.frequency * dot(omega, position) + phi) +
sin(gp.frequency * length(position) + phi);
r = vector3(h, h2, 0.0) * 0.5;
}
else if (gp.mode == "gabor_square") { /* SHD_GABOR_MODE_SQUARE */
vector3 positionyxz = vector3(position.y, position.x, position.z);
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * dot(omega, positionyxz) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * dot(omega, positionyxz) + phi);
r = vector3(h, 0.0, 0.0) * 0.5;
}
else if (gp.mode == "phasor_square") {
vector3 positionyxz = vector3(position.y, position.x, position.z);
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * dot(omega, positionyxz) + phi);
float h2 = sin(gp.base_frequency * dot(omega, position) + phi) +
sin(gp.base_frequency * dot(omega, positionyxz) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * dot(omega, positionyxz) + phi);
float h2 = sin(gp.frequency * dot(omega, position) + phi) +
sin(gp.frequency * dot(omega, positionyxz) + phi);
r = vector3(h, h2, 0.0) * 0.5;
}
@ -268,7 +268,7 @@ float gabor_grid_2d(output GaborParams gp, point p, float scale, int periodic)
}
GaborParams gabor_parameters(vector direction,
float base_frequency,
float frequency,
float gain,
float radius,
float impulses,
@ -294,7 +294,7 @@ GaborParams gabor_parameters(vector direction,
gp.cell_randomness = cell_randomness;
gp.gain = gain;
gp.radius = radius;
gp.base_frequency = base_frequency * M_PI;
gp.frequency = frequency * M_PI;
return gp;
}
@ -319,7 +319,7 @@ float gabor_fractal_noise(FractalParams fp,
vector3 co = p + float(use_origin_offset * i * GABOR_SEED);
float t = (dimensions == "3D") ? gabor_grid_3d(gp, fscale * co, scale, periodic) :
gabor_grid_2d(gp, fscale * co, scale, periodic);
gp.base_frequency *= fp.fre_lacunarity;
gp.frequency *= fp.fre_lacunarity;
gp.rotation -= fp.rot_lacunarity;
sum += t * amp;
maxamp += amp;
@ -344,7 +344,7 @@ float gabor_fractal_noise(FractalParams fp,
float gabor_noise(point p,
vector direction,
float scale,
float base_frequency,
float frequency,
float detail,
float roughness,
float scl_lacunarity,
@ -381,7 +381,7 @@ float gabor_noise(point p,
fp.rot_lacunarity = rot_lacunarity;
GaborParams gp = gabor_parameters(direction,
base_frequency,
frequency,
gain,
radius,
impulses,
@ -423,13 +423,13 @@ shader node_gabor_texture(int use_mapping = 0,
int use_origin_offset = 1,
vector3 Vector = vector(0, 0, 0),
float Scale = 5.0,
float BaseFrequency = 4.0,
float Detail = 0.0,
float Roughness = 0.5,
float ScaleLacunarity = 2.0,
float FrequencyLacunarity = 2.0,
float RotationLacunarity = 0.0,
float Gain = 1.0,
float Frequency = 4.0,
float Radius = 1.0,
float Impulses = 2.0,
float PhaseOffset = 0.0,
@ -450,7 +450,7 @@ shader node_gabor_texture(int use_mapping = 0,
Value = gabor_noise(p,
Direction,
Scale,
BaseFrequency,
Frequency,
Detail,
Roughness,
ScaleLacunarity,

View File

@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
#define GABOR_SEED 11939
typedef struct GaborParams {
float base_frequency;
float frequency;
float gain;
float radius;
float impulses;
@ -61,45 +61,43 @@ ccl_device float3 gabor_kernel(GaborParams gp, float3 omega, float phi, float3 p
float h;
if (gp.mode == SHD_GABOR_MODE_GABOR) {
h = gp.base_frequency * dot(omega, position) + phi;
h = gp.frequency * dot(omega, position) + phi;
r = make_float3(cos(h), 0.0f, 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR) {
h = gp.base_frequency * dot(omega, position) + phi;
h = gp.frequency * dot(omega, position) + phi;
r = make_float3(cos(h), sin(h), 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_CROSS) {
h = gp.base_frequency * len(omega * position) + phi;
h = gp.frequency * len(omega * position) + phi;
r = make_float3(cos(h), 0.0f, 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_CROSS) {
h = gp.base_frequency * len(omega * position) + phi;
h = gp.frequency * len(omega * position) + phi;
r = make_float3(cos(h), sin(h), 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_RING) {
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * len(position) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) + cos(gp.frequency * len(position) + phi);
r = make_float3(h, 0.0f, 0.0f) * 0.5f;
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_RING) {
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * len(position) + phi);
const float h2 = sin(gp.base_frequency * dot(omega, position) + phi) +
sin(gp.base_frequency * len(position) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) + cos(gp.frequency * len(position) + phi);
const float h2 = sin(gp.frequency * dot(omega, position) + phi) +
sin(gp.frequency * len(position) + phi);
r = make_float3(h, h2, 0.0f) * 0.5f;
}
else if (gp.mode == SHD_GABOR_MODE_SQUARE) {
const float3 positionyxz = make_float3(position.y, position.x, position.z);
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * dot(omega, positionyxz) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * dot(omega, positionyxz) + phi);
r = make_float3(h, 0.0f, 0.0f) * 0.5f;
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_SQUARE) {
const float3 positionyxz = make_float3(position.y, position.x, position.z);
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * dot(omega, positionyxz) + phi);
const float h2 = sin(gp.base_frequency * dot(omega, position) + phi) +
sin(gp.base_frequency * dot(omega, positionyxz) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * dot(omega, positionyxz) + phi);
const float h2 = sin(gp.frequency * dot(omega, position) + phi) +
sin(gp.frequency * dot(omega, positionyxz) + phi);
r = make_float3(h, h2, 0.0f) * 0.5f;
}
@ -280,7 +278,7 @@ ccl_device float gabor_fractal_noise(FractalParams fp,
float3 co = p + float(use_origin_offset * i * GABOR_SEED);
float t = (dimensions == 3) ? gabor_grid_3d(gp, fscale * co, scale, periodic) :
gabor_grid_2d(gp, fscale * co, scale, periodic);
gp.base_frequency *= fp.fre_lacunarity;
gp.frequency *= fp.fre_lacunarity;
gp.rotation -= fp.rot_lacunarity;
sum += t * amp;
CharlieJolly marked this conversation as resolved Outdated

Perhaps a little nitpicky but perhaps return sum * gp.bandwidth / maxamp; makes the intention a little clearer as division isn't commutative.

Perhaps a little nitpicky but perhaps `return sum * gp.bandwidth / maxamp;` makes the intention a little clearer as division isn't commutative.
maxamp += amp;
@ -301,7 +299,7 @@ ccl_device float gabor_fractal_noise(FractalParams fp,
}
ccl_device GaborParams gabor_parameters(float3 direction,
float base_frequency,
float frequency,
float gain,
float radius,
float impulses,
@ -327,7 +325,7 @@ ccl_device GaborParams gabor_parameters(float3 direction,
gp.cell_randomness = cell_randomness;
gp.gain = gain;
gp.radius = radius;
gp.base_frequency = base_frequency * M_PI_F;
gp.frequency = frequency * M_PI_F;
return gp;
}
@ -336,7 +334,7 @@ ccl_device GaborParams gabor_parameters(float3 direction,
ccl_device float gabor_noise(float3 p,
float3 direction,
float scale,
float base_frequency,
float frequency,
float detail,
float roughness,
float scl_lacunarity,
@ -370,7 +368,7 @@ ccl_device float gabor_noise(float3 p,
fp.rot_lacunarity = rot_lacunarity;
GaborParams gp = gabor_parameters(direction,
base_frequency,
frequency,
gain,
radius,
impulses,
@ -415,10 +413,10 @@ ccl_device_noinline int svm_node_tex_gabor(
uint rot_variance_offset, phase_variance_offset, rotation_offset, gain_offset,
tilt_randomness_offset, cell_randomness_offset;
uint scl_lacunarity_offset, use_normalize_offset, dimension_offset, rot_lacunarity_offset;
uint base_frequency_offset, radius_offset;
uint frequency_offset, radius_offset;
svm_unpack_node_uchar4(
node.y, &vector_in_offset, &scale_offset, &base_frequency_offset, &detail_offset);
node.y, &vector_in_offset, &scale_offset, &frequency_offset, &detail_offset);
svm_unpack_node_uchar4(node.z,
&roughness_offset,
&scl_lacunarity_offset,
@ -439,7 +437,7 @@ ccl_device_noinline int svm_node_tex_gabor(
float3 vector_in = stack_load_float3(stack, vector_in_offset);
float scale = stack_load_float_default(stack, scale_offset, defaults_node3.x);
float base_frequency = stack_load_float_default(stack, base_frequency_offset, defaults_node3.y);
float frequency = stack_load_float_default(stack, frequency_offset, defaults_node3.y);
float detail = stack_load_float_default(stack, detail_offset, defaults_node3.z);
float roughness = stack_load_float_default(stack, roughness_offset, defaults_node3.w);
@ -467,7 +465,7 @@ ccl_device_noinline int svm_node_tex_gabor(
float value = gabor_noise(vector_in,
direction,
scale,
base_frequency,
frequency,
detail,
roughness,
scl_lacunarity,

View File

@ -1236,7 +1236,7 @@ NODE_DEFINE(GaborTextureNode)
SOCKET_IN_POINT(vector, "Vector", zero_float3(), SocketType::LINK_TEXTURE_GENERATED);
SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
SOCKET_IN_FLOAT(base_frequency, "Base Frequency", 4.0f);
SOCKET_IN_FLOAT(frequency, "Frequency", 4.0f);
SOCKET_IN_FLOAT(gain, "Gain", 1.0f);
SOCKET_IN_FLOAT(detail, "Detail", 0.0f);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
@ -1279,7 +1279,7 @@ void GaborTextureNode::compile(SVMCompiler &compiler)
{
ShaderInput *vector_in = input("Vector");
ShaderInput *scale_in = input("Scale");
ShaderInput *base_frequency_in = input("Base Frequency");
ShaderInput *frequency_in = input("Frequency");
ShaderInput *detail_in = input("Detail");
ShaderInput *roughness_in = input("Roughness");
ShaderInput *scl_lacunarity_in = input("Scale Lacunarity");
@ -1302,7 +1302,7 @@ void GaborTextureNode::compile(SVMCompiler &compiler)
int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
int scale_in_stack_offset = compiler.stack_assign(scale_in);
int base_frequency_in_stack_offset = compiler.stack_assign(base_frequency_in);
int frequency_in_stack_offset = compiler.stack_assign(frequency_in);
int detail_in_stack_offset = compiler.stack_assign(detail_in);
int roughness_in_stack_offset = compiler.stack_assign(roughness_in);
int scl_lacunarity_in_stack_offset = compiler.stack_assign(scl_lacunarity_in);
@ -1325,7 +1325,7 @@ void GaborTextureNode::compile(SVMCompiler &compiler)
compiler.add_node(NODE_TEX_GABOR,
compiler.encode_uchar4(vector_stack_offset,
scale_in_stack_offset,
base_frequency_in_stack_offset,
frequency_in_stack_offset,
detail_in_stack_offset),
compiler.encode_uchar4(roughness_in_stack_offset,
scl_lacunarity_in_stack_offset,
@ -1348,7 +1348,7 @@ void GaborTextureNode::compile(SVMCompiler &compiler)
use_origin_offset);
compiler.add_node(__float_as_int(scale),
__float_as_int(base_frequency),
__float_as_int(frequency),
__float_as_int(detail),
__float_as_int(roughness));
compiler.add_node(__float_as_int(scl_lacunarity),

View File

@ -251,7 +251,7 @@ class GaborTextureNode : public TextureNode {
NODE_SOCKET_API(float3, vector)
NODE_SOCKET_API(float, scale)
NODE_SOCKET_API(float, base_frequency)
NODE_SOCKET_API(float, frequency)
NODE_SOCKET_API(float, detail)
NODE_SOCKET_API(float, roughness)
NODE_SOCKET_API(float, scl_lacunarity)

View File

@ -52,7 +52,7 @@
#define GABOR_SEED 11939
struct GaborParams {
float base_frequency;
float frequency;
float gain;
float radius;
float impulses;
@ -100,43 +100,43 @@ vec3 gabor_kernel(GaborParams gp, vec3 omega, float phi, vec3 position, float dv
float h;
if (gp.mode == SHD_GABOR_MODE_GABOR) {
h = gp.base_frequency * dot(omega, position) + phi;
h = gp.frequency * dot(omega, position) + phi;
r = vec3(cos(h), 0.0, 0.0);
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR) {
h = gp.base_frequency * dot(omega, position) + phi;
h = gp.frequency * dot(omega, position) + phi;
r = vec3(cos(h), sin(h), 0.0);
}
else if (gp.mode == SHD_GABOR_MODE_CROSS) {
h = gp.base_frequency * length(omega * position) + phi;
h = gp.frequency * length(omega * position) + phi;
r = vec3(cos(h), 0.0, 0.0);
}
CharlieJolly marked this conversation as resolved Outdated

Why are we computing the fractcal on the freqiency as opposed to the scale to make it consistent with other noise functions? Is there a good reason for that?

Why are we computing the fractcal on the freqiency as opposed to the scale to make it consistent with other noise functions? Is there a good reason for that?

This was implemented per impulse/splat rather than per texture pass. This was mentioned to me by @Hoshinova so I have this marked as a todo. The results are quite different.

This was implemented per impulse/splat rather than per texture pass. This was mentioned to me by @Hoshinova so I have this marked as a todo. The results are quite different.

Implemented fractal based on other noise functions.

Implemented fractal based on other noise functions.
else if (gp.mode == SHD_GABOR_MODE_PHASOR_CROSS) {
h = gp.base_frequency * length(omega * position) + phi;
h = gp.frequency * length(omega * position) + phi;
r = vec3(cos(h), sin(h), 0.0);
CharlieJolly marked this conversation as resolved Outdated

Why does this function return a vec3 when the third component is always zero and ignored?

Why does this function return a `vec3` when the third component is always zero and ignored?

Added note to gabor_kernel function, this is due to returning Phasor values.

Added note to gabor_kernel function, this is due to returning Phasor values.
}
else if (gp.mode == SHD_GABOR_MODE_RING) {
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * length(position) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * length(position) + phi);
r = vec3(h, 0.0, 0.0) * 0.5;
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_RING) {
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * length(position) + phi);
float h2 = sin(gp.base_frequency * dot(omega, position) + phi) +
sin(gp.base_frequency * length(position) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * length(position) + phi);
float h2 = sin(gp.frequency * dot(omega, position) + phi) +
sin(gp.frequency * length(position) + phi);
r = vec3(h, h2, 0.0) * 0.5;
}
else if (gp.mode == SHD_GABOR_MODE_SQUARE) {
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * dot(omega, position.yxz) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * dot(omega, position.yxz) + phi);
r = vec3(h, 0.0, 0.0) * 0.5;
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_SQUARE) {
h = cos(gp.base_frequency * dot(omega, position) + phi) +
cos(gp.base_frequency * dot(omega, position.yxz) + phi);
float h2 = sin(gp.base_frequency * dot(omega, position) + phi) +
sin(gp.base_frequency * dot(omega, position.yxz) + phi);
h = cos(gp.frequency * dot(omega, position) + phi) +
cos(gp.frequency * dot(omega, position.yxz) + phi);
float h2 = sin(gp.frequency * dot(omega, position) + phi) +
sin(gp.frequency * dot(omega, position.yxz) + phi);
r = vec3(h, h2, 0.0) * 0.5;
}
@ -303,7 +303,7 @@ float gabor_grid_2d(GaborParams gp, vec3 p, float scale, int periodic)
/* Gabor parameters. Impulses are clamped as these directly impact performance. */
GaborParams gabor_parameters(vec3 direction,
float base_frequency,
float frequency,
float gain,
float radius,
float impulses,
@ -329,7 +329,7 @@ GaborParams gabor_parameters(vec3 direction,
gp.cell_randomness = cell_randomness;
gp.gain = gain;
gp.radius = radius;
gp.base_frequency = base_frequency * M_PI;
gp.frequency = frequency * M_PI;
return gp;
}
@ -359,7 +359,7 @@ float gabor_fractal_noise(FractalParams fp,
vec3 co = p + float(use_origin_offset * i * GABOR_SEED);
float t = (dimensions == 3) ? gabor_grid_3d(gp, fscale * co, scale, periodic) :
gabor_grid_2d(gp, fscale * co, scale, periodic);
gp.base_frequency *= fp.fre_lacunarity;
gp.frequency *= fp.fre_lacunarity;
gp.rotation -= fp.rot_lacunarity;
sum += t * amp;
maxamp += amp;
@ -383,13 +383,13 @@ float gabor_fractal_noise(FractalParams fp,
void node_tex_gabor(vec3 co,
float scale,
float base_frequency,
float gain,
float detail,
float roughness,
float scl_lacunarity,
float fre_lacunarity,
float rot_lacunarity,
float frequency,
float radius,
float impulses,
float phase,
@ -423,7 +423,7 @@ void node_tex_gabor(vec3 co,
/* Set Gabor params. */
GaborParams gp = gabor_parameters(direction,
base_frequency,
frequency,
gain,
radius,
impulses,

View File

@ -48,11 +48,6 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>("Value").no_muted_links();
b.add_input<decl::Vector>("Vector").implicit_field(implicit_field_inputs::position);
b.add_input<decl::Float>("Scale").min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>("Base Frequency")
.min(-100.0f)
.max(100.0f)
.default_value(4.0f)
.description("Frequency for the kernel shape, higher values provides more detail");
b.add_input<decl::Float>("Gain").min(-10.0f).max(10.0f).default_value(1.0f);
PanelDeclarationBuilder &fractal = b.add_panel("Fractal").default_closed(true).draw_buttons(
[](uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) {
@ -81,6 +76,11 @@ static void node_declare(NodeDeclarationBuilder &b)
"The difference between the kernel rotation of each consecutive octave, does not work "
"when Anisotropic is set to 1");
PanelDeclarationBuilder &kernel = b.add_panel("Kernel").default_closed(true);
kernel.add_input<decl::Float>("Frequency")
.min(-100.0f)
.max(100.0f)
.default_value(4.0f)
.description("Frequency for the kernel shape, higher values provides more detail");
kernel.add_input<decl::Float>("Radius")
.min(0.0f)
.max(1.0f)
@ -190,7 +190,7 @@ static int node_shader_gpu_tex_gabor(GPUMaterial *mat,
#define GABOR_SEED 11939
typedef struct GaborParams {
float base_frequency;
float frequency;
float gain;
float radius;
float impulses;
@ -235,45 +235,45 @@ static float3 gabor_kernel(const GaborParams gp,
float h;
if (gp.mode == SHD_GABOR_MODE_GABOR) {
h = gp.base_frequency * math::dot(omega, position) + phi;
h = gp.frequency * math::dot(omega, position) + phi;
r = float3(math::cos(h), 0.0f, 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR) {
h = gp.base_frequency * math::dot(omega, position) + phi;
h = gp.frequency * math::dot(omega, position) + phi;
r = float3(math::cos(h), math::sin(h), 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_CROSS) {
h = gp.base_frequency * math::length(omega * position) + phi;
h = gp.frequency * math::length(omega * position) + phi;
r = float3(math::cos(h), 0.0f, 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_CROSS) {
h = gp.base_frequency * math::length(omega * position) + phi;
h = gp.frequency * math::length(omega * position) + phi;
r = float3(math::cos(h), math::sin(h), 0.0f);
}
else if (gp.mode == SHD_GABOR_MODE_RING) {
h = math::cos(gp.base_frequency * math::dot(omega, position) + phi) +
math::cos(gp.base_frequency * math::length(position) + phi);
h = math::cos(gp.frequency * math::dot(omega, position) + phi) +
math::cos(gp.frequency * math::length(position) + phi);
r = float3(h, 0.0f, 0.0f) * 0.5f;
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_RING) {
h = math::cos(gp.base_frequency * math::dot(omega, position) + phi) +
math::cos(gp.base_frequency * math::length(position) + phi);
const float h2 = math::sin(gp.base_frequency * math::dot(omega, position) + phi) +
math::sin(gp.base_frequency * math::length(position) + phi);
h = math::cos(gp.frequency * math::dot(omega, position) + phi) +
math::cos(gp.frequency * math::length(position) + phi);
const float h2 = math::sin(gp.frequency * math::dot(omega, position) + phi) +
math::sin(gp.frequency * math::length(position) + phi);
r = float3(h, h2, 0.0f) * 0.5f;
}
else if (gp.mode == SHD_GABOR_MODE_SQUARE) {
const float3 positionyxz = float3(position.y, position.x, position.z);
h = math::cos(gp.base_frequency * math::dot(omega, position) + phi) +
math::cos(gp.base_frequency * math::dot(omega, positionyxz) + phi);
h = math::cos(gp.frequency * math::dot(omega, position) + phi) +
math::cos(gp.frequency * math::dot(omega, positionyxz) + phi);
r = float3(h, 0.0f, 0.0f) * 0.5f;
}
else if (gp.mode == SHD_GABOR_MODE_PHASOR_SQUARE) {
const float3 positionyxz = float3(position.y, position.x, position.z);
h = math::cos(gp.base_frequency * math::dot(omega, position) + phi) +
math::cos(gp.base_frequency * math::dot(omega, positionyxz) + phi);
const float h2 = math::sin(gp.base_frequency * math::dot(omega, position) + phi) +
math::sin(gp.base_frequency * math::dot(omega, positionyxz) + phi);
h = math::cos(gp.frequency * math::dot(omega, position) + phi) +
math::cos(gp.frequency * math::dot(omega, positionyxz) + phi);
const float h2 = math::sin(gp.frequency * math::dot(omega, position) + phi) +
math::sin(gp.frequency * math::dot(omega, positionyxz) + phi);
r = float3(h, h2, 0.0f) * 0.5f;
}
@ -459,7 +459,7 @@ static float gabor_fractal_noise(FractalParams fp,
float3 co = p + float(use_origin_offset * i * GABOR_SEED);
const float t = (dimensions == 3) ? gabor_grid_3d(gp, fscale * co, scale, periodic) :
gabor_grid_2d(gp, fscale * co, scale, periodic);
gp.base_frequency *= fp.fre_lacunarity;
gp.frequency *= fp.fre_lacunarity;
gp.rotation -= fp.rot_lacunarity;
sum += t * amp;
maxamp += amp;
@ -481,7 +481,7 @@ static float gabor_fractal_noise(FractalParams fp,
/* Set parameters used by Gabor noise. */
static GaborParams gabor_parameters(float3 direction,
float base_frequency,
float frequency,
float gain,
float radius,
float impulses,
@ -507,14 +507,14 @@ static GaborParams gabor_parameters(float3 direction,
gp.cell_randomness = cell_randomness;
gp.gain = gain;
gp.radius = radius;
gp.base_frequency = base_frequency * float(M_PI);
gp.frequency = frequency * float(M_PI);
return gp;
}
static float gabor_noise(const float3 p,
const float3 direction,
const float scale,
const float base_frequency,
const float frequency,
const float detail,
const float roughness,
const float scl_lacunarity,
@ -548,7 +548,7 @@ static float gabor_noise(const float3 p,
fp.rot_lacunarity = rot_lacunarity;
GaborParams gp = gabor_parameters(direction,
base_frequency,
frequency,
gain,
radius,
impulses,
@ -583,13 +583,13 @@ static mf::Signature gabor_signature(const char *name)
mf::SignatureBuilder builder{name, signature};
builder.single_input<float3>("Vector");
builder.single_input<float>("Scale");
builder.single_input<float>("Base Frequency");
builder.single_input<float>("Gain");
builder.single_input<float>("Detail");
builder.single_input<float>("Roughness");
builder.single_input<float>("Scale Lacunarity");
builder.single_input<float>("Frequency Lacunarity");
builder.single_input<float>("Rotation Lacunarity");
builder.single_input<float>("Frequency");
builder.single_input<float>("Radius");
builder.single_input<float>("Impulses");
builder.single_input<float>("Phase Offset");
@ -631,8 +631,6 @@ class GaborNoiseFunction : public mf::MultiFunction {
int param = 0;
const VArray<float3> &vector = params.readonly_single_input<float3>(param++, "Vector");
const VArray<float> &scale = params.readonly_single_input<float>(param++, "Scale");
const VArray<float> &base_frequency = params.readonly_single_input<float>(param++,
"Base Frequency");
const VArray<float> &gain = params.readonly_single_input<float>(param++, "Gain");
const VArray<float> &detail = params.readonly_single_input<float>(param++, "Detail");
const VArray<float> &roughness = params.readonly_single_input<float>(param++, "Roughness");
@ -642,6 +640,7 @@ class GaborNoiseFunction : public mf::MultiFunction {
param++, "Frequency Lacunarity");
const VArray<float> &rot_lacunarity = params.readonly_single_input<float>(
param++, "Rotation Lacunarity");
const VArray<float> &frequency = params.readonly_single_input<float>(param++, "Frequency");
const VArray<float> &radius = params.readonly_single_input<float>(param++, "Radius");
const VArray<float> &impulses = params.readonly_single_input<float>(param++, "Impulses");
@ -666,7 +665,7 @@ class GaborNoiseFunction : public mf::MultiFunction {
r_value[i] = gabor_noise(vector[i],
direction[i],
scale[i],
base_frequency[i],
frequency[i],
detail[i],
roughness[i],
scale_lacunarity[i],