Unity에서 흐림 이미지 동적 생성
Unity에서 흐림 이미지 동적 생성
라는, 조금 낚시 같은 제목으로 했습니다만.
원래를 바로잡으면 지금 하고 있는 일로, 이미 있는 화상에 대해서 흐림이 걸린 화상을 동적으로 생성하지 않으면 안 되는 처리가 있어.
우선, 셰이더로 써 보는 것은 좋지만, 코드가 거의 거의 픽셀 셰이더로 근처 픽셀을 보거나 부하 괜찮아? 라고 생각한 것과,
이것은 도중에 애니메이션하는 것도 아니고, 첫회에서 흐림 이미지를 생성해 버리면 나머지는 그것을 보통으로 텍스처로서 사용하는 것일까? 하지만 그건 Unity에서 할 수 있니? 라고 하는 소박한 의문으로부터 크리스마스 이브이브인데 보치보치와 조사 개시.
결론부터 말하면
아주 쉽게 할 수 있었다. (단, 메모리 사용량이나 처리 속도를 고려하지 않으면)
소스 코드적으로는 htp // d. 하테나. 네. jp/코 rcぇ/20090628/1246208145 의 가우시안필을 거의 둥근 파크리.
필요한 것이 그 자체의 흐림 이미지가 아니라 단색이었기 때문에, 알파치만을 취득하도록 조금 수정.
게다가, 아무렇지도 않게 캐쉬해 벌써 블러 이미지 작성이 끝난 경우는 캐쉬한 텍스처를 돌려주도록 해 보거나.
Release 메소드 준비해 보았지만, 이것으로 제대로 개방될지 어떨지는 불명(Dictionary를 clear하고 있을 뿐)
using System.Linq;
using UnityEngine;
using System.Collections.Generic;
public static class BuildTexture
{
private static Dictionary<Texture2D, Texture2D> _textureCache = new Dictionary<Texture2D, Texture2D>();
public static Texture2D CreateBlurTexture(Texture2D tex, float sig,bool isCache = true)
{
if (isCache && _textureCache.ContainsKey(tex)) return _textureCache[tex];
int W = tex.width;
int H = tex.height;
int Wm = (int)(Mathf.Ceil(3.0f * sig) * 2 + 1);
int Rm = (Wm - 1) / 2;
//フィルタ
float[] msk = new float[Wm];
sig = 2 * sig * sig;
float div = Mathf.Sqrt(sig * Mathf.PI);
//フィルタの作成
for (int x = 0; x < Wm; x++) {
int p = (x - Rm) * (x - Rm);
msk[x] = Mathf.Exp(-p / sig) / div;
}
var src = tex.GetPixels(0).Select(x => x.a).ToArray();
var tmp = new float[src.Length];
var dst = new Color[src.Length];
//垂直方向
for (int x = 0; x < W; x++) {
for (int y = 0; y < H; y++) {
float sum = 0;
for (int i = 0; i < Wm; i++) {
int p = y + i - Rm;
if (p < 0 || p >= H) continue;
sum += msk[i] * src[x + p * W];
}
tmp[x + y * W] = sum;
}
}
//水平方向
for (int x = 0; x < W; x++) {
for (int y = 0; y < H; y++) {
float sum = 0;
for (int i = 0; i < Wm; i++) {
int p = x + i - Rm;
if (p < 0 || p >= W) continue;
sum += msk[i] * tmp[p + y * W];
}
dst[x + y * W] = new Color(1, 1, 1, sum);
}
}
var createTexture = new Texture2D(W, H);
createTexture.SetPixels(dst);
createTexture.Apply();
if (isCache)
{
_textureCache.Add(tex, createTexture);
}
return createTexture;
}
public static void Release()
{
_textureCache.Clear();
}
}
사전 준비로
・원래의 텍스처의 ImportSetting의 Read/Write Enable가 유효한 것
있습니다. 하지 않으면 텍스처의 픽셀 정보를 읽을 수 없기 때문에.
알려진 문제점
Unity2D의 스프라이트에도 적용하고 싶었지만 스프라이트의 원본 이미지의 텍스처를 흐리게 할 수 있어도 스프라이트에 적용하는 방법을 모른다.
어쩔 수 없기 때문에, Sprite.Create라는 것을 사용하여 Sprite 그 자체를 생성하는 것에.
var spr = GetComponent<SpriteRenderer>();
var tex = BuildTexture.CreateBlurTexture(spr.sprite.texture, 2.0f);
spr.sprite = Sprite.Create(tex, spr.sprite.rect,new Vector2(0.5f,0.5f),16.0f);
우선, 지금 사용하고 있는 스프라이트를 블러 이미지로 바꿨습니다.
하지만 Sprite.Create 에 건네주는 PixelsPerUnit 의 값이 어디로부터 취득하면 좋은가 불명.
맞지 않으면 사이즈가 어긋나 버리기 때문에 무슨 일인가. 이번은 16이라고 알고 있었으므로 16을 설정했습니다만・・・.
그런 이렇게
이런 느낌의 일을 할 수 있게 됩니다 (그대로 뒤에 두거나, 색을 바꾸어 보거나, OrderInLayer로 굳이 위에 거듭해 보거나)
텍스처 자체는 별개이므로 DrawCall 삭감과는 전혀 되지 않습니다만, 매 프레임 GPU로 쉐이더 처리하는 것보다 유효한 경우도 있는 것은···?
···없는가···.
이 콘텐츠는 유니티 찬 라이센스에서 제공됩니다.
Reference
이 문제에 관하여(Unity에서 흐림 이미지 동적 생성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/divideby_zero/items/4c02177a56f7d500d4c0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
아주 쉽게 할 수 있었다. (단, 메모리 사용량이나 처리 속도를 고려하지 않으면)
소스 코드적으로는 htp // d. 하테나. 네. jp/코 rcぇ/20090628/1246208145 의 가우시안필을 거의 둥근 파크리.
필요한 것이 그 자체의 흐림 이미지가 아니라 단색이었기 때문에, 알파치만을 취득하도록 조금 수정.
게다가, 아무렇지도 않게 캐쉬해 벌써 블러 이미지 작성이 끝난 경우는 캐쉬한 텍스처를 돌려주도록 해 보거나.
Release 메소드 준비해 보았지만, 이것으로 제대로 개방될지 어떨지는 불명(Dictionary를 clear하고 있을 뿐)
using System.Linq;
using UnityEngine;
using System.Collections.Generic;
public static class BuildTexture
{
private static Dictionary<Texture2D, Texture2D> _textureCache = new Dictionary<Texture2D, Texture2D>();
public static Texture2D CreateBlurTexture(Texture2D tex, float sig,bool isCache = true)
{
if (isCache && _textureCache.ContainsKey(tex)) return _textureCache[tex];
int W = tex.width;
int H = tex.height;
int Wm = (int)(Mathf.Ceil(3.0f * sig) * 2 + 1);
int Rm = (Wm - 1) / 2;
//フィルタ
float[] msk = new float[Wm];
sig = 2 * sig * sig;
float div = Mathf.Sqrt(sig * Mathf.PI);
//フィルタの作成
for (int x = 0; x < Wm; x++) {
int p = (x - Rm) * (x - Rm);
msk[x] = Mathf.Exp(-p / sig) / div;
}
var src = tex.GetPixels(0).Select(x => x.a).ToArray();
var tmp = new float[src.Length];
var dst = new Color[src.Length];
//垂直方向
for (int x = 0; x < W; x++) {
for (int y = 0; y < H; y++) {
float sum = 0;
for (int i = 0; i < Wm; i++) {
int p = y + i - Rm;
if (p < 0 || p >= H) continue;
sum += msk[i] * src[x + p * W];
}
tmp[x + y * W] = sum;
}
}
//水平方向
for (int x = 0; x < W; x++) {
for (int y = 0; y < H; y++) {
float sum = 0;
for (int i = 0; i < Wm; i++) {
int p = x + i - Rm;
if (p < 0 || p >= W) continue;
sum += msk[i] * tmp[p + y * W];
}
dst[x + y * W] = new Color(1, 1, 1, sum);
}
}
var createTexture = new Texture2D(W, H);
createTexture.SetPixels(dst);
createTexture.Apply();
if (isCache)
{
_textureCache.Add(tex, createTexture);
}
return createTexture;
}
public static void Release()
{
_textureCache.Clear();
}
}
사전 준비로
・원래의 텍스처의 ImportSetting의 Read/Write Enable가 유효한 것
있습니다. 하지 않으면 텍스처의 픽셀 정보를 읽을 수 없기 때문에.
알려진 문제점
Unity2D의 스프라이트에도 적용하고 싶었지만 스프라이트의 원본 이미지의 텍스처를 흐리게 할 수 있어도 스프라이트에 적용하는 방법을 모른다.
어쩔 수 없기 때문에, Sprite.Create라는 것을 사용하여 Sprite 그 자체를 생성하는 것에.
var spr = GetComponent<SpriteRenderer>();
var tex = BuildTexture.CreateBlurTexture(spr.sprite.texture, 2.0f);
spr.sprite = Sprite.Create(tex, spr.sprite.rect,new Vector2(0.5f,0.5f),16.0f);
우선, 지금 사용하고 있는 스프라이트를 블러 이미지로 바꿨습니다.
하지만 Sprite.Create 에 건네주는 PixelsPerUnit 의 값이 어디로부터 취득하면 좋은가 불명.
맞지 않으면 사이즈가 어긋나 버리기 때문에 무슨 일인가. 이번은 16이라고 알고 있었으므로 16을 설정했습니다만・・・.
그런 이렇게
이런 느낌의 일을 할 수 있게 됩니다 (그대로 뒤에 두거나, 색을 바꾸어 보거나, OrderInLayer로 굳이 위에 거듭해 보거나)
텍스처 자체는 별개이므로 DrawCall 삭감과는 전혀 되지 않습니다만, 매 프레임 GPU로 쉐이더 처리하는 것보다 유효한 경우도 있는 것은···?
···없는가···.
이 콘텐츠는 유니티 찬 라이센스에서 제공됩니다.
Reference
이 문제에 관하여(Unity에서 흐림 이미지 동적 생성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/divideby_zero/items/4c02177a56f7d500d4c0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Unity2D의 스프라이트에도 적용하고 싶었지만 스프라이트의 원본 이미지의 텍스처를 흐리게 할 수 있어도 스프라이트에 적용하는 방법을 모른다.
어쩔 수 없기 때문에, Sprite.Create라는 것을 사용하여 Sprite 그 자체를 생성하는 것에.
var spr = GetComponent<SpriteRenderer>();
var tex = BuildTexture.CreateBlurTexture(spr.sprite.texture, 2.0f);
spr.sprite = Sprite.Create(tex, spr.sprite.rect,new Vector2(0.5f,0.5f),16.0f);
우선, 지금 사용하고 있는 스프라이트를 블러 이미지로 바꿨습니다.
하지만 Sprite.Create 에 건네주는 PixelsPerUnit 의 값이 어디로부터 취득하면 좋은가 불명.
맞지 않으면 사이즈가 어긋나 버리기 때문에 무슨 일인가. 이번은 16이라고 알고 있었으므로 16을 설정했습니다만・・・.
그런 이렇게
이런 느낌의 일을 할 수 있게 됩니다 (그대로 뒤에 두거나, 색을 바꾸어 보거나, OrderInLayer로 굳이 위에 거듭해 보거나)
텍스처 자체는 별개이므로 DrawCall 삭감과는 전혀 되지 않습니다만, 매 프레임 GPU로 쉐이더 처리하는 것보다 유효한 경우도 있는 것은···?
···없는가···.
이 콘텐츠는 유니티 찬 라이센스에서 제공됩니다.
Reference
이 문제에 관하여(Unity에서 흐림 이미지 동적 생성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/divideby_zero/items/4c02177a56f7d500d4c0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Unity에서 흐림 이미지 동적 생성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/divideby_zero/items/4c02177a56f7d500d4c0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)