void Update() { UpdateLights(); if (!_render) { return; } if (_photons == null) { _photons = new Photon[maxPhotons]; } // add new photons if (_lights.Length > 0) { for (int i = 0; i < _photons.Length; i++) { if (!_photons[i].alive) { float u = Random.value * _totalLightSurfaceArea; LightSource light = null; float cdf = 0f; for (int li = 0; li < _lights.Length; li++) { cdf += /*_lights[li].intensity **/ _lights[li]._surfaceArea; if (u <= cdf) { light = _lights[li]; break; } } if (light == null) { light = _lights[_lights.Length - 1]; } light.MakePhoton(ref _photons[i]); _photons[i].alive = true; } } } // trace photons for (int i = 0; i < _photons.Length; i++) { //// the should all be alive - no branch needed //if( !_photons[i].alive ) // continue; RaycastHit hitInfo; if (Physics.Raycast(_photons[i].position + 0.01f * _photons[i].next_dir, _photons[i].next_dir, out hitInfo)) { _photons[i].intensity /= 1f + (hitInfo.point - _photons[i].position).magnitude * 0.1f; //_photons[i].intensity /= Mathf.Max( 1f, (hitInfo.point - _photons[i].position).sqrMagnitude ); //if( Random.value < 0.2f ) // Debug.DrawLine( _photons[i].position, hitInfo.point, new Color( 1f, 1f, 1f, _photons[i].intensity.magnitude*0.1f ), 1f ); Color existingRadiance = Color.black; LightFlood lf = hitInfo.collider.GetComponent <LightFlood>(); if (lf) { lf.Hit(ref _photons[i], ref hitInfo, out existingRadiance); } // cosine rule for energy loss _photons[i].intensity *= Vector3.Dot(hitInfo.normal, -_photons[i].next_dir); //_photons[i].intensity += 0.1f * new Vector3( existingRadiance.r, existingRadiance.g, existingRadiance.b ); _photons[i].intensity = new Vector3(_photons[i].intensity.x * lf.color.r, _photons[i].intensity.y * lf.color.g, _photons[i].intensity.z * lf.color.b); // add whatever radiance was there before as well _photons[i].position = hitInfo.point; if (Vector3.Dot(_photons[i].next_dir = Random.onUnitSphere, hitInfo.normal) < 0f) { _photons[i].next_dir = -_photons[i].next_dir; } if (_photons[i].intensity.sqrMagnitude < 0.01f) { _photons[i].alive = false; } } else { //Debug.DrawLine( _photons[i].position, _photons[i].position + 100f * _photons[i].next_dir, new Color( 1f, 1f, 1f, _photons[i].intensity * 0.01f ), 1f ); // photon escaped scene _photons[i].alive = false; } } }