Canvas shader making a block instead of wrapping on sprite
Asked Answered
B

6

0

I am using a shader I found online for a simple binary conversion (straight black and white) filter. Only problem is that it is affecting an entire block rather than the area of the sprite. Nothing is wrong with the image transparency in the file. I am pretty sure I am missing something and forgive my ignorance here, but I am still learning shaders.

shader_type canvas_item;
// Binary Conversion (Black & White)

uniform float _threshold : hint_range(0, 3) = 1.5;


void fragment() {
	vec3 col = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
	float temp = col.r + col.g + col.b;
	
	if (temp > _threshold) {
		col = vec3(1.0, 1.0, 1.0);
	} else{
		col = vec3(0.0, 0.0, 0.0);
	}
	
	COLOR.rgb = col;
}

Default:

With Shader:
[
](https://)

Britain answered 29/10, 2023 at 19:0 Comment(0)
I
0

Britain Assign sprite's texture alpha to COLOR.a

Invertebrate answered 29/10, 2023 at 19:6 Comment(0)
B
0

Invertebrate Bear with me, still learning shader syntax. How would I code that?

Britain answered 29/10, 2023 at 19:8 Comment(0)
I
0

Britain

COLOR.a = texture(TEXTURE, UV).a;
Invertebrate answered 29/10, 2023 at 19:21 Comment(0)
B
0

Thank you very much for that. I had to do a bit more noodling to get it right (because the screen texture was plugged in also) but you already showed me how. Many thanks. Complete code fix:

shader_type canvas_item;
// Binary Conversion (Black & White)

uniform float _threshold : hint_range(0, 3) = 1.5;


void fragment() {
	vec3 col = textureLod(TEXTURE, UV, 0.0).rgb;
	float temp = col.r + col.g + col.b;
	
	if (temp > _threshold) {
		col = vec3(1.0, 1.0, 1.0);
	} else{
		col = vec3(0.0, 0.0, 0.0);
	}
	
	COLOR.rgb = col;
	COLOR.a = texture(TEXTURE, UV).a;
}
Britain answered 29/10, 2023 at 19:28 Comment(0)
I
0

Britain You should also stay away from ifs in shader code and instead use step() function.

If you want to write it more in the spirit of shader coding you can use dot product to sum vector components. So the whole fragment function would look something like this:

void fragment() {
	float grayscale = dot(texture(SCREEN_TEXTURE, SCREEN_UV).rgb, vec3(1.0));
	COLOR.rgb = vec3(step(_threshold, grayscale));
	COLOR.a = texture(TEXTURE, UV).a;
}

If you want to make it as compact as possible then:

void fragment() {
	COLOR = vec4(step(_threshold, dot(texture(SCREEN_TEXTURE, SCREEN_UV), vec4(vec3(1.0), 0.0))));
	COLOR.a = texture(TEXTURE, UV).a;
}
Invertebrate answered 29/10, 2023 at 19:50 Comment(0)
B
0

Invertebrate i prefer less code to parse through. I'll use that last example. Thank you for your knowledge!

Britain answered 29/10, 2023 at 20:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.