Conway's Game of Life Shader converted from Shadertoy not iterating

Version: 4.3 stable

Hello, I’m trying to convert a shader of Conway’s Game of Life to Godot, in the process of finally learning the shader language. I’m converted all the parts from GLSL and it compiles, but it doesn’t update to any next iteration. I’m using a standard noise as starting condition and after trying everything in my very narrow shader knowledge I hope someone here can tell me what I did wrong.

As a “vessel” for the shader I used a TextureRect with the noise as texture btw

shader_type canvas_item;


uniform sampler2D noise;

void fragment() {
    vec2 uv = FRAGCOORD.xy * SCREEN_PIXEL_SIZE.xy;
  
    // setting color to DEAD at first
    vec3 color = vec3(0.0);
	
	
    float neighbors = 0.0;
    for(float i = -1.0; i <= 1.0; i += 1.0)
    {
        for( float j = -1.0; j <= 1.0; j += 1.0)
        {
        	vec2 offset = vec2(i, j) * SCREEN_PIXEL_SIZE.xy;		 // Scale the offset down
        	vec4 lookup = texture(TEXTURE, uv + offset); // Apply offset and sample
        	neighbors += lookup.x;							 // Accumulate the result
			
        }
    }

    float cell = texture(TEXTURE, uv).x;
    
	// set to DEAD, only need to check alive rules
    if(cell > 0.0) {
		// ALIVE
        if(neighbors >= 3.0 && neighbors <= 4.0) {
            color = vec3(1.0);
        }
    } else if(neighbors > 2.0 && neighbors < 4.0) {
		// DEAD, but soon alive
    	color = vec3(1.0);
    }

	COLOR = vec4(color, 1.0);
}

I don’t see anything that would iterate, shaders don’t write to their own texture. I think you would have to use a screen texture for your lookups.

Could you elaborate? If I change the COLOR of a pixel and the access the TEXTURE variable those changes from the previous “Iteration” should be there and I should or am I misunderstanding sth?

TEXTURE refers to the canvas item’s texture, presumably your noise texture, COLOR refers to the end result drawn to the screen. If you do not plug the end result back into the sampled value then it won’t iterate.

The screen texture via hint_screen_texture are one way to do this, though I’m not sure how you’ll start the process with the noise texture.

You could start the process with the noise texture using the _draw function in a separate node (runs once by default). You’ll also want to set the environment background mode to “Keep” so that it’s not cleared by the default color.

But yeah hint_screen_texture looks like the right way to refer to the screen texture in 4+

Oh thanks I thought TEXTURE always uses the thing on screen and not the initial texture.

Is it possible to do it like this, for the start?

if(TIME < 1.0) {
	color = vec3(texture(noise, uv).x);
}
COLOR = vec4(color, 1.0);

Plus combining this with hint_screen_texture to read directly from the screen? Tried it with those methods, but now it just jumps to an all black/dead screen? Counting the neighbouring living cells doesn’t work and there are always 2 alive ones? Is there an issue on how I sample the neighbouring cells maybe?

I am now drawing a noise texture to the screen via the _draw function (draw_texture), but that didn’t do much either :confused: