자라고싶다
[UnityShader/HLSL] Simple Sub Surface Scattering 본문
Shader "Custom/SSS_Forward_MainLight"
{
Properties
{
_BaseColor("BaseColor", Color) = (1,1,1,1)
_Thickness("Subsurface Thickness", Range(0, 1)) = 0.5
_ScatteringFactor("ScatteringFactor", Range(1,4)) = 2
[HDR]_SSSColor("Subsurface Color", Color) = (1, 0.4, 0.3, 1)
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float3 normalWS : TEXCOORD0;
float3 positionWS : TEXCOORD1;
};
float _Thickness;
half4 _SSSColor;
half4 _BaseColor;
float _ScatteringFactor;
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz);
OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS);
OUT.positionHCS = TransformWorldToHClip(OUT.positionWS);
return OUT;
}
float3 SubsurfaceLighting(float3 N, float3 L, float3 V, float thickness)
{
float3 H = normalize(L + V);
float NdotL = saturate(dot(N, L));
float forwardScatter = pow(saturate(dot(-L, V)), _ScatteringFactor); // Light passing through
//float forwardScatter = pow(saturate(dot(-L, V)), _ScatteringFactor) * (1 / (4 * 3.1415)); //HeyneyGreenstein Phase Function
return _SSSColor.rgb * forwardScatter * thickness * (1-NdotL);
}
float4 frag(Varyings IN) : SV_Target
{
float3 N = normalize(IN.normalWS);
float3 V = normalize(_WorldSpaceCameraPos - IN.positionWS);
float3 AL = SampleSH(N);
Light mainLight = GetMainLight();
float3 L = normalize(mainLight.direction);
float NdotL = saturate(dot(N,L));
float3 sss = SubsurfaceLighting(N, L, V, _Thickness);
float4 color = _BaseColor;
color.rgb *= mainLight.color;
color.rgb *= NdotL;
color.rgb += _BaseColor.rgb * AL;
color.rgb += sss.rgb * mainLight.color;
return float4(color.rgb, 1);
}
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
}
forwardScatter 에 (1 / (4 * 3.1415)) 를 곱하면 HeyneyGreenstein Phase Function 에 좀 더 근접한 수식을 구현할 수 있다.
추가로 공부할 것
- Diffusion Profile
- Thickness Map 추가
- ScreenSpace 기반 SSS 구현
- Additional Light 추가?
'Unity > UnityShader' 카테고리의 다른 글
[HLSL]Henyey-Greenstein Phase Function (0) | 2025.03.25 |
---|---|
[CustomEditor]프로퍼티 #1 (0) | 2024.04.23 |
[HLSL]Tessellation + Displacement (1) | 2023.11.23 |
[HLSL] Diffuse Wrap + Shadow Ramp (0) | 2023.10.17 |
[HLSL]2 Pass Outline (0) | 2023.10.16 |