
If yor task is to create particle shaders:
Your task is to generate particle shaders for a particle system that is structured into two central nodes, 
termed "Spawn" and "Simulation." Each node allows you to predetermine a particle's behavior based on various input parameters.

**1. Spawn Node:** This component regulates the predetermined settings of a particle, based on the following inputs:
- **Lifetime:** Specifies the lifespan of a particle.
- **Position:** Defines the initial location of a particle.
- **Direction:** Determines the primary directional vector of a particle.
- **Speed:** Establishes the particle's initial speed.
- **Size:** Sets the initial size of the particle.
- **Rotation:** Demarcates the particle's initial rotational angle.
- **Color:** Identifies the particle's initial color.
- **Emissive:** Describes the initial emissive color value.

**2. Simulation Node:** This unit directs a particle's behavior per frame using these inputs:
- **Position:** Utilized only when you seek direct control over the particle's position during the simulation. Leaving it blank will not influence the particles.
- **Velocity:** Dictates the particle's speed.
- **Size:** Regulates a particle's current dimensions.
- **Color:** Defines the present color of the particle.
- **Emissive:** Describes the current emissive value.
- **Rotation:** Determines the current rotational angle of a particle.
- **Linear Drag:** Indicates the amount of drag affecting the particle's motion.
- **Gravity:** Points to the gravitational factor influencing the particle.
- **Collision:** Refers to the collision response factor (requires an output from the Collision node).
- **Flip Book:** Manages animation frame adjustments (requires output from the Flip Book node).

Try to leverage the simulation output primarily, proceeding to use other nodes to calculate desired motion if the target effect seems achievable.  

**Example Prompt:**

"Explosive particles that shrink over time and are affected by gravity."

**Generated Compute Shader Code:**
// **Overall thinking process:
    //Explosive particles usually spawn from a spherical shape with random starting speeds and lifetimes. To control shrinking, we can manipulate the particle size using the particle age in the simulation also we can set gravity at the simulation end node.
// <Spawn Code>

    // Assign a random lifetime between 1 and 4
    float lifetime;
    RandomInRange(1, 4, 66, lifetime); // RandomInRange(min, max, seed, out)

    // Spawn particles in a sphere with a radius of 0.1
    vec3 position, direction;
    RandomPositionInSphere(0.1, position, direction); // Outputs in 'position' and 'direction'

    // Assign a random initial speed between 0 and 26
    float speed;
    RandomInRange(0, 26, 22, speed);

    // Set initial size to 0 (controlled in simulation) and use default rotation, color, and emissive values
    OutputVFXSpawnBlock(lifetime, position, direction, speed, 0, vec3(0, 0, 0), vec4(1, 1, 1, 1), vec3(0, 0, 0));

// <Simulation Code>

    // Compute the age normalized by lifetime (range 0 to 1)
    float normalizedAge;
    AgeOverLifetime(normalizedAge);

    // Retrieve the current velocity
    vec3 velocity;
    GetCurrentVelocity(velocity);

    // Scale size inversely with age (to shrink over time)
    float shrinkFactor;
    SubtractBlock(1, normalizedAge, shrinkFactor);

    // Assign a random scale factor between 1 and 2 to each particle
    float randomScale;
    RandomInRange(1, 2, 34, randomScale);

    // Calculate final size after applying shrink factor
    float finalSize;
    MultiplyBlock(shrinkFactor, randomScale, finalSize);

    // Output updated particle properties, enable gravity (1) and set other properties to default
    OutputVFXSimulationBlock(-,velocity, finalSize, vec4(1, 1, 1, 1), vec3(0, 0, 0), vec3(0, 0, 0), 3, 1, vec4(0, 0, 0, 0), 0);

**Example Prompt:**

"Snow particle with some random movement."

**Generated Compute Shader Code:**
// **Overall thinking process:
    //Snow particles usually spawn from a flat cubic surface. We can also randomly set their size and lifetime during spawning to avoid changing these parameters during updates (simulation). Then, in the simulation, we calculate a random velocity for each particle and linearly interpolate (lerp) to it based on the particle's age. Additionally, snow particles usually rotate, so we can rotate them in the simulation.
    
// <Spawn Code>
    // Assign a random lifetime between 3 and 8
    float lifetime;
    RandomInRange(3, 8, 66, lifetime);

    // Assign a random initial size between 0.03 and 0.08
    float size;
    RandomInRange(0.03, 0.08, 244, size);

    // Spawn particles in a cube with dimensions of 20x20x1
    vec3 position, direction;
    RandomPositionInCube(vec3(20, 20, 1), 0, position, direction);

    // Use default direction, speed, rotation, color, and emissive values
    OutputVFXSpawnBlock(lifetime, position, vec3(0, 0, 0), 0, size, vec3(0, 0, 0), vec4(1, 1, 1, 1), vec3(0, 0, 0));

// <Simulation Code>
    // Retrieve the current size set during spawn
    float currentSize;
    GetCurrentSize(currentSize);

    // Assign a random initial speed
    float initialSpeed;
    RandomInRange(0, 1, 23, initialSpeed);

    // Compute the age normalized by lifetime (range 0 to 1)
    float normalizedAge;
    AgeOverLifetime(normalizedAge);

    // Retrieve the current velocity
    vec3 velocity;
    GetCurrentVelocity(velocity);

    // Calculate a random velocity over lifetime
    float randomVelocity;
    LerpBlock(-1, 1, initialSpeed, randomVelocity);

    // Multiply normalized age by random velocity
    float finalVelocity;
    MultiplyBlock(normalizedAge, randomVelocity, finalVelocity);

    // Apply the calculated velocity to the current velocity
    vec3 updatedVelocity;
    AddForce(velocity, vec3(finalVelocity, finalVelocity, finalVelocity), updatedVelocity);

    // Assign a random rotation angle over lifetime
    float rotationAngle;
    RandomInRange(-45, 45, 46, rotationAngle);

    // Adjust rotation over lifetime
    vec3 updatedRotation;
    RotateOverLifeTime(vec3(0, 0, 0), vec3(0, 0, rotationAngle), updatedRotation);

    // Output updated particle properties, use default color, emissive, linear drag, gravity, and collision
    OutputVFXSimulationBlock(-, updatedVelocity, currentSize, vec4(1, 1, 1, 1), vec3(0, 0, 0), updatedRotation, 0, 0.2, vec4(0, 0, 0, 0), 0);

**Example Prompt:**
"Water fountain whose color changes over time and uses an 8x8 texture sheet."

**Generated Compute Shader Code:**

// **Overall thinking process:
    // The fountain particles spawn from a cone shape, and we can define their initial size during spawning. In the simulation phase, we maintain the current size and velocity without manipulation. However, we need to interpolate (lerp) the color based on the particle's age. Additionally, we should utilize a texture sheet for animation to achieve a flipbook effect.
    
// <Spawn Code>

    // Assign a random lifetime between 2 and 3
    float lifetime;
    RandomInRange(2, 3, 66, lifetime);

    // Spawn particles in a cone shape with base radius 0.1, top radius 0.5, and height 2
    vec3 position, direction;
    RandomPositionInCone(0.1, 0.5, 2, position, direction);

    // Assign a random initial size between 0.5 and 1
    float size;
    RandomInRange(0.5, 1, 244, size);

    // Use default direction, speed, rotation, color, and emissive values
    OutputVFXSpawnBlock(lifetime, position, direction, 20, size, vec3(0, 0, 0), vec4(1, 1, 1, 1), vec3(0, 0, 0));

// <Simulation Code>

    // Retrieve the current size set during spawn
    float currentSize;
    GetCurrentSize(currentSize);

    // Retrieve the current velocity
    vec3 velocity;
    GetCurrentVelocity(velocity);

    // Assign a random value to use in rotate overlife time
    float rotationAngle;
    RandomInRange(-5, 5, 46, rotationAngle);

    // Animate the texture sheet with an 8x8 grid, starting from frame 0 and ending at frame 1
    uint frameIndex;
    TextureSheetAnimation(vec2(8, 8), 0, 1, frameIndex);

    // Compute the age normalized by lifetime (range 0 to 1)
    float normalizedAge;
    AgeOverLifetime(normalizedAge);

    // Adjust rotation over lifetime
    vec3 updatedRotation;
    RotateOverLifeTime(vec3(0, 0, 0), vec3(0, 0, rotationAngle), updatedRotation);

    // Use smoothstep function to get a smooth value for alpha transition from 1 to 0
    float alpha;
    SmoothStepBlock(normalizedAge, 0.8, 1, alpha);

    // Interpolate color from blue to light blue based on normalized age
    vec3 color;
    LerpBlock(vec3(0, 0.5, 1), vec3(0.587025, 0.878206, 1), vec3(normalizedAge, normalizedAge, normalizedAge), color);

    // Compute the inverse of alpha for the final color to have fade out
    float inverseAlpha;
    OneMinusBlock(alpha, inverseAlpha);

    // Combine the interpolated color with alpha
    vec4 finalColor;
    Vec4 SwizzleBlock(color.x, color.y, color.z, inverseAlpha, finalColor);

    // Output updated particle properties, use default linear drag, gravity, and collision
    OutputVFXSimulationBlock(-, velocity, currentSize, finalColor, vec3(0, 0, 0), updatedRotation, 1, 1, vec4(0, 0, 0, 0), frameIndex);
