Applying a shader effect to sourse texture

I create a shader that changes the parameters of the texture (brightness, saturation, etc.).
After manipulating the image, I need to upload it in .png format. But the original image is preserved unchanged.

How to apply shader settings to original texture?

You want to save a .png file with the modifications, correct?

Shaders only apply on the GPU, so you need some way to copy the data from the GPU back to the CPU. To do that you need to render your material to a RenderTexture using a Blit(), then create a Texture2D with the same dimensions and format as the render texture and use ReadPixels() to copy the render texture to the CPU memory. Then you can use EncodeToPNG() to convert the image to a png and save the resulting data to disk.

2 Likes

Right!
Thanks for the answer
I try to do as you advise, it turns out something similar, but not quite right
What am I doing wrong?

Image img = IMG.GetComponent<Image>();

            img.material = Instantiate(Resources.Load("ImageEffect") as Material);
            img.material.SetFloat("_Brightness", bright);

            RenderTexture rTex = new RenderTexture(img.sprite.texture.width, img.sprite.texture.height, 16, RenderTextureFormat.ARGB32);
            Graphics.Blit(img.material.mainTexture, rTex);

            Texture2D TX = new Texture2D(rTex.width, rTex.height);

            img.sprite.texture.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0, false);
            img.sprite.texture.Apply();

Apparently I am grabbing the texture incorrectly.

Because you’re trying to grab the texture from a material you’re using on a UI element, which has no texture assigned. The texture being used in your example is the sprite assigned to the image component, which is setting the texture to use at runtime when displaying that UI component.

For a Blit you need a Texture2D, not a sprite. Also you need to assign a material to use with the Blit otherwise it’s just making a copy of the original image unmodified.

1 Like

Here is code that seems to work but is not correct.

RenderTexture buffer = new RenderTexture(img.sprite.texture.width, img.sprite.texture.height, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);

            Graphics.Blit(img.sprite.texture, buffer, img.material);

            img.sprite.texture.ReadPixels(new Rect(0, 0, img.sprite.texture.width, img.sprite.texture.height), 0, 0, false);
            img.sprite.texture.Apply();

I don’t understand what material should be used. The texture changes, but becomes either light or dark

6427481--718763--qwest2.png