Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Overview:
- Simplex Noise Function (simplex_noise_3d):
- This is a 3D Simplex noise implementation.
- Simplex noise is a gradient-based noise technique often used in procedural generation for textures, terrains, and animations.
- The function takes 3D coordinates (x, y, z) and returns a noise value, which can be used to create smooth, natural patterns.
- Simplex noise is preferred over Perlin noise due to its speed and reduced directional artifacts.
- Animation Variables and Loop Setup:
- The animation is set up to be a continuously looping animation of a specific duration (loop_duration).
- The loop is divided into several steps (noise_steps), where noise values are precomputed to make the animation seamlessly repeat.
- The precomputed noise_values store the (x, y, z) coordinates for the noise function, calculated in such a way to create a looping effect.
- Step Event:
- The Step Event updates the current animation time using delta_time, which ensures smooth movement regardless of frame rate.
- It keeps track of the current noise step and updates current_frame based on the current progress in the loop.
- Draw Event:
- A surface (surf) is used for drawing the noise pattern. Surfaces are off-screen textures in GameMaker, which are useful for creating complex or repeating visual effects.
- The surface is updated with interpolated noise values between two consecutive precomputed noise_values, ensuring smooth transitions.
- Nested loops are used to draw noise-based colors onto the surface. Warping is applied to the coordinates to create more interesting organic patterns.
- simplex_noise_3d is called multiple times to create a multi-octave effect (adding detail at different scales).
- The result is colored using HSV to produce an animated organic look that shifts smoothly over time.
- Finally, the surface is tiled across the screen to fill the entire room.
- Clean Up Event:
- Ensures that any created surfaces are freed to prevent memory leaks.
- Uses:
- Procedural Textures: The 3D simplex noise is ideal for generating procedural textures, such as organic surfaces (clouds, marble, wood) or terrain height maps. This makes it useful for game backgrounds, terrain, or abstract visual elements.
- Visual Effects: The warping and multi-octave noise layers create a dynamic, swirling effect that could be used for spell effects, energy fields, or magical glows.
- Shaders & Animation: This approach can be used to create animated materials or effects in combination with other shaders to create effects like water ripples, fire, or gaseous fog.
- Background Art: This code can generate looping animated backgrounds that give a sense of depth and movement, suitable for atmospheric indie games.
- Audio Visualization: The organic patterns could also be synchronized with audio to create a unique visualizer effect for a music game or media player.
- Potential Improvements and Creative Use:
- Dynamic Parameters: You could link parameters like warp_scale or base_scale to in-game events, making the animation react to player actions or environmental changes.
- Color Variation: The HSV color assignment could be randomized or modulated over time to create shifting color palettes, enhancing the psychedelic or natural look.
- User Interaction: Allow users to interact with the noise effect by adding a "mouse influence," where the noise values change in response to mouse position or clicks.
- Layering Effects: By stacking multiple surfaces with different parameters, you could create more complex layered animations for even richer visual effects.
- This script effectively creates a vivid, dynamic animation using procedural generation, perfect for games that need ambient visual effects or a striking background that feels alive and organic.
- */
- //create event ::
- function simplex_noise_3d(x, y, z) {
- // Simplex noise implementation
- static p = [151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180];
- static grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]];
- static dot = function(g, x, y, z) {
- return g[0]*x + g[1]*y + g[2]*z;
- };
- static F3 = 1/3;
- static G3 = 1/6;
- var n0, n1, n2, n3;
- var s = (x+y+z)*F3;
- var i = floor(x+s);
- var j = floor(y+s);
- var k = floor(z+s);
- var t = (i+j+k)*G3;
- var X0 = i-t;
- var Y0 = j-t;
- var Z0 = k-t;
- var x0 = x-X0;
- var y0 = y-Y0;
- var z0 = z-Z0;
- var i1, j1, k1;
- var i2, j2, k2;
- if(x0>=y0) {
- if(y0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; }
- else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; }
- else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; }
- } else {
- if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; }
- else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; }
- else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; }
- }
- var x1 = x0 - i1 + G3;
- var y1 = y0 - j1 + G3;
- var z1 = z0 - k1 + G3;
- var x2 = x0 - i2 + 2*G3;
- var y2 = y0 - j2 + 2*G3;
- var z2 = z0 - k2 + 2*G3;
- var x3 = x0 - 1 + 3*G3;
- var y3 = y0 - 1 + 3*G3;
- var z3 = z0 - 1 + 3*G3;
- var ii = i & 255;
- var jj = j & 255;
- var kk = k & 255;
- var gi0 = p[(ii+p[(jj+p[kk&255])&255])&255] % 12;
- var gi1 = p[(ii+i1+p[(jj+j1+p[(kk+k1)&255])&255])&255] % 12;
- var gi2 = p[(ii+i2+p[(jj+j2+p[(kk+k2)&255])&255])&255] % 12;
- var gi3 = p[(ii+1+p[(jj+1+p[(kk+1)&255])&255])&255] % 12;
- var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
- if(t0<0) n0 = 0;
- else {
- t0 *= t0;
- n0 = t0 * t0 * dot(grad3[gi0], x0, y0, z0);
- }
- var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
- if(t1<0) n1 = 0;
- else {
- t1 *= t1;
- n1 = t1 * t1 * dot(grad3[gi1], x1, y1, z1);
- }
- var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
- if(t2<0) n2 = 0;
- else {
- t2 *= t2;
- n2 = t2 * t2 * dot(grad3[gi2], x2, y2, z2);
- }
- var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
- if(t3<0) n3 = 0;
- else {
- t3 *= t3;
- n3 = t3 * t3 * dot(grad3[gi3], x3, y3, z3);
- }
- return 32*(n0 + n1 + n2 + n3);
- }
- // Animation variables
- loop_duration = 60; // Loop duration in seconds
- animation_time = 0;
- current_frame = -1; // To keep track of the current frame
- // Set up the scale for the noise
- base_scale = 0.5;
- warp_scale = .1;
- // Surface variables
- surf = -1;
- surf_width = 64;
- surf_height = 64;
- // Precompute noise values for perfect looping
- noise_steps = 10; // Number of keyframes for the loop
- noise_values = array_create(noise_steps);
- for (var i = 0; i < noise_steps; i++) {
- var t = i / noise_steps;
- noise_values[i] = {
- x: (cos(2 * pi * t) + 1) * 0.5,
- y: (sin(2 * pi * t) + 1) * 0.5,
- z: t
- };
- }
- // New variable to track the last step we showed a debug message for
- last_debug_step = -1;
- /// Step Event
- // Update time using delta timing
- var dt = delta_time / 1000000; // Convert microseconds to seconds
- animation_time += dt;
- if (animation_time >= loop_duration) {
- animation_time -= loop_duration;
- }
- // Calculate the current step more precisely
- var loop_progress = animation_time / loop_duration;
- var current_step = floor(loop_progress * noise_steps);
- // Check if we've moved to a new step
- if (current_step != last_debug_step) {
- last_debug_step = current_step;
- // This is where you can add your code for each new step
- //show_debug_message("New step: " + string(current_step));
- // Add any other actions you want to perform on each new step here
- }
- // Update current_frame for interpolation in Draw event
- current_frame = loop_progress * noise_steps;
- // Check if surface needs to be recreated
- if (!surface_exists(surf)) {
- surf = surface_create(surf_width, surf_height);
- }
- //Draw event
- // Ensure surface exists
- if (!surface_exists(surf)) {
- surf = surface_create(surf_width, surf_height);
- }
- // Set up the surface
- surface_set_target(surf);
- draw_clear_alpha(c_black, 0);
- // Calculate interpolation factor
- var loop_progress = animation_time / loop_duration;
- var index_float = loop_progress * noise_steps;
- var index1 = floor(index_float) % noise_steps;
- var index2 = (index1 + 1) % noise_steps;
- var alpha = frac(index_float);
- // Interpolate between noise values
- var noise1 = noise_values[index1];
- var noise2 = noise_values[index2];
- var noise = {
- x: lerp(noise1.x, noise2.x, alpha),
- y: lerp(noise1.y, noise2.y, alpha),
- z: lerp(noise1.z, noise2.z, alpha)
- };
- // Draw the organic animation
- for (var i = 0; i < surf_width; i++) {
- for (var j = 0; j < surf_height; j++) {
- var nx = i / surf_width;
- var ny = j / surf_height;
- // Create warping effect
- var warp_x = warp_scale * simplex_noise_3d(nx * 2, ny * 2, noise.x);
- var warp_y = warp_scale * simplex_noise_3d(nx * 2, ny * 2, noise.y);
- // Apply warping and create multi-octave noise
- var n1 = simplex_noise_3d((nx + warp_x) * base_scale, (ny + warp_y) * base_scale, noise.x);
- var n2 = 0.5 * simplex_noise_3d((nx + warp_x) * base_scale * 2, (ny + warp_y) * base_scale * 2, noise.y);
- var n3 = 0.25 * simplex_noise_3d((nx + warp_x) * base_scale * 4, (ny + warp_y) * base_scale * 4, noise.z);
- var n = (n1 + n2 + n3 + 1) * 0.5;
- var col = make_color_hsv((n * 255) % 255, 200, 200);
- draw_point_color(i, j, col);
- }
- }
- // Reset the surface
- surface_reset_target();
- // Draw the surface tiled to fill the screen
- var tile_w = surf_width;
- var tile_h = surf_height;
- for (var i = 0; i < room_width; i += tile_w) {
- for (var j = 0; j < room_height; j += tile_h) {
- draw_surface(surf, i, j);
- }
- }
- //Clean up event
- /// Clean Up Event
- if (surface_exists(surf)) {
- surface_free(surf);
- }
Advertisement
Add Comment
Please, Sign In to add comment