Last active
August 28, 2023 23:54
-
-
Save rngtm/ac4a7ae611db1fe5553fe925b1fe5901 to your computer and use it in GitHub Desktop.
Spriteにガウシアンブラーを適用した結果をMeshRendererで表示するスクリプトとシェーダー (ブラーの復習に書いた)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Hidden/GaussianBlur" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
_Variance ("Variance", Float) = 1.0 | |
_Range ("Range (px)", Float) = 5.0 | |
_GaussianSum ("Gaussian Sum", Float) = 1.0 | |
_KernelSize ("Kernel Size", Float) = 5 | |
} | |
SubShader | |
{ | |
Cull Off ZWrite Off ZTest Always | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
float4 vertex : SV_POSITION; | |
}; | |
v2f vert(appdata v) | |
{ | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = v.uv; | |
return o; | |
} | |
sampler2D _MainTex; | |
float4 _MainTex_TexelSize; // x: 1/width y:1/height | |
float _Variance; // 標準偏差 | |
float _Range; // サンプリング範囲 | |
float _GaussianSum; // ガウス分布の合計 | |
int _KernelSize; // カーネルの大きさ | |
#define V (_Variance) // 分散 | |
// 1次元ガウス分布 | |
float Gauss(float x) | |
{ | |
return exp(- x * x / (2.0 * V)) | |
/ sqrt(2.0 * V * UNITY_TWO_PI); | |
} | |
// 2次元ガウス分布 | |
float Gauss(float2 p) | |
{ | |
return exp(- dot(p, p) / (2.0 * V)) | |
/ sqrt(2.0 * V * UNITY_PI); | |
} | |
fixed4 frag(v2f i) : SV_Target | |
{ | |
float4 c = 0; | |
#define KERNEL_SIZE _KernelSize | |
#define N (KERNEL_SIZE * KERNEL_SIZE) | |
for (int y = -KERNEL_SIZE/2; y <= KERNEL_SIZE/2; y++) | |
{ | |
float ty = (float)y / KERNEL_SIZE; | |
for (int x = -KERNEL_SIZE/2; x <= KERNEL_SIZE/2; x++) | |
{ | |
float tx = (float)x / KERNEL_SIZE; | |
float2 p = float2(tx, ty); | |
float2 uv = i.uv + p * _Range * _MainTex_TexelSize.xy; | |
c += Gauss(p) * tex2D(_MainTex, uv) / _GaussianSum; | |
} | |
} | |
c.a = 1.0; | |
return c; | |
} | |
ENDCG | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Rendering.Utility; | |
using UnityEngine; | |
public class SpriteBlur : MonoBehaviour | |
{ | |
[SerializeField] private Sprite sprite; | |
[SerializeField, Range(0.01f, 2f)] private float variance = 1f; | |
[SerializeField] private float range = 5f; | |
[SerializeField, Range(1, 9)] private int kernelSize = 5; | |
private MeshRenderer meshRenderer; | |
private RenderTexture renderTexture; | |
private Material _renderMaterial; | |
private Shader blurShader; | |
private Material _blurMaterial; | |
private float _gaussianSum; | |
private void Start() | |
{ | |
meshRenderer = GetComponent<MeshRenderer>(); | |
_blurMaterial = CreateGaussianBlurMaterial(); | |
_renderMaterial = meshRenderer.material; | |
CreateRenderTexture(); | |
_renderMaterial.mainTexture = renderTexture; | |
ExecuteBlur(); | |
} | |
private void OnValidate() | |
{ | |
ExecuteBlur(); | |
} | |
private void ExecuteBlur() | |
{ | |
if (sprite == null) | |
{ | |
return; | |
} | |
if (renderTexture == null) | |
{ | |
return; | |
} | |
if (_blurMaterial == null) | |
{ | |
return; | |
} | |
_gaussianSum = GaussianDistribution.GetSum(kernelSize, variance); | |
_blurMaterial.SetFloat("_GaussianSum", _gaussianSum); | |
_blurMaterial.SetFloat("_Variance", variance); | |
_blurMaterial.SetFloat("_Range", range); | |
_blurMaterial.SetInt("_KernelSize", kernelSize); | |
Graphics.Blit(sprite.texture, renderTexture, _blurMaterial); | |
} | |
private void OnDestroy() | |
{ | |
DestroyRenderTexture(); | |
_renderMaterial.mainTexture = null; | |
DestroyMaterial(); | |
} | |
private Material CreateGaussianBlurMaterial() | |
{ | |
return CreateMaterial("Hidden/GaussianBlur"); | |
} | |
static Material CreateMaterial(string shaderName) | |
{ | |
var shader = Shader.Find(shaderName); | |
if (shader == null) | |
{ | |
Debug.LogError($"Fail to find shader: {shaderName}"); | |
} | |
return new Material(shader); | |
} | |
private void DestroyMaterial() | |
{ | |
Destroy(_renderMaterial); | |
Destroy(_blurMaterial); | |
_blurMaterial = null; | |
blurShader = null; | |
} | |
private void CreateRenderTexture() | |
{ | |
renderTexture = new RenderTexture(512, 512, 0); | |
} | |
private void DestroyRenderTexture() | |
{ | |
renderTexture.Release(); | |
renderTexture = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment