Particle shader works with editor but does not work when exported

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ichster

Hi, I have some custom particle shaders that work with Particles2D when I run the game from the editor, but once I export the game to a release build, they stop emitting or doing anything.

I am running Godot on 3.2.2-stable for both my exports and editor, and doing all of this on Windows.

Is there some box I have tick in order to get drivers working for custom particle shaders on the exported project? Or is my shader code failing for whatever reason only upon export.

Any suggestions on how to fix would be great.

Let me dump my shader code below, although I don’t think there is anything wrong with it:

shader_type particles;

// particle firing stuff
uniform float spread;
uniform float firing_angle;
uniform int amount;
uniform float speed;

// obstacle texture stuff
uniform sampler2D obstacle_tex : hint_black;
uniform int block_sz;
uniform vec2 tex_origin;

vec2 ang2vec(float a) {
	return vec2(cos(a), sin(a));
}

mat4 rotationMatrix(vec3 axis, float angle)
{
    axis = normalize(axis);
    float s = sin(angle);
    float c = cos(angle);
    float oc = 1.0 - c;
    
	mat4 resm;
	resm[0] = vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y + axis.z * s, oc * axis.z * axis.x - axis.y * s, 0.0);
	resm[1] = vec4(oc * axis.x * axis.y - axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z + axis.x * s, 0.0);
	resm[2] = vec4(oc * axis.z * axis.x + axis.y * s, oc * axis.y * axis.z - axis.x * s, oc * axis.z * axis.z + c, 0.0);
	resm[3] = vec4(0.0, 0.0, 0.0, 1.0);
	
	return resm;
}

void vertex()
{
	// collision found later
	// v_found_obstacle = uintBitsToFloat(0);
	COLOR.a = 1.0;
	
	// reset
	if (RESTART) {
		// translate because of non-local coords
		TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;
		// rotate based on firing_angle
		TRANSFORM *= rotationMatrix(vec3(0.0, 0.0, 1.0), firing_angle);
		// start moving
		float increment = spread / float(amount);
		float idx_angle = ((float(INDEX) - float(amount)/2.0) * increment) + firing_angle;
		vec2 firing_direction = ang2vec(idx_angle);
		VELOCITY.xy = firing_direction * speed;
	} else {
		// check if inside square next frame
		// get pos
		ivec2 world_pos;
		world_pos.x = int(TRANSFORM[3].x) + int(VELOCITY.x * DELTA);
		world_pos.y = int(TRANSFORM[3].y) + int(VELOCITY.y * DELTA);
		
		// get byte
		ivec2 obst_pos_st = (world_pos / block_sz) - ivec2(int(tex_origin.x), int(tex_origin.y));
		vec4 texel = texelFetch(obstacle_tex, obst_pos_st, 0);
		bool non_obstacle = floatBitsToUint(texel.r) != uint(0x00);
		// check result
		if (non_obstacle) {
			// stop moving
			ACTIVE = false;
		}
	}
}
enter code here
:bust_in_silhouette: Reply From: ichster

I had two issues:

  1. I was not exporting the .json files I was using for meta data in my shader. That was fixed by adding *.json to non-resource files when exported.

  2. Checking if a file exists via File.new().file_exists(path) doesn’t work with image resources after exporting the game, because they get shuffled around in the pack. Issue is documented here: File.file_exists() doesn’t take remappings after resource conversion into account