Created
October 27, 2013 17:32
-
-
Save bcatcho/7185422 to your computer and use it in GitHub Desktop.
lightprobe lighting in unity3d: This was a quick test made in a couple of hours. Seems to get the job done.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
public class lightprobemanager : MonoBehaviour | |
{ | |
public Color ambient; | |
public Light[] lights; | |
private float[] _coefficients; | |
private int _probeCount; | |
private const int _coefficientsPerProbe = 27; | |
private Vector3[] _probePositions; | |
void Start() | |
{ | |
LightmapSettings.lightProbes = Instantiate(LightmapSettings.lightProbes) as LightProbes; | |
_coefficients = LightmapSettings.lightProbes.coefficients; | |
_probeCount = LightmapSettings.lightProbes.count; | |
_probePositions = LightmapSettings.lightProbes.positions; | |
} | |
void UpdateLightProbes() | |
{ | |
int i = 0; | |
i = 0; | |
while (i < _coefficients.Length) | |
{ | |
_coefficients[i] = 0f; | |
i++; | |
} | |
// i =0; | |
// while (i < _probeCount) | |
// { | |
// AddSHAmbientLight(ambient, _coefficients, i * _coefficientsPerProbe); | |
// i++; | |
// } | |
foreach (Light l in lights) | |
{ | |
if (l.type == LightType.Directional) | |
{ | |
i = 0; | |
while (i < _probeCount) | |
{ | |
AddSHDirectionalLight(l.color, -l.transform.forward, l.intensity, _coefficients, i * _coefficientsPerProbe); | |
i++; | |
} | |
} | |
else if (l.type == LightType.Point) | |
{ | |
i = 0; | |
while (i < _probeCount) | |
{ | |
AddSHPointLight(l.color, l.transform.position, l.range, l.intensity, _coefficients, i * _coefficientsPerProbe, _probePositions[i]); | |
i++; | |
} | |
} | |
} | |
LightmapSettings.lightProbes.coefficients = _coefficients; | |
} | |
void Update() | |
{ | |
UpdateLightProbes(); | |
} | |
void AddSHAmbientLight(Color color, float[] coefficients, int index) | |
{ | |
float k2SqrtPI = 3.54490770181F; | |
coefficients[index + 0] += color.r * k2SqrtPI; | |
coefficients[index + 1] += color.g * k2SqrtPI; | |
coefficients[index + 2] += color.b * k2SqrtPI; | |
} | |
void AddSHDirectionalLight(Color color, Vector3 direction, float intensity, float[] coefficients, int index) | |
{ | |
float kInv2SqrtPI = 0.28209479177F; | |
float kSqrt3Div2SqrtPI = 0.4886025119F; | |
float kSqrt15Div2SqrtPI = 1.09254843059F; | |
float k3Sqrt5Div4SqrtPI = 0.94617469576F; | |
float kSqrt15Div4SqrtPI = 0.5462742153F; | |
float kOneThird = 0.33333333333F; | |
float[] dirFactors = new float[9]; | |
dirFactors[0] = kInv2SqrtPI; | |
dirFactors[1] = -direction.y * kSqrt3Div2SqrtPI; | |
dirFactors[2] = direction.z * kSqrt3Div2SqrtPI; | |
dirFactors[3] = -direction.x * kSqrt3Div2SqrtPI; | |
dirFactors[4] = direction.x * direction.y * kSqrt15Div2SqrtPI; | |
dirFactors[5] = -direction.y * direction.z * kSqrt15Div2SqrtPI; | |
dirFactors[6] = (direction.z * direction.z - kOneThird) * k3Sqrt5Div4SqrtPI; | |
dirFactors[7] = -direction.x * direction.z * kSqrt15Div2SqrtPI; | |
dirFactors[8] = (direction.x * direction.x - direction.y * direction.y) * kSqrt15Div4SqrtPI; | |
float kNormalization = 2.95679308573F; | |
intensity *= 2.0F; | |
float rscale = color.r * intensity * kNormalization; | |
float gscale = color.g * intensity * kNormalization; | |
float bscale = color.b * intensity * kNormalization; | |
int i = 0; | |
while (i < 9) | |
{ | |
float c = dirFactors[i]; | |
coefficients[index + 3 * i + 0] += c * rscale; | |
coefficients[index + 3 * i + 1] += c * gscale; | |
coefficients[index + 3 * i + 2] += c * bscale; | |
++i; | |
} | |
} | |
void AddSHPointLight(Color color, Vector3 position, float range, float intensity, float[] coefficients, int index, Vector3 probePosition) | |
{ | |
Vector3 probeToLight = position - probePosition; | |
float attenuation = 1.0F / (1.0F + 25.0F * probeToLight.sqrMagnitude / range * range); | |
AddSHDirectionalLight(color, probeToLight.normalized, intensity * attenuation, coefficients, index); | |
} | |
#if UNITY_EDITOR | |
public bool GenerateProbeGrid = false; | |
public float ProbeGridCellSize = .5f; | |
public Bounds ProbeGridSize; | |
private void OnDrawGizmosSelected() | |
{ | |
Gizmos.DrawWireCube(transform.position + ProbeGridSize.center, ProbeGridSize.size); | |
} | |
private void RegenerateProbeGrid() | |
{ | |
int width = Mathf.RoundToInt( ProbeGridSize.size.x / ProbeGridCellSize); | |
int depth = Mathf.RoundToInt( ProbeGridSize.size.z / ProbeGridCellSize); | |
var probeLocations = new Vector3[width * depth + 1]; | |
// now do the grid | |
for(int w = 0; w < width; w++) | |
{ | |
for(int d = 0; d < depth; d++) | |
{ | |
probeLocations[w*width + d] = ProbeGridSize.min + new Vector3(w, 0, d) * ProbeGridCellSize; | |
} | |
} | |
// first add a probe high up to make it a volume | |
probeLocations[width * depth] = ProbeGridSize.center+Vector3.up*ProbeGridSize.extents.y; | |
var probeGroup = GetComponent<LightProbeGroup>(); | |
probeGroup.probePositions = probeLocations; | |
} | |
private void OnValidate() | |
{ | |
if (GenerateProbeGrid) | |
{ | |
GenerateProbeGrid = false; | |
RegenerateProbeGrid(); | |
} | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment