Nodes: Optimize Gabor noise with early exit
Optimize the Gabor noise texture code with an early exit for points that are further away from the kernel center. This was already done for the kernel, but is now being done earlier before computing the weight, so its computation is now skipped. Thanks to Charlie Jolly for the suggestion.
This commit is contained in:
@@ -60,13 +60,7 @@
|
||||
* normalization", to ensure a zero mean, which should help with normalization. */
|
||||
vector2 compute_2d_gabor_kernel(vector2 position, float frequency, float orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
float distance_squared = dot(position, position);
|
||||
if (distance_squared >= 1.0) {
|
||||
return vector2(0.0, 0.0);
|
||||
}
|
||||
|
||||
float hann_window = 0.5 + 0.5 * cos(M_PI * distance_squared);
|
||||
float gaussian_envelop = exp(-M_PI * distance_squared);
|
||||
float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -130,6 +124,12 @@ vector2 compute_2d_gabor_noise_cell(
|
||||
vector2 kernel_center = hash_vector3_to_vector2(seed_for_kernel_center);
|
||||
vector2 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (dot(position_in_kernel_space, position_in_kernel_space) >= 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
float weight = hash_vector3_to_float(seed_for_weight) < 0.5 ? -1.0 : 1.0;
|
||||
@@ -169,13 +169,7 @@ vector2 compute_2d_gabor_noise(vector2 coordinates,
|
||||
* vector, so we just need to scale it by the frequency value. */
|
||||
vector2 compute_3d_gabor_kernel(vector3 position, float frequency, vector3 orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
float distance_squared = dot(position, position);
|
||||
if (distance_squared >= 1.0) {
|
||||
return vector2(0.0, 0.0);
|
||||
}
|
||||
|
||||
float hann_window = 0.5 + 0.5 * cos(M_PI * distance_squared);
|
||||
float gaussian_envelop = exp(-M_PI * distance_squared);
|
||||
float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -242,6 +236,12 @@ vector2 compute_3d_gabor_noise_cell(
|
||||
vector3 kernel_center = hash_vector4_to_vector3(seed_for_kernel_center);
|
||||
vector3 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (dot(position_in_kernel_space, position_in_kernel_space) >= 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
float weight = hash_vector4_to_float(seed_for_weight) < 0.5 ? -1.0 : 1.0;
|
||||
|
||||
@@ -57,13 +57,7 @@ CCL_NAMESPACE_BEGIN
|
||||
* normalization", to ensure a zero mean, which should help with normalization. */
|
||||
ccl_device float2 compute_2d_gabor_kernel(float2 position, float frequency, float orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
float distance_squared = dot(position, position);
|
||||
if (distance_squared >= 1.0f) {
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
float hann_window = 0.5f + 0.5f * cosf(M_PI_F * distance_squared);
|
||||
float gaussian_envelop = expf(-M_PI_F * distance_squared);
|
||||
float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -127,6 +121,12 @@ ccl_device float2 compute_2d_gabor_noise_cell(
|
||||
float2 kernel_center = hash_float3_to_float2(seed_for_kernel_center);
|
||||
float2 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (dot(position_in_kernel_space, position_in_kernel_space) >= 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
float weight = hash_float3_to_float(seed_for_weight) < 0.5f ? -1.0f : 1.0f;
|
||||
@@ -166,13 +166,7 @@ ccl_device float2 compute_2d_gabor_noise(float2 coordinates,
|
||||
* vector, so we just need to scale it by the frequency value. */
|
||||
ccl_device float2 compute_3d_gabor_kernel(float3 position, float frequency, float3 orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
float distance_squared = dot(position, position);
|
||||
if (distance_squared >= 1.0f) {
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
float hann_window = 0.5f + 0.5f * cosf(M_PI_F * distance_squared);
|
||||
float gaussian_envelop = expf(-M_PI_F * distance_squared);
|
||||
float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -239,6 +233,12 @@ ccl_device float2 compute_3d_gabor_noise_cell(
|
||||
float3 kernel_center = hash_float4_to_float3(seed_for_kernel_center);
|
||||
float3 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (dot(position_in_kernel_space, position_in_kernel_space) >= 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
float weight = hash_float4_to_float(seed_for_weight) < 0.5f ? -1.0f : 1.0f;
|
||||
|
||||
@@ -2108,13 +2108,7 @@ static float2 compute_2d_gabor_kernel(const float2 position,
|
||||
const float frequency,
|
||||
const float orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
const float distance_squared = math::dot(position, position);
|
||||
if (distance_squared >= 1.0f) {
|
||||
return float2(0.0f);
|
||||
}
|
||||
|
||||
const float distance_squared = math::length_squared(position);
|
||||
const float hann_window = 0.5f + 0.5f * math::cos(math::numbers::pi * distance_squared);
|
||||
const float gaussian_envelop = math::exp(-math::numbers::pi * distance_squared);
|
||||
const float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -2183,6 +2177,12 @@ static float2 compute_2d_gabor_noise_cell(const float2 cell,
|
||||
const float2 kernel_center = noise::hash_float_to_float2(seed_for_kernel_center);
|
||||
const float2 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (math::length_squared(position_in_kernel_space) >= 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
const float weight = noise::hash_float_to_float(seed_for_weight) < 0.5f ? -1.0f : 1.0f;
|
||||
@@ -2224,13 +2224,7 @@ static float2 compute_3d_gabor_kernel(const float3 position,
|
||||
const float frequency,
|
||||
const float3 orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
const float distance_squared = math::dot(position, position);
|
||||
if (distance_squared >= 1.0f) {
|
||||
return float2(0.0f);
|
||||
}
|
||||
|
||||
const float distance_squared = math::length_squared(position);
|
||||
const float hann_window = 0.5f + 0.5f * math::cos(math::numbers::pi * distance_squared);
|
||||
const float gaussian_envelop = math::exp(-math::numbers::pi * distance_squared);
|
||||
const float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -2305,6 +2299,12 @@ static float2 compute_3d_gabor_noise_cell(const float3 cell,
|
||||
const float3 kernel_center = noise::hash_float_to_float3(seed_for_kernel_center);
|
||||
const float3 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (math::length_squared(position_in_kernel_space) >= 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
const float weight = noise::hash_float_to_float(seed_for_weight) < 0.5f ? -1.0f : 1.0f;
|
||||
|
||||
@@ -60,13 +60,7 @@
|
||||
* normalization", to ensure a zero mean, which should help with normalization. */
|
||||
vec2 compute_2d_gabor_kernel(vec2 position, float frequency, float orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
float distance_squared = length_squared(position);
|
||||
if (distance_squared >= 1.0) {
|
||||
return vec2(0.0);
|
||||
}
|
||||
|
||||
float hann_window = 0.5 + 0.5 * cos(M_PI * distance_squared);
|
||||
float gaussian_envelop = exp(-M_PI * distance_squared);
|
||||
float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -130,6 +124,12 @@ vec2 compute_2d_gabor_noise_cell(
|
||||
vec2 kernel_center = hash_vec3_to_vec2(seed_for_kernel_center);
|
||||
vec2 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (length_squared(position_in_kernel_space) >= 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
float weight = hash_vec3_to_float(seed_for_weight) < 0.5 ? -1.0 : 1.0;
|
||||
@@ -153,8 +153,10 @@ vec2 compute_2d_gabor_noise(vec2 coordinates,
|
||||
for (int j = -1; j <= 1; j++) {
|
||||
for (int i = -1; i <= 1; i++) {
|
||||
vec2 cell_offset = vec2(i, j);
|
||||
|
||||
vec2 current_cell_position = cell_position + cell_offset;
|
||||
vec2 position_in_cell_space = local_position - cell_offset;
|
||||
|
||||
sum += compute_2d_gabor_noise_cell(
|
||||
current_cell_position, position_in_cell_space, frequency, isotropy, base_orientation);
|
||||
}
|
||||
@@ -169,13 +171,7 @@ vec2 compute_2d_gabor_noise(vec2 coordinates,
|
||||
* vector, so we just need to scale it by the frequency value. */
|
||||
vec2 compute_3d_gabor_kernel(vec3 position, float frequency, vec3 orientation)
|
||||
{
|
||||
/* The kernel is windowed beyond the unit distance, so early exist with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
float distance_squared = length_squared(position);
|
||||
if (distance_squared >= 1.0) {
|
||||
return vec2(0.0);
|
||||
}
|
||||
|
||||
float hann_window = 0.5 + 0.5 * cos(M_PI * distance_squared);
|
||||
float gaussian_envelop = exp(-M_PI * distance_squared);
|
||||
float windowed_gaussian_envelope = gaussian_envelop * hann_window;
|
||||
@@ -240,6 +236,12 @@ vec2 compute_3d_gabor_noise_cell(
|
||||
vec3 kernel_center = hash_vec4_to_vec3(seed_for_kernel_center);
|
||||
vec3 position_in_kernel_space = position - kernel_center;
|
||||
|
||||
/* The kernel is windowed beyond the unit distance, so early exit with a zero for points that
|
||||
* are further than a unit radius. */
|
||||
if (length_squared(position_in_kernel_space) >= 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We either add or subtract the Gabor kernel based on a Bernoulli distribution of equal
|
||||
* probability. */
|
||||
float weight = hash_vec4_to_float(seed_for_weight) < 0.5 ? -1.0 : 1.0;
|
||||
|
||||
Reference in New Issue
Block a user