Skip to content

Wavey patterns

wavey patterns

Simple wave

OpenCL
#bind layer uv? float2
#bind layer !&dst

#bind parm scale float val=200
#bind parm phase float val=0

@KERNEL
{
    float2 uv = @uv;
    if(!@uv.bound){
        uv = @P; 
    }

    // Create wave pattern
    float wave = sin(uv.x * @scale + @phase);

    @dst.set(wave);
}

Rotated wave

Vanilla OpenCL does not have many mathematical functions built in. SideFX team have build helping functions for matrix operations but for this, simple rotation we could just utilise simple sin() and cos() functions to apply rotations.

OpenCL
#bind layer uv? float2 
#bind layer !&dst float 

#bind parm scale float val=200
#bind parm phase float val=0
#bind parm rotation float val=45

// Function to create a wave pattern based on UV coordinates
float wave(float2 uv, float scale, float phase, float rotation) {
    // Convert rotation to radians
    float rad = radians(rotation);

    // Calculate the rotated UVs
    float u = uv.x * cos(rad) - uv.y * sin(rad);
    float v = uv.x * sin(rad) + uv.y * cos(rad);

    // Create the wave pattern
    float wave = sin(u * scale + phase);

    return wave;
}

@KERNEL
{
    float2 uv = @uv;
    if (!@uv.bound) {
        uv = @P; 
    }

    float result = wave(uv, @scale, @phase, @rotation);

    @dst.set(result);
}

Noised wave

To make our wave more interesting, we could apply some noise. But, as I have mentioned above, vanilla opencl is quite bare and it does not provide any build-in noises like a common gradient noise Perlin Noise. Implementing it on our own might be overwhelmin, therefore we could piggyback on SideFX pre-built functions from mtlx_noise_internal.h like

mx_perlin_noise_float_2(float2 p, int2 per)
mx_perlin_noise_float_3(float3 p, int3 per)
mx_perlin_noise_float3_2(float2 p, int2 per)
mx_perlin_noise_float3_3(float3 p, int3 per)
OpenCL
#bind layer uv? float2
#bind layer !&dst float 

#bind parm scale float val=200
#bind parm phase float val=0
#bind parm rotation float val=45
#bind parm distortion float val=0.6

#import "mtlx_noise_internal.h"

// Function to create a wave pattern with distortion
float wave(float2 uv, float scale, float phase, float rotation, float distortion) {
    // Convert rotation to radians
    float rad = radians(rotation);

    // Calculate the rotated UVs
    float u = uv.x * cos(rad) - uv.y * sin(rad);
    float v = uv.x * sin(rad) + uv.y * cos(rad);

    // Apply noise for distortion using Perlin noise
    float noiseValue = mx_perlin_noise_float_2((float2)(u, v), (int2)(0, 0)) * distortion;

    // Create the wave pattern with distortion
    float wave = sin((u + noiseValue) * scale + phase);

    return wave;
}

@KERNEL
{
    float2 uv = @uv;
    if (!@uv.bound) {
        // Convert @P from range [-1, 1] to [0, 1]
        uv = (@P + 1.0f) * 0.5f; 
    }

    float result = wave(uv, @scale, @phase, @rotation, @distortion);

    @dst.set(result);
}

You can grab file with those examples,