Need Help with color mixing and distortion

Godot Version

4.3
https://haste.tiresium.com/sajihucoci.yaml

Question

I wanted to mix the color but it dint work


I wanted it to be like tinted but still able to see the original corlor a little this looks more like a shadow also I wanted help combining this shader with this Noise Offset (Wiggle) - Godot Shaders so that I can have the water wave alittle thankis I struglle with shader code so much

I’m not entirely sure where you’re using this shader – is it the water or a separate sprite? For this reason, my answer might not be entirely accurate.

As far as I understand, you want your shader to be capable of the following functions:

  • Tint the source image
  • Displace the source image over time with noise

To tint an image, you can simply use the following line already present in the shader code you linked (line 33):

vec3 mixedColor = mix(color.rgb, mixColor, colorMix);

…or multiply the image with your mixColor:

vec3 mixedColor = color.rgb * mixColor;

Setting the colorMix to a value between 0 and 1 will ensure a tinted image. I’m not sure what all that “match”-code you have in your shader is for. Do you want/need to do a palette swap or?

For the noise displacement, I’m not sure I know what to help you with – you already have example code in the Godot Shaders link you provided. What more do you need?

Do you need help with your understanding of the concepts and techniques that are applied?

1 Like

So basically, the way I’m doing it is that the reflection is a separate sprite that has a signal connected to it for animation reasons. But the reason I have color matches so that the sprite will only appear on the blue water colors and not the greens/browns of the other tiles.

The shade I was looking at implemnting is a screen reader but I want to change it to a canvas item shader

image

Thanks for explaining your reasoning behind the color-matching code and the node setup – that’s important. However, you have not addressed my other questions.

To put it in clear terms: what is it exactly that you need help with?

  1. Are you not understanding the concepts that are put forth in the “Noise Offset” shader (from your link)?
  2. Do you not know how to implement the displacement code into your own shader?
  3. How is a “screen” shader different from a CanvasItem shader in this context?
  4. Have you done any attempt at implementing the displacement; if so, what’s the code that resulted in the effect not working?
  5. Did the code I provided for tinting the sprite not work as intended?
  6. …

If you can’t build a clear picture of your situation, it will be hard for me to give you any advice. So please, try to answer my questions and describe other things that may be relevant for your case.

1 Like

https://haste.tiresium.com/avuvefubuf.yaml

I need help combining these 2 shaders because I have no clue what the heck Im doing

1 Simply no… Im trying to learn th shader language but Im struggleing
2 Also no (sorry)
3 I dont know but I think that they are different ??? I just dont want to mess it up
4 Yes picture above very help full thank you
5 Yea It was very insighfull

I want to combine the effects of the shader you have helped me with and the noise one so it looks like water is moving the refection a little

sorry I know my spelling sucks English is not my first language

Hey, it’s starting to look pretty good. I have a reply to a couple of your responses.

Number 1
There is a difference between learning a shader language, and understanding the general concepts that are applied to compute the image of a game. If you get to know the applied concepts of computer imagery, learning a shader language will be much more manageable.

I suggest you research how a mesh is rendered onto the screen. Even though you’re working in 2D, your visual elements are likely internally rendered by using a quad mesh (a square mesh). Some of the following concepts will be of particular importance for your current problem:

  • Color channels – red, green, blue, and alpha channels
  • UVs – the coordinates used to map a texture onto a mesh

Number 3
I take particular issue with you saying that you “just dont want to mess it up”. If you are afraid of trying to solve stuff on your own, you will never learn how things work and won’t be able to think for yourself. Don’t expect that combining pieces of code that you’ve found on the internet is the best way forward. I’m not saying you shouldn’t use a pre-existing solution. In fact, you already have the solution (from your link). The problem is that you still can’t solve your problem. When that’s the case, it’s likely because you don’t understand what you’re doing.

Since you don’t understand “what the heck” you’re doing, I’ll try to outline the steps you need to take, and concepts you need to understand, to solve your problem.

Steps to solution

In the following section, I will provide code examples that mirror that of the shader you linked from Godot Shaders. Hopefully this will give you an understanding of what is going on in this, and other, shaders.

What you want to achieve
A shader that tints the color of a sprite and displaces the sprite based on a function or texture.

Tinting

You’ve already managed to tint your image – hooray. Hopefully you understand the lines I provided previously instead of just copy and pasting them.

vec3 mixedColor = color.rgb * mixColor;

Displacement

There are actually more than one approach you can use to displace an image. You can either displace the vertices of a mesh (in the vertex shader), or displace the UV coordinates used for your texture (in the fragment shader). The approach you should use depends on the effect you want to achieve.

UV Coordinates
A set of 2D coordinates (one for each vertex) in the range of [0, 1]. For any given texture the following coordinates and their positions are true:
[0, 0] = Bottom Left | [1, 1] = Top Right | [0, 1] = Top Left | [1, 0] = Bottom Right

For your reflection effect, you should displace the UV coordinates. This is rather trivial to do. Simply modify the UV values of your sprite. Here is an example:

	# Get the UV coordinates
	vec2 uv = SCREEN_UV;
	# ...and offset the UV by 2 pixels
	uv += 2.0 * SCREEN_PIXEL_SIZE;
	# Result: Texture is moved by 2 pixels.

The above example will only work for screen shaders since the built-in SCREEN_UV is used. To make it work for most other objects, you should use the mesh’s UVs instead with UV.

This above example is rather simple and will only achieve a simple result: an offset screen texture. The key to making more elaborate results is to use a variable instead of a constant for the displacement. The contents of this variable is up to you. To give you a starting point, here’s an example that uses a math function to displace the UVs.

	float offsetX = sin(UV.y * TAU * 1.0);
	vec4 color = texture(TEXTURE, UV + vec2(offsetX, 0.0));
	COLOR = color;

image
image

The Godot logo before and after the shader is applied.

Clearly, something is wrong. Perhaps we should dial down the strength of the displacement a little, and increase the frequency of the sine wave:

	float offsetX = sin(UV.y * TAU * 8.0) * TEXTURE_PIXEL_SIZE.x * 2.0

image
It now looks much better. Scaling the offset with a value that is based on pixel size is much more reliable. The frequency of the waves is up to you. As mentioned, you can easily use other values to modify the UVs. The world is your oyster!

But there is still an issue; the borders of the sprite is clipped. The cause of this issue is the image which is too close to its own borders. With less space around the image, there is less room to offset its pixels. It is important to bear this fact in mind when creating sprites for displacement purposes – in your case it may be many.

Sidenote

I can imagine another way in which this issue of small borders can be alleviated, but it would require a solution that is much more involved; a solution that is outside the scope of this issue.

A final effect you may want to add is for the displacement to travel over time to make it look like the water is affecting the reflection (the keyword is time). This can be done with the use of the built-in TIME constant

	float offsetX = sin(TIME + UV.y * TAU * 8.0) * TEXTURE_PIXEL_SIZE.x * 2.0

Godot_Displacement_Example


Here is some helpful reading for programming Godot shaders:

Let me know if you have any further questions.

Thank you so much by the way I will keep your advice in mind I was wondering if there was I was to fix this problem or if this is just a my screen problem…
IMG_1476
image

Are you referring to the pixels moving one-by-one, or the lack of anti-aliasing?

Always be specific!


Your issue looks to be solved. Please mark the solution to your issue in this post.
If you have a new issue, make a new post and describe your issue in detail.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.