0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unityの2DRendererにおけるOpaqueTextureで剣閃エフェクト(2DRenderer中編)

Last updated at Posted at 2025-04-16

# もくじ

2DRenderer前編

2DRenderer後編

概要

ゲームのよくある演出として剣閃の部分をゆがませる表現があります。
UnityURPの3DではOpaqueTextureというRenderEventでAfterRenderingOpaquesくらいまで描画したRenderTextureを別のRenderTextureにBlitしといて後のTransparentの描画時やCustomPostProcessなどで使用できるものです。

2DRendererでも似たような機能としてCameraSortingLayerTextureがあり、それを利用して剣閃エフェクトを作成した事例を説明します。

環境

  • Unity 6000.0.23f1

実装

CameraSortingLayerTexture

2DRendererは3DRendererと違ってOpaqueObject(不透明オブジェクト)とTransparentObject(透過オブジェクト)と分かれておらず、すべてTransparentObjectの扱いなのでCameraSortingLayerTextureの生成タイミングをSortingLayerで指定してあげる必要があります。

1.png

3Dのレンダリング順(色々省略版)

2Dのレンダリング順(色々省略版)

OpaqueTextureがOpaqueObject描画時に使えないのと同様にCameraSortingLayerTextureは生成タイミング以前のSortingLayerの描画時には使えません。

CameraSortingLayerTextureの使い方はOpaqueTexture同じで2DTextureのプロパティ名を_CameraSortingLayerTextureにすることで受け取れます。

剣閃エフェクト

剣閃のMeshはVisualEffectGraphのParticleStripで作成しており、刃の刃先と根本のPositionを常に渡し刃の長さ、角度、向きを計算してます。後はParticleStripは何もしないとParticleが常に繋がってしまうので、過去の剣閃は消したかったので、剣閃ごとにStripIdを変えて過去IDだったらParticleを削除するようにしてます。
3.png

後はShaderでCameraSortingLayerTextureをゆがませるだけです。基本的にはノイズテクスチャをUVスクロールさせて、NormalFromHeightのノードで剣閃のMeshのUVをゆがませScreenPotisionからスクリーンのUVに加算、それでCameraSortingLayerTextureをサンプルすることで背景をゆがませた表現を描画します。自分は3DTextureを3軸にUVスクロールできるSubGraphを作成してより自然なノイズのアニメーションを実現、Normalへの変換も備え付けのノードは荒くなってしまうのでどこかで拝見した式を3DTexture用に改良してCustomFunctionで実装しました。

ちゃんと変換されてますが、正しい計算なのかはちょっと自信ないです。

void HeightToNormal3D_float(UnityTexture3D heightMap, UnitySamplerState samplesState,  float3 uv, float3 heightMapResolution, float normalStrength, out float4 OutColor)
{
    OutColor = 0;

    float3 s = 1/heightMapResolution;
    
    float p = SAMPLE_TEXTURE3D(heightMap, samplesState, uv).x;
    float h1 = SAMPLE_TEXTURE3D(heightMap, samplesState, uv + s * float3(1, 0, 0)).x;
    float v1 = SAMPLE_TEXTURE3D(heightMap, samplesState, uv + s * float3(0, 1, 0)).x;
       
    float2 normal = (p - float2(h1, v1));
    
    normal *= normalStrength;
    
    OutColor = float4(normal, 1, 1);
    
}

そのほか刃に近いところほど歪みを強くしたり発光するエフェクトを追加してたりしてます。
4.png

5.png

まとめ

CameraSortingLayerTextureですがRenderLoopの中で1回しか生成できないのでそれが不便です。透過表現をしたいとき必ず必要になる機能なので複数回生成できるようにしてくれてもいいような気がします。しかも2DRendererは2DLightなどのクラスでinternalでアクセスできないものが多数ありRendererFeatureなどで自前でCameraSortingLayerTextureのようなテクスチャを用意することもできません。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?