This commit is contained in:
Jan Racek
2026-03-24 13:00:54 +01:00
parent 53e993f58e
commit 4aa4e49424
145 changed files with 10853 additions and 2965 deletions

View File

@@ -1,88 +1,87 @@
using UnityEngine;
public static class PSXLightingBaker
namespace SplashEdit.RuntimeCode
{
/// <summary>
/// Computes the per-vertex lighting from all scene light sources.
/// Incorporates ambient, diffuse, and spotlight falloff.
/// </summary>
/// <param name="vertex">The world-space position of the vertex.</param>
/// <param name="normal">The normalized world-space normal of the vertex.</param>
/// <returns>A Color representing the lit vertex.</returns>
public static Color ComputeLighting(Vector3 vertex, Vector3 normal)
public static class PSXLightingBaker
{
Color finalColor = Color.black;
Light[] lights = Object.FindObjectsByType<Light>(FindObjectsSortMode.None);
foreach (Light light in lights)
/// <summary>
/// Computes the per-vertex lighting from all scene light sources.
/// Incorporates ambient, diffuse, and spotlight falloff.
/// </summary>
/// <param name="vertex">The world-space position of the vertex.</param>
/// <param name="normal">The normalized world-space normal of the vertex.</param>
/// <param name="sceneLights">Pre-gathered array of enabled scene lights (pass to avoid per-vertex FindObjectsByType).</param>
/// <returns>A Color representing the lit vertex.</returns>
public static Color ComputeLighting(Vector3 vertex, Vector3 normal, Light[] sceneLights)
{
if (!light.enabled)
continue;
Color finalColor = Color.black;
Color lightContribution = Color.black;
if (light.type == LightType.Directional)
foreach (Light light in sceneLights)
{
Vector3 lightDir = -light.transform.forward;
float NdotL = Mathf.Max(0f, Vector3.Dot(normal, lightDir));
lightContribution = light.color * light.intensity * NdotL;
}
else if (light.type == LightType.Point)
{
Vector3 lightDir = light.transform.position - vertex;
float distance = lightDir.magnitude;
lightDir.Normalize();
Color lightContribution = Color.black;
float NdotL = Mathf.Max(0f, Vector3.Dot(normal, lightDir));
float attenuation = 1.0f / Mathf.Max(distance * distance, 0.0001f);
lightContribution = light.color * light.intensity * NdotL * attenuation;
}
else if (light.type == LightType.Spot)
{
Vector3 L = light.transform.position - vertex;
float distance = L.magnitude;
L = L / distance;
float NdotL = Mathf.Max(0f, Vector3.Dot(normal, L));
float attenuation = 1.0f / Mathf.Max(distance * distance, 0.0001f);
float outerAngleRad = (light.spotAngle * 0.5f) * Mathf.Deg2Rad;
float innerAngleRad = outerAngleRad * 0.8f;
if (light is Light spotLight)
if (light.type == LightType.Directional)
{
if (spotLight.innerSpotAngle > 0)
Vector3 lightDir = -light.transform.forward;
float NdotL = Mathf.Max(0f, Vector3.Dot(normal, lightDir));
lightContribution = light.color * light.intensity * NdotL;
}
else if (light.type == LightType.Point)
{
Vector3 lightDir = light.transform.position - vertex;
float distance = lightDir.magnitude;
lightDir.Normalize();
float NdotL = Mathf.Max(0f, Vector3.Dot(normal, lightDir));
float attenuation = 1.0f / Mathf.Max(distance * distance, 0.0001f);
lightContribution = light.color * light.intensity * NdotL * attenuation;
}
else if (light.type == LightType.Spot)
{
Vector3 L = light.transform.position - vertex;
float distance = L.magnitude;
L = L / distance;
float NdotL = Mathf.Max(0f, Vector3.Dot(normal, L));
float attenuation = 1.0f / Mathf.Max(distance * distance, 0.0001f);
float outerAngleRad = (light.spotAngle * 0.5f) * Mathf.Deg2Rad;
float innerAngleRad = outerAngleRad * 0.8f;
if (light is Light spotLight)
{
innerAngleRad = (spotLight.innerSpotAngle * 0.5f) * Mathf.Deg2Rad;
if (spotLight.innerSpotAngle > 0)
{
innerAngleRad = (spotLight.innerSpotAngle * 0.5f) * Mathf.Deg2Rad;
}
}
float cosOuter = Mathf.Cos(outerAngleRad);
float cosInner = Mathf.Cos(innerAngleRad);
float cosAngle = Vector3.Dot(L, -light.transform.forward);
if (cosAngle >= cosOuter)
{
float spotFactor = Mathf.Clamp01((cosAngle - cosOuter) / (cosInner - cosOuter));
spotFactor = Mathf.Pow(spotFactor, 4.0f);
lightContribution = light.color * light.intensity * NdotL * attenuation * spotFactor;
}
else
{
lightContribution = Color.black;
}
}
float cosOuter = Mathf.Cos(outerAngleRad);
float cosInner = Mathf.Cos(innerAngleRad);
float cosAngle = Vector3.Dot(L, -light.transform.forward);
if (cosAngle >= cosOuter)
{
float spotFactor = Mathf.Clamp01((cosAngle - cosOuter) / (cosInner - cosOuter));
spotFactor = Mathf.Pow(spotFactor, 4.0f);
lightContribution = light.color * light.intensity * NdotL * attenuation * spotFactor;
}
else
{
lightContribution = Color.black;
}
finalColor += lightContribution;
}
finalColor += lightContribution;
finalColor.r = Mathf.Clamp(finalColor.r, 0.0f, 0.8f);
finalColor.g = Mathf.Clamp(finalColor.g, 0.0f, 0.8f);
finalColor.b = Mathf.Clamp(finalColor.b, 0.0f, 0.8f);
finalColor.a = 1f;
return finalColor;
}
finalColor.r = Mathf.Clamp(finalColor.r, 0.0f, 0.8f);
finalColor.g = Mathf.Clamp(finalColor.g, 0.0f, 0.8f);
finalColor.b = Mathf.Clamp(finalColor.b, 0.0f, 0.8f);
finalColor.a = 1f;
return finalColor;
}
}