public static float Evaluate(ref VolumeFalloffEngineData falloff, ref OrientedBBox obb, float3 positionWS, float distanceWS) { float3x3 obbFrame = new float3x3(obb.right, obb.up, math.cross(obb.up, obb.right)); float3 obbExtents = new float3(obb.extentX, obb.extentY, obb.extentZ); float3 samplePositionBS = math.mul(obbFrame, positionWS - obb.center); float3 samplePositionBCS = samplePositionBS / obbExtents; bool isInsideVolume = math.max(math.abs(samplePositionBCS.x), math.max(math.abs(samplePositionBCS.y), math.abs(samplePositionBCS.z))) < 1.0f; if (!isInsideVolume) { return(0.0f); } float3 samplePositionBNDC = samplePositionBCS * 0.5f + 0.5f; float volumeWeight = VolumeFalloff.ComputeVolumeFalloffWeight( samplePositionBNDC, distanceWS, falloff.rcpFaceFadePos, falloff.rcpFaceFadeNeg, falloff.rcpDistFadeLen, falloff.endTimesRcpDistFadeLen ); volumeWeight *= falloff.weight; return(volumeWeight); }
private void ComputeEngineData(ref List <AmbientAudioVolume> instances) { for (int i = 0, iLen = instances.Count; i < iLen; ++i) { AmbientAudioVolume ambientAudioVolume = instances[i]; VolumeFalloff volumeFalloff = ambientAudioVolume.volumeFalloff; VolumeFalloff.ComputeOrientedBBoxFromFalloffAndTransform(out VolumeFalloff.OrientedBBox obb, ref volumeFalloff, ambientAudioVolume.transform); bounds[i] = obb; falloffData[i] = volumeFalloff.ConvertToEngineData(); audioData[i] = ambientAudioVolume.ConvertToEngineData(); } }
private void ComputeAudioVolumeAtPositionAndDirectionFromEngineData(float3 targetPositionWS, float3 targetTangentDirectionWS, float3 targetForwardDirectionWS) { for (int i = 0; i < audioVolumeCount; ++i) { audioVolume[i] = float2.zero; } for (int i = 0; i < count; ++i) { VolumeFalloff.OrientedBBox obb = bounds[i]; AmbientAudioVolume.AmbientAudioVolumeEngineData audioEngineData = audioData[i]; VolumeFalloff.VolumeFalloffEngineData falloffEngineData = falloffData[i]; float distanceWS = math.length(obb.center - targetPositionWS); float weight = VolumeFalloff.Evaluate(ref falloffEngineData, ref obb, targetPositionWS, distanceWS); if (weight < 1e-5f) { continue; } // TODO: Figure out how to modulate left and right ear independantly. float3 audioPositionOffsetWS = audioEngineData.audioPositionWS - targetPositionWS; float spatialAttenuation = 1.0f / math.max(1.0f, math.dot(audioPositionOffsetWS, audioPositionOffsetWS)); float audioVolumeIsotropic = audioEngineData.audioVolume * weight * spatialAttenuation; float3 targetToAudioDirectionWS = math.normalize(audioPositionOffsetWS); // Debug.Log("spatialAttenuation = " + spatialAttenuation); // Perform simple wrap lighting model for ear direction attenuation. // TODO: Research realistic attenuation models. float2 earWeights = new float2( math.saturate(math.dot(targetTangentDirectionWS, targetToAudioDirectionWS) * -0.5f + 0.5f), math.saturate(math.dot(targetTangentDirectionWS, targetToAudioDirectionWS) * 0.5f + 0.5f) ); // Add behind head attenuation to help differentiate between things in front and things behind the camera. earWeights *= (1.0f - math.max(0.0f, math.dot(-targetForwardDirectionWS, targetToAudioDirectionWS))) * 0.5f + 0.5f; audioVolume[audioEngineData.audioIndex] = earWeights * audioVolumeIsotropic + audioVolume[audioEngineData.audioIndex]; } }
private static float ComputeVolumeFalloffWeight( float3 samplePositionBoxNDC, float distanceWS, float3 rcpPosFaceFade, float3 rcpNegFaceFade, float rcpDistFadeLen, float endTimesRcpDistFadeLen ) { // We have to account for handedness. samplePositionBoxNDC.z = 1 - samplePositionBoxNDC.z; float3 posF = VolumeFalloff.Remap10(samplePositionBoxNDC, rcpPosFaceFade, rcpPosFaceFade); float3 negF = VolumeFalloff.Remap01(samplePositionBoxNDC, rcpNegFaceFade, 0); float fade = posF.x * posF.y * posF.z * negF.x * negF.y * negF.z; float dstF = 1.0f;//VolumeFalloff.Remap10(distanceWS, rcpDistFadeLen, endTimesRcpDistFadeLen); return(fade * dstF); }
public static void ComputeOrientedBBoxFromFalloffAndTransform(out OrientedBBox obb, ref VolumeFalloff falloff, Transform t) { Matrix4x4 m = falloff.isTransformScaleUsed ? (t.localToWorldMatrix * Matrix4x4.TRS(falloff.center, Quaternion.identity, falloff.size)) : Matrix4x4.TRS(t.position + (t.rotation * falloff.center), t.rotation, falloff.size); obb = new OrientedBBox(m); }