원래는 cpu로 그래픽 작업 했는데 글카 나오면서 마이크로프로세서로 병렬처리하는 방법 생겨났다
opengl이 맨 처음 만들어진 그래픽 api였다
directx가 shader라는거 만들었다
opengl하고 directx하고 싸웠는데 opengl이 이전 기능 제거 안 하고 기능 추가 제대로 안 해서 밀릴뻔했는데 요즘(이 글 쓴 때가 언제인진 모르겠지만)은 다시 좋아졌다
LayerMask.NameToLayer()는 생성자나 필드 초기화 구문에서 사용할 수 없다~를 붙여줘야 무시하는 마스크가 된다Shader "URP/FullscreenOutline_DepthNormal"
{
Properties
{
_OutlineColor ("Outline Color", Color) = (0,0,0,1)
_Thickness ("Outline Thickness(px)", Range(1,6)) = 1
_DepthThreshold ("Depth Δ", Range(0,0.02)) = 0.002
_NormalThreshold ("Normal Δ", Range(0,1)) = 0.15
}
SubShader
{
Tags { "RenderPipeline" = "UniversalRenderPipeline" }
Pass
{
Name "FullscreenPass" Tags{ "LightMode"="UniversalRenderer" }
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// 핵심 버퍼
TEXTURE2D_X(_BlitTexture); SAMPLER(sampler_BlitTexture);
TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
TEXTURE2D(_CameraNormalsTexture); SAMPLER(sampler_CameraNormalsTexture);
// 머티리얼 프로퍼티
float4 _OutlineColor;
float _Thickness;
float _DepthThreshold;
float _NormalThreshold;
struct Varyings { float4 positionCS : SV_POSITION; };
Varyings FullscreenVert (uint id : SV_VertexID)
{
Varyings o;
o.positionCS = GetFullScreenTriangleVertexPosition(id);
return o;
}
// depth to linear eye‑space
float LinearEye (float raw) { return Linear01Depth(raw, _ZBufferParams); }
float4 frag (Varyings i) : SV_Target
{
float2 uv = i.positionCS.xy / _ScreenParams.xy;
float2 texel = _Thickness / _ScreenParams.xy;
// 기준 픽셀 깊이·노멀
float depthCenter = LinearEye(SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r);
float3 normalCenter = normalize(SAMPLE_TEXTURE2D(_CameraNormalsTexture, sampler_CameraNormalsTexture, uv).rgb * 2 - 1);
// 최대 변화량 저장 변수 (ASCII 이름!)
float maxDepthDelta = 0.0;
float maxNormalDelta = 0.0;
[unroll] for (int y = -1; y <= 1; ++y)
{
[unroll] for (int x = -1; x <= 1; ++x)
{
if (x == 0 && y == 0) continue;
float2 offset = float2(x, y) * texel;
float d = LinearEye(SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, uv + offset).r);
float3 n = normalize(SAMPLE_TEXTURE2D(_CameraNormalsTexture, sampler_CameraNormalsTexture, uv + offset).rgb * 2 - 1);
maxDepthDelta = max(maxDepthDelta, abs(d - depthCenter));
maxNormalDelta = max(maxNormalDelta, 1 - dot(n, normalCenter)); // 각도 차
}
}
bool isEdge =
(maxDepthDelta > _DepthThreshold) ||
(maxNormalDelta > _NormalThreshold);
float4 src = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, uv);
return isEdge ? _OutlineColor : src;
}
ENDHLSL
}
}
}
배경을 무시하지 않고 외곽선만 따도록 변경.
o1이 딴소리하던거 o3한테 물었더니 한 번에 해결해줌.
이게 맞나 싶긴 한데 일단 해결했으니 ok.
