- RenderStreamOutput 을 URP 17 RenderGraph API 로 마이그레이션
(옛 Execute() 도 Compatibility Mode 호환용으로 유지)
- 알파 합성 셰이더 신규: Pre/Post 비교(블룸/글로우) + NiloToon Prepass G + 가우시안 블러
- 알파 채널 별도 Spout 송신 추가 ("Streamingle Spout Alpha Output")
- 그레이스케일 RGB 마스크, A=1
- spout_ndi_normalizer.exe 외부 프로세스 자동 실행/종료 (SpoutNdiLauncher 병합)
- Display 드롭다운 / Vsync / AlwaysOnTop / HideCursor / Realtime / NoActivate 옵션
- exe 가 있으면 강제 종료 후 단일 인스턴스 보장
- 내부 옵션(exe 경로, window size 등)은 [HideInInspector]
- ScreenshotManager 가 RenderStreamOutput 의 합성 결과를 그대로 PNG 저장
- 자체 카메라 렌더/셰이더 관리 제거 → 알파 품질 라이브 출력과 동일
- captureWidth/Height 지정 시 한 프레임 임시 고해상도 렌더 후 원복
- spout_ndi_normalizer.exe 위치: Resources → StreamingAssets/SpoutNdiNormalizer
- URP Asset: Allow Post Process Alpha Output 활성화
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
4.5 KiB
Plaintext
97 lines
4.5 KiB
Plaintext
// 후처리 후 RGB + 합성 알파를 출력하는 풀스크린 Blit 셰이더.
|
|
//
|
|
// 알파 = saturate(prepassAlpha + bloomAlpha)
|
|
// prepassAlpha = NiloToon Prepass G 채널 (캐릭터 외곽, AA 포함)
|
|
// bloomAlpha = saturate((postLum - preLum) * _BloomAlphaGain) — 후처리가 추가한 빛
|
|
//
|
|
// _PreColorTex 가 비어있으면 bloomAlpha = 0 (Prepass 만 사용)
|
|
// _NiloToonPrepassBufferTex 가 비어있으면 prepassAlpha = 0 (Bloom diff 만 사용)
|
|
Shader "Hidden/Streamingle/AlphaCompose"
|
|
{
|
|
Properties
|
|
{
|
|
_SourceAlphaGain ("Source Alpha Gain (cameraColor.a)", Range(0, 4)) = 1.0
|
|
_BloomAlphaGain ("Bloom Alpha Gain", Range(0, 20)) = 5.0
|
|
_PrepassAlphaGain ("Prepass Alpha Gain", Range(0, 4)) = 1.0
|
|
_AlphaBlurRadius ("Alpha Blur Radius (texels)", Range(0, 5)) = 1.0
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
|
|
|
|
Pass
|
|
{
|
|
ZWrite Off ZTest Always Cull Off
|
|
Blend Off
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
|
|
|
// _BlitTexture 는 Blit.hlsl 가 이미 선언함 (후처리 후 cameraColor)
|
|
TEXTURE2D(_PreColorTex); // 후처리 전 cameraColor
|
|
SAMPLER(sampler_PreColorTex);
|
|
|
|
TEXTURE2D(_NiloToonPrepassBufferTex); // NiloToon 글로벌
|
|
SAMPLER(sampler_NiloToonPrepassBufferTex);
|
|
|
|
float _SourceAlphaGain;
|
|
float _BloomAlphaGain;
|
|
float _PrepassAlphaGain;
|
|
float _AlphaBlurRadius;
|
|
|
|
// 3x3 가우시안 가중치 (1/4 1/8 1/16) — Prepass G 외곽 부드럽게
|
|
half SamplePrepassAlpha(float2 uv)
|
|
{
|
|
if (_AlphaBlurRadius <= 0.001)
|
|
return SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex,
|
|
sampler_NiloToonPrepassBufferTex, uv).g;
|
|
|
|
float2 t = (1.0 / _ScreenParams.xy) * _AlphaBlurRadius;
|
|
|
|
half a = 0;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv).g * 0.25;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2( 0, t.y)).g * 0.125;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2( 0, -t.y)).g * 0.125;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2( t.x, 0)).g * 0.125;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2(-t.x, 0)).g * 0.125;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2( t.x, t.y)).g * 0.0625;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2(-t.x, t.y)).g * 0.0625;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2( t.x, -t.y)).g * 0.0625;
|
|
a += SAMPLE_TEXTURE2D(_NiloToonPrepassBufferTex, sampler_NiloToonPrepassBufferTex, uv + float2(-t.x, -t.y)).g * 0.0625;
|
|
return a;
|
|
}
|
|
|
|
half4 Frag(Varyings input) : SV_Target
|
|
{
|
|
float2 uv = input.texcoord;
|
|
|
|
half4 postSample = SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, uv);
|
|
half3 postRgb = postSample.rgb;
|
|
half sourceAlpha = postSample.a * _SourceAlphaGain;
|
|
|
|
half3 preRgb = SAMPLE_TEXTURE2D(_PreColorTex, sampler_PreColorTex, uv).rgb;
|
|
|
|
// 후처리가 추가한 luminance (블룸/글로우/플레어 등)
|
|
half postLum = Luminance(postRgb);
|
|
half preLum = Luminance(preRgb);
|
|
half bloomAlpha = saturate((postLum - preLum) * _BloomAlphaGain);
|
|
|
|
// NiloToon Prepass G 채널 알파 (캐릭터 외곽, 가우시안 블러로 AA)
|
|
half prepassAlpha = SamplePrepassAlpha(uv) * _PrepassAlphaGain;
|
|
|
|
half alpha = saturate(sourceAlpha + prepassAlpha + bloomAlpha);
|
|
|
|
return half4(postRgb, alpha);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
Fallback Off
|
|
}
|