- God of war 3에서 여러 광원처리 기법
- pixel shader가 느렸던 기기여서 vertex에서 처리
// ref: https://github.com/Unity-Technologies/Graphics/blob/master/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
half3 VertexLighting(float3 positionWS, half3 normalWS)
{
half3 vertexLightColor = half3(0.0, 0.0, 0.0);
#ifdef _ADDITIONAL_LIGHTS_VERTEX
uint lightsCount = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN(lightsCount)
Light light = GetAdditionalLight(lightIndex, positionWS);
half3 lightColor = light.color * light.distanceAttenuation;
vertexLightColor += LightingLambert(lightColor, light.direction, normalWS);
LIGHT_LOOP_END
#endif
return vertexLightColor;
}
struct VStoFS
{
half4 positionCS : SV_POSITION;
half2 uv : TEXCOORD0;
half3 N : TEXCOORD1;
half3 H_Sun : TEXCOORD2;
half3 H_Points : TEXCOORD3;
half3 Diffuse_Sun : TEXCOORD4;
half3 Diffuse_Points : TEXCOORD5;
};
VStoFS vert(in APPtoVS IN)
{
half3 L_points = half3(0, 0, 0);
uint additionalLightsCount = min(GetAdditionalLightsCount(), 3);
for (uint i = 0; i < additionalLightsCount; ++i)
{
Light additionalLight = GetAdditionalLight(i, positionWS);
half3 L_attenuated = additionalLight.direction * additionalLight.distanceAttenuation;
OUT.Diffuse_Points += saturate(dot(N, L_attenuated)) * additionalLight.color;
L_points += L_attenuated;
}
OUT.H_Points = normalize(L_points) + V;
OUT.Diffuse_Sun = saturate(dot(N, L * mainLight.distanceAttenuation)) * mainLight.color;
OUT.H_Sun = normalize(L + V);
}
half4 frag(in VStoFS IN) : SV_Target
{
{
half3 diffuse = diffuseTex * (IN.Diffuse_Sun + IN.Diffuse_Points);
half2 highlights;
highlights.x = pow(saturate(dot(N, H_Sun)), _SpecularPower);
highlights.y = pow(saturate(dot(N, H_Points)), _SpecularPower);
half3 specular = specularMaskTex * ((IN.Diffuse_Sun * highlights.x) + (IN.Diffuse_Points * highlights.y));
half3 result = diffuse + specular;
}