LoginSignup
0
0

More than 1 year has passed since last update.

Unity Textureのコピーとソフトフィルター

Posted at

RenderTextureに一度コピーしてから取得する。

Texture2D tar;
Texture2D dst = tar.Copy();
//Texture2D dst = tar.Copy(filter);
static class TextureCopyExtension
{
    public static Sprite ToSprite(this Texture2D tex)
    {
        return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
    }

    public static Texture2D Copy(this Texture2D source, System.Func<Color[], int, int, Color[]> filter = null)
    {

        var texture = new Texture2D(source.width, source.height, TextureFormat.RGBA32, false);
        var renderTexture = new RenderTexture(texture.width, texture.height, 32);

        // もとのテクスチャをRenderTextureにコピー
        Graphics.Blit(source, renderTexture);
        RenderTexture.active = renderTexture;

        // RenderTexture.activeの内容をtextureに書き込み
        texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        RenderTexture.active = null;
        // 不要になったので削除
        RenderTexture.DestroyImmediate(renderTexture);

        if (filter != null)
        {
            var pixels = filter(texture.GetPixels(), texture.width, texture.height);
            texture.SetPixels(pixels);
            texture.Apply();
        }

        return texture;
    }

}//class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class filter : MonoBehaviour
{

    [SerializeField] Texture2D _tex;
    // Start is called before the first frame update
    void Start()
    {
        gameObject.GetComponent<Image>().sprite = _tex
         //.Copy(filter_grayscale)
         //.Copy(filter_dither)
         //.Copy(filter_blue)
         .Copy(filter_gamma)
         .ToSprite()
         ;

    }
    Color[] filter_grayscale(Color[] data, int w, int h)
    {
        for (var i = 0; i < data.Length; i++)
        {
            int x = i % h, y = i / w;
            float c = (data[i].r + data[i].g + data[i].b) / 3.0f;
            data[i] = new Color(c,c,c, data[i].a);
        }
        return data;
    }

    Color[] filter_dither(Color[] data, int w, int h)
    {

        int[,] bayer ={
         {0 * 16 + 8, 8 * 16 + 8, 2 * 16 + 8, 10 * 16 + 8},
         {12 * 16 + 8, 4 * 16 + 8, 14 * 16 + 8, 6 * 16 + 8},
         {3 * 16 + 8, 11 * 16 + 8, 1 * 16 + 8, 9 * 16 + 8},
         {15 * 16 + 8, 7 * 16 + 8, 13 * 16 + 8, 5 * 16 + 8}
        };
        int x, y, chk, wk, gain = 255;

        for (var i = 0; i < data.Length; i++)
        {
            wk = (i / 4);
            y = (wk / w);
            x = (wk % w);
            chk = bayer[x % 4, y % 4];
            var r = (data[i].r * gain >= chk) ? 1 : 0;
            var g = (data[i].g * gain >= chk) ? 1 : 0;
            var b = (data[i].b * gain >= chk) ? 1 : 0;
            data[i] = new Color(r,g,b, data[i].a);

        }
        return data;
    }

    Color[] filter_blue(Color[] data, int w, int h)
    {
        float f(float d) => Mathf.Min(d, 1);
        for (var i = 0; i < data.Length; i++)
        {
            // (r+g+b)/3
            float c = (data[i].r + data[i].g + data[i].b) / 3.0f;
            var r=c;
            var g=f(c + c * 0.25f);
            var b=f(c + c * 0.5f);
            data[i] = new Color(r,g,b, data[i].a);
        }
        return data;
    }

    Color[] filter_gamma(Color[] data, int w, int h){
        // 補正値(1より小さい:暗くなる、1より大きい明るくなる)
        var gamma = 0.8f;//2.0f;
        // 補正式
        float correctify(float val) => Mathf.Pow(val, 1 / gamma);

        for (var i = 0; i < data.Length; i++)
        {
            var r = correctify(data[i].r);
            var g = correctify(data[i].g);
            var b = correctify(data[i].b);
            data[i] = new Color(r,g,b,data[i].a);
        }

        return data;
    }


}//class




static class TextureCopyExtension
{
    public static Sprite ToSprite(this Texture2D tex)
    {
        return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
    }

    public static Texture2D Copy(this Texture2D source, System.Func<Color[], int, int, Color[]> filter = null)
    {

        var texture = new Texture2D(source.width, source.height, TextureFormat.RGBA32, false);
        var renderTexture = new RenderTexture(texture.width, texture.height, 32);

        // もとのテクスチャをRenderTextureにコピー
        Graphics.Blit(source, renderTexture);
        RenderTexture.active = renderTexture;

        // RenderTexture.activeの内容をtextureに書き込み
        texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        RenderTexture.active = null;
        // 不要になったので削除
        RenderTexture.DestroyImmediate(renderTexture);

        if (filter != null)
        {
            var pixels = filter(texture.GetPixels(), texture.width, texture.height);
            texture.SetPixels(pixels);
            texture.Apply();
        }

        return texture;
    }

}//class
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0