Shader to add noise to a sphere

Godot Version

4.3

Question

Shader to add noise to a sphere

Hello, there.
I’m trying to create a shader to change the geometry of a sphereMesh I’m using in a GPUParticle3d.

The goal is to simulate some kind of smoke.

I would like to make each sphere deform by adding some noise, as if it were some kind of drop of water in zero gravity.

Something like this:

I’ve tried several things (code generated with chatGPT…)
But this is the result:

The problem is that the size of the noise is too small and the speed is too fast.

I would like to achieve something similar to that drop of water without gravity moving slowly, with those valleys and mountains in its geometry.

But it seems that the vertex() function is called for each vertex and in the code I have not been able to take into account the adjacent vertices, as if a proportional edition were done in Blender.

I have tried to modify the values ​​of some variables in the code and generated other completely different codes but I can’t find the key.

Any suggestions?

Codes:
1st try:

shader_type spatial;
render_mode unshaded;

uniform float noise_strength = 0.05;  // Deformación sutil
uniform float time_speed = 2;       // Velocidad del cambio
uniform float noise_scale = 0.1;      // Escala del ruido (puedes ajustarlo)

float random(vec3 p) {
    return fract(sin(dot(p, vec3(127.1, 311.7, 74.7))) * 43758.5453123);
}

void vertex() {
    // Aumentamos la escala de las coordenadas de la partícula
    vec3 noise_pos = VERTEX * noise_scale + vec3(TIME * time_speed); 
    float noise = random(noise_pos); // Generamos ruido

    // Aplica la deformación en la dirección de la partícula
    VERTEX += normalize(VERTEX) * (noise - 0.5) * noise_strength;
}

2nd try:

shader_type spatial;
render_mode unshaded;

uniform float noise_strength = 0.1;  // Intensidad de la deformación
uniform float time_speed = 0.5;      // Velocidad del cambio
uniform float noise_scale = 3.0;     // Escala del ruido (ajustable)

float random(vec3 p) {
    return fract(sin(dot(p, vec3(127.1, 311.7, 74.7))) * 43758.5453123);
}

void vertex() {
    // Calcular un "punto medio" entre el vértice y los de alrededor
    vec3 avg_pos = VERTEX;
    avg_pos += normalize(VERTEX) * 0.1; // Proyección hacia las posiciones cercanas

    // Aumentamos la escala de las coordenadas de la partícula
    vec3 noise_pos = avg_pos * noise_scale + vec3(TIME * time_speed); 

    // Generamos un ruido más "coherente"
    float noise = random(noise_pos);  // Generamos ruido basado en la posición global

    // Aplica la deformación en la dirección del vértice de forma más suave
    VERTEX += normalize(VERTEX) * (noise - 0.5) * noise_strength;
}

3rd try:

shader_type spatial;
render_mode unshaded;

uniform float noise_strength = 0.05;  // Intensidad de la deformación
uniform float time_speed = 0.001;      // Velocidad de la deformación (ahora mucho más lento)
uniform float noise_scale = 3.0;      // Escala del ruido

// Función para generar ruido Perlin suave
float perlin_noise(vec3 p) {
    return fract(sin(dot(p, vec3(12.9898, 78.233, 137.357))) * 43758.5453123);
}

void vertex() {
    // Normalizamos la posición del vértice hacia el centro de la esfera
    vec3 local_position = normalize(VERTEX);

    // Ajustamos la escala del ruido para que afecte áreas más grandes
    vec3 noise_position = local_position * noise_scale + vec3(TIME * time_speed);

    // Obtenemos el ruido, pero ahora lo escalamos para hacerlo más grande
    float noise = perlin_noise(noise_position);

    // La deformación no es solo un simple ruido, sino que se aplica suavemente por zonas
    // El ruido se "acentúa" o "suaviza" para que afecte a áreas más grandes y no a un solo vértice
    float deformation = noise * noise_strength;

    // Aplicamos la deformación de manera que las montañas y valles se extiendan más
    VERTEX += local_position * deformation;
}

I could hit more attempts, but I think you see where the shots are going
Thanks in advance

Hi.
I think what you need is a 3D noise function where you can use your vertex spatial position.

Have a look here … try a 3D noise function from this site.

1 Like