Point Cloud Sound for irregular shaped audio sources

Point Cloud Sound für unregelmäßig geformte Audioquellen
In der Videospielentwicklung sind wir gewohnt, dass Geräusche von einzelnen Positionen im Raum kommen, aber wie gehen wir damit um, wenn Geräusche aus einer unregelmäßig geformten Fläche stammen?
In Video-Spiel-Entwicklung sind wir es gewohnt, dass Geräusche aus einzelnen Positionen im Raum kommen, aber wie gehen wir damit um, wenn Geräusche aus einer unregelmäßigen Form stammen?
Eine Technik besteht darin, eine reguläre Audiosource an die Position innerhalb eines Volumens zu verschieben, die am nächsten an den Zuhörer liegt. Das funktioniert gut für konvexe Formen, und ich habe es in meinem Spiel Eye of the Temple selbst verwendet, für das Geräusch eines herab senkenden Decken-Traps, der rumpelt, und für den Lavaboden in einer großen Halle.
Eine Technik besteht darin, eine reguläre Audiosource an die Position innerhalb eines Volumens zu verschieben, das dem Zuhörer am nächsten liegt. Das funktioniert gut für konvexe Formen, und ich habe es selbst in meinem Spiel Eye of the Temple verwendet, für das Geräusch eines herab senkenden Decken-Traps, der rumpelt, und für den Lava-Boden in einer großen Kammer.
Aber bei nicht-konvexen Formen hat der Nächste-Punkt-Ansatz einige Probleme.
Stellen Sie sich einen stark verschlungenen Fluss vor, bei dem ein einzelner Punkt auf dem Land genauso nahe an zwei völlig unterschiedlichen Stellen am Fluss liegt. Hier wird der Nächste-Punkt-Ansatz abrupt von einer Position zur anderen wechseln, wenn der Spieler sich nur minimal in eine Richtung oder die andere bewegt.
Eine Technik, zwei Punkte in einer nicht-konvexen Schallquelle können dem Zuhörer gleichermaßen nahe liegen, während sie sich in ganz unterschiedliche Richtungen befinden.
Während die Lautstärke gleich bleibt (da die beiden Punkte gleich weit entfernt sind), ändert sich die Richtung, was mit jeder Richtungssound-Technologie sehr auffällig sein kann, von Stereosound über Surround-Sound bis hin zu HRTF-Sound.
Eine weitere Herangehensweise besteht darin, einfach viele Audioquellen innerhalb des Volumens (oder auf der Oberfläche) der Schall abgebenden Form zu platzieren. Das hat kein Richtungsproblem wie beim Nächste-Punkt-Ansatz, erfordert aber möglicherweise viel Rechenleistung, wenn eine Menge Audiosourcen gleichzeitig aktiv ist.
Eine andere Herangehensweise ist, eine weitere Möglichkeit zu erfinden, die ich „Point Cloud Sound“-Technik nenne. Da sie sich als sehr nützlich und effektiv für verschiedene Anwendungsfälle erwiesen hat, beschreibe ich hier, wie sie funktioniert.
Sie können eine Demonstration der Point-Cloud-Sound-Technik sehen, die für Wasser verwendet wird, in diesem Video, ab ca. 4:02 (bis 4:48). Ich empfehle Kopfhörer:
Dieser Artikel behandelt nicht alle Implementierungsdetails. Die Codebeispiele decken zentrale Aspekte der Technik ab, sind aber unvollständig und erfordern zusätzliche Implementierung, um zu kompilieren und zu funktionieren. Meine eigentliche Implementierung ist auf mein Spiel zugeschnitten und hängt von Drittanbieter-Bibliotheken (einschließlich einer kostenpflichtigen) für verschiedene nicht-kernrelevante Funktionen ab. Da ich nicht die komplette zweite funktionsfähige Implementierung implementieren wollte, lasse ich das als Übungsaufgabe für den Leser.
Anwendungsfälle
Hier sind die Anwendungsfälle, für die ich es bisher verwende:
– Das Geräusch von fließendem Wasser in Wasserläufen, in mehreren Intensitäten.
– Das Geräusch raschelnder Blätter von Tausenden von Bäumen und Sträuchern.
– Das Geräusch, dass der Spieler mit dem Laub der genannten Bäume kollidiert (durch sie hindurchgeht).
(Foliage-Collision-Sounds funktionieren etwas anders als die anderen und sind etwas, das ich am Ende des Beitrags behandeln werde. Eine kurze Video-Demonstration dazu finden Sie in meinem Mastodon-Beitrag hier.)
In all diesen Fällen brauche ich nicht wirklich mehrere Geräusche, die unabhängig voneinander spielen.
Zum Beispiel kann ich bei raschelnden Blättern einen einzelnen sich wiederholenden Rascheln-Laut verwenden, egal ob es innerhalb der Hörreichweite eines Baums 1 oder 30 Bäume sind, solange es sich so anhört, als komme es von der richtigen Position(en) im Raum.
Für das Wasser brauche ich unterschiedliche Geräusche für unterschiedliche Intensitäten, aber wiederum nicht nur für unterschiedliche Positionen im Raum.
Die Point-Cloud-Sound-Technik nutzt dies stark, indem sie mit so wenig wie einer einzigen Audioquelle auskommt, die sich über tausende von Punkten im Raum erstreckt. Das bedeutet, dass die Technik auch auf Anwendungsfälle anwendbar ist, in denen es keine individuell unterscheidbaren Instanzen gibt, sondern nur ein allgemeines Geräusch des Ganzen.
Berechnung des Lautstärke manuell
Mit der Point-Cloud-Sound-Technik definieren wir eine Menge von Punktproben im 3D-Raum, die wir grob so verwenden, als wären es einzelne Audioquellen.
(struct Code-Beispiel entfernt für Klarheit.)
Anstatt einzelne Audio-Quellobjekte zu erstellen, berechnen wir eine kombinierte Lautstärke, Richtung und Verbreitung pro Frame und setzen diese Eigenschaften auf ein einziges Audioquell-Objekt.
Unter diesen Eigenschaften ist Lautstärke am einfachsten zu handhaben, obwohl zuerst einige Dinge geklärt werden müssen. Ob es bessere Begriffe gibt, weiß ich nicht, aber hier verwende ich den Begriff source volume (Quellen-Lautstärke) für die inhärente Lautstärke einer Quellenspur, unabhängig vom Zuhörer, und den Begriff attenuated volume (abgeblendete Lautstärke), um zu bezeichnen, wie laut sie vom Zuhörer gehört wird, unter Berücksichtigung der Distanzabnahme.
Die abgeblendete Lautstärke, wie sie in Audiogeräte-Begriffen verstanden wird, nimmt gemäß dem umgekehrten Abstand ab. Es besteht ein weitverbreiteter Irrglaube, dass sie gemäß dem umgekehrten Quadratabstand abnimmt, aber das ist nicht der Fall. Während die Schallintensität mit dem umgekehrten Quadratabstand abnimmt, nimmt die Schallamplitude (Änderung des Drucks) nicht ab, wie hier beschrieben. Die Audio-Engines, die ich kenne, machen es korrekt und reduzieren gemäß dem umgekehrten Abstand, und das werden wir auch tun. (All dies berücksichtigt keine Audiodurchdringung, was den Umfang dieser Technik überschreitet.)
Ich komme darauf zurück, wie man eine Source-Volume für jeden Punktproben in unserer Point-Cloud-Sound definiert. Sobald wir diese Volumen haben, berechnen wir das kombinierte attenuated volume, indem wir die Summe jedes Sample-Quellvolumens durch seinen Abstand zum Zuhörer (dem Mikrofon) teilen. Einfach! Wir wenden dieses kombinierte attenuated volume dann auf unser einzelnes Audioquell-Objekt an.
(Code-Beispiel: Lautstärke summieren, Richtungen berücksichtigen, Gesamtgewicht berechnen, Volume des kombinierten Sounds setzen.)
Wichtig ist, dass wir die integrierte Distanz-Absenkung des Audioquell-Objekts deaktivieren, z. B. durch Festlegen einer benutzerdefinierten Lautstärke-Rolloff-Kurve, die immer eins ist. Es muss dennoch ein räumliches Audioquell-Objekt bleiben, da wir seine eingebaute Richtungs- und Streu-Behandlung nutzen werden.
Bedeutung von Streuung (Spread)
In Unity haben Audioquellen eine 3D-Sound-Einstellung namens Spread, und andere Audio-Engines haben ähnliche Konzepte. Spread ist subtiler als Lautstärke und Tonhöhe, aber zentral für die Point-Cloud-Sound-Technik.
Ein nicht-null Spread simuliert Schall, der aus einer Streuung von Richtungen kommt, und nicht aus einem einzelnen Punkt. In Unity kann Spread bis zu 360 Grad reichen, aber das führt dazu, dass der Schall aus der entgegengesetzten Richtung kommt, was wenig sinnvoll ist. Stattdessen betrachte ich in Unity eine Spread von 180 Grad als representation von 360 Grad, also dass der Schall den Zuhörer von allen Seiten umgibt. Unity behandelt Spread von 180 Grad so, als würden die linken und rechten Audio-Clips (wenn der Clip stereo ist) 180 Grad voneinander entfernt gespielt. Das sorgt dafür, dass ungefähr gleicher Schall in beiden Ausgabekanälen vorhanden ist, egal in welche Richtung der Zuhörer dem Schall gegenübersteht. Ist der Clip Mono, ist es dasselbe, außer den linken und rechten „Eingangs-Kanälen“ sind identisch.
Im restlichen Beitrag spreche ich von einem normalisierten Spread, der von 0 bis 1 geht, wobei 0 bedeutet, der Schall kommt aus einer einzelnen Richtung, und 1 bedeutet, der Schall kommt gleichmäßig aus allen Richtungen.
Der Spread-Begriff ermöglicht es uns, das Problem des Closest-Point-Ansatzes zu umgehen, bei dem sich die scheinbare Richtung eines Sounds abrupt ändert. Wir können dies mit der Point-Cloud-Sound-Technik vermeiden, indem wir sicherstellen, dass der Spread 1 ist (voller Spread), wenn der Zuhörer nahe an zwei Punkten in entgegengesetzte Richtungen ist. Allgemeiner gilt: Je dominanter eine Richtung ist, desto kleiner sollte der Spread sein; je mehr verschiedene Richtungen gleich beitragen, desto größer der Spread. Nun, wie berechnen wir das wirklich?
Berechnung von Richtung und Spread
Da wir eine theoretisch unendliche Anzahl von Audio-Punktproben haben, aber nur eine Audit-Sourcen-Objekt, müssen wir eine durchschnittliche Richtung berechnen, aus der der Schall kommt. Wir können nicht den Durchschnitt der Vektoren zu jedem Punktprobe (bezogen auf den Zuhörer) nehmen, da Proben, die weiter entfernt sind, einen größeren Beitrag hätten.
Stattdessen mitteln wir die normalisierten Richtungen. Das heißt, die Vektoren vom Zuhörer zu jeder Punktprobe wurden so normalisiert, dass sie eine Länge von eins haben, bevor wir sie mitteln.
Darüber hinaus müssen wir sicherstellen, dass Proben, die lauter gehört werden, mehr zur Durchschnittsrichtung beitragen. Also nehmen wir nicht einen einfachen Durchschnitt, sondern einen gewichteten Durchschnitt, wobei das attenuierte Volume jeder Punktprobe als Gewicht verwendet wird.
(Code-Beispiel: Volumen- und Richtungs-Berechnung, gewichteter Durchschnitt der Normalrichtungen.)
Mit der berechneten durchschnittlichen Richtung müssen wir lediglich die Audioquelle so positionieren, dass sie in diese Richtung liegt, relativ zum Zuhörer. Eine einfache Herangehensweise ist, sie immer eine Einheit vom Zuhörer entfernt zu platzieren. Da wir die integrierte Volumen-Absenkung deaktiviert haben, spielt der genaue Abstand überhaupt keine Rolle für die Lautstärke.
Nun, zur Berechnung der Spread: Eine überraschend einfache Lösung, die sich als sehr gut funktioniert, lautet Folgendes. Beachten Sie, dass wir eine gewichtete Durchschnitt der normalisierten Richtungen nehmen; das Ergebnis ist nicht notwendigerweise normalisiert. Je unterschiedlicher die gemittelten Richtungen zueinander sind, desto kürzer ist der resultierende Vektor. Wenn sie theoretisch exakt gleichmäßig in alle Richtungen verteilt wären, hätte der resultierende Vektor eine Länge von Null. Das korreliert perfekt mit dem, was wir für unseren Spread-Parameter brauchen. Wir können einfach den normalisierten Spread auf 1 minus die Länge des gemittelten Richtungs-Vektors setzen.
(Code-Beispiel: Volume, Richtung und Spread des kombinierten Sounds setzen.)
Hinweis: Einen Audio-Quell-Objekt einen Meter entfernt zu platzieren, ist für Stereosound in Ordnung; bei HRTF-Sound kann es jedoch bessere Ergebnisse geben (das habe ich nicht untersucht). Es kann auch das Debuggen erschweren, wo der Sound zu einem bestimmten Zeitpunkt herkommt. Eine Modifikation besteht darin, zusätzlich einen gewichteten Durchschnittsvektor zu berechnen, dessen Länge zu messen und das Audio-Quell-Objekt diese Distanz vom Zuhörer entfernen zu platzieren. Aus Gründen der Einfachheit spiegele ich dies im Beispielcode jedoch nicht wider.
Variable Größe der Punktproben
Vielleicht sollten nicht alle Punktproben im Point Cloud die gleiche Quellvolumen haben. Bisher habe ich übersprungen, was jede Punktprobe repräsentiert. Wir gehen ins Detail:
Personen, die mit Punktwolken in der Grafik vertraut sind, könnten annehmen, dass Oberflächen dicht mit Punkten bedeckt sind, aber meine Nutzung ist viel restriktiver. Für meine Wasserläufe platziere ich Punktproben nur entlang der Mitte, mit einem Abstand fast so groß wie der Wasserlauf selbst. Für Bäume verwende ich pro Baum eine Punktprobe, oder zwei für Bäume mit sehr nicht-sphärischen Kronen.
Wir könnten leicht für jede Punktprobe ein Quellvolumen angeben, aber es ist schwer zu wissen, was ich für jedes Quellvolumen setzen soll. Stattdessen habe ich meine Implementierung um Konzepte von Radius und Fläche herum entworfen.
Jede Punktprobe hat einen Radius, und sein Volumen wächst mit dem Quadrat des Radius. Warum nicht Kuben des Radius? Ein Ball ist schließlich ein Raumbereich. In der Praxis scheint es sinnvoll zu sein, zu vermuten, dass der Schall von einer Oberfläche statt eines Raums ausgeht. Im Fall eines Wasserlaufs kommt der Schall von einer flachen Fläche, nicht von einem kugelförmigen Volumen. Und bei einem Baum befinden sich Blätter auf vielen Baumarten in einer Hülle konzentriert statt den gesamten Raum zu füllen, da Blätter im Inneren des Raums wenig Sonnenlicht bekommen würden.
Für Bäume setze ich den Radius so, dass er ungefähr die Form der Baumkrone wiedergibt. Für Wasserläufe verfolge ich einen anderen Ansatz und berechne die Fläche des Wassersegments, das die Punktprobe repräsentiert (Breite mal Länge), berechne den Radius eines Scheibens mit entsprechendem Flächeninhalt (Wurzel aus Breite x Länge x Pi) und verwende diesen Radius für die Probe.
Alle Volumina werden mit einem Multiplikatorwert des Point-Cloud-Sounds multipliziert. Damit können Sie die Gesamtlautstärke des Sounds steuern.
In der Point-Cloud-Sound-Seite der Implementierung berechne ich sofort die Lautstärke des Sounds entsprechend dem Radius, wann immer eine neue Punktprobe registriert wird.
(Code-Beispiel: Struktur SoundPointSample mit Radius und Volume; AddSoundPointSample-Aufruf berechnet Fläche und Volume; Sample mit Radius und Volume speichern.)
Dann in der Frame-basierten Bewertung der Beiträge jeder Punktprobe multiplizieren wir dieses Quellvolumen mit der berechneten attenuierten Lautstärke.
(Code-Beispiel: Gewicht = Sample-Volume mal Abklingung)
Ich verwende den Radius auch noch für einen anderen Zweck. Die attenuierte Lautstärke, die wir bisher verwendet haben, geht gegen unendlich, je näher man dem Zentrum kommt. Aber man könnte nie so nahe an eine Schallquelle herankommen, die innerhalb eines Radius verteilt ist. Stattdessen können wir entscheiden, dass die Lautstärke nicht weiter ansteigen soll, sobald der Zuhörer den Radius betritt.
(Code-Beispiel: Distanz angepasst und Abklingung berechnet)
Es gibt noch elaboriertere Formeln, die verwendet werden könnten, aber da der Radius sowieso eine grobe Annäherung ist, gibt es keinen Grund, etwas besonders Konstruiertes damit zu tun.
Optimierungen
Bisher habe ich die Logik so simpel wie möglich gehalten, um die Grundideen zu verdeutlichen, aber für Produktionscode sollten wir etwas optimieren.
Es gibt keinen Grund, jede Punktprobe von unendlicher Entfernung aus hörbar zu machen. Wir können eine maximale Distanz festlegen und die meisten Berechnungen für Punktproben jenseits dieser Distanz einsparen.
(Code-Beispiel: maxDist = 40f)
Da es günstiger ist, die quadratische Distanz zu berechnen als die Distanz selbst, können wir damit beginnen und alle Punktproben verwerfen, deren quadratische Distanz größer als der quadrierte maxDist ist.
Wie sicherstellen, dass die Lautstärke am Max-Dist-Schwellwert nicht abrupt mute, gibt es verschiedene Wege; mein bevorzugter Weg ist es, die potenziell abgeblendete Lautstärke auf diesen Distanzwert von der allgemeinen abgeblendeten Lautstärke abzuziehen (den sogenannten Threshold).
(Code-Beispiel: maxDistSqr, threshold)
Eine weitere Optimierung ist, die Punktproben in mehrere Sammlungen aufzuteilen, die jeweils einen räumlichen Bereich abdecken. Wenn Sie die Begrenzungsbox für jede Sammlung beim Registrieren berechnen (und die maximale Distanz berücksichtigen), können Sie die Berechnungen pro Frame erheblich beschleunigen, indem Sie Sammlungen überspringen, in denen der Zuhörer sich nicht innerhalb der Bounding-Box befindet. Natürlich können Sie auch fortgeschrittenere Strukturen wie Quadtrees, Octrees oder andere räumliche Datenstrukturen verwenden, aber ich halte es lieber einfach.
Sammlungen von Punktproben lassen sich gut mit dem Laden oder prozeduralen Generieren von Weltabschnitten zur Laufzeit verbinden, da jeder Abschnitt dann verantwortlich sein kann, seine eigenen Punktproben-Sammlungen zu registrieren und abzumelden.
Ich werde hier keine Implementierung von Punktprobensammlungen detailliert behandeln, da es nichts Besonderes Neues oder Interessantes daran gibt.
Parametrische Klänge
Die bisher behandelte Technik ist vollständig ausreichend für einfache Anwendungsfälle, aber wir treten jetzt in optionales Terrain ein.
Wie zu Beginn erwähnt, ist einer meiner Anwendungsfälle ein Wasserlauf mit Wasser in unterschiedlichen Intensitäten. Manchmal wird daraus sogar ein Wasserfall, und das klingt ganz anders als ruhig fließendes Wasser.
Ich könnte einfach mehrere Point-Cloud-Sounds mit unterschiedlichen Audio-Clips verwenden und einen davon für jede Punktprobe entlang meiner Wasserläufe auswählen. Aber ich denke, Wasserintensität als kontinuierlichen Wert zu betrachten, anstatt einige diskrete Schritte zu wählen, ist sinnvoller. Aus diesem Grund unterstützt meine Point-Cloud-Sound-Implementierung eine parametrisierte Klänge, die wie folgt funktioniert:
– Jede Punktprobe wird mit einem Parameterwert erstellt.
– Im Point-Cloud-Sound-Objekt ist es möglich, mehrere Sound-Komponenten zu definieren.
– Jede Sound-Komponente hat einen anderen Looping-Audio-Clip sowie eine Kurve, die ihr Volumen für einen gegebenen Parameterwert festlegt. Ich verwende diese Kurven so, dass sie zu eins addieren, im Grunde von einer Komponente zur nächsten überblenden, während der Parameterwert erhöht wird.
(The screenshot des Inspektor-Panels eines Point-Cloud-Sounds mit vier Komponenten.)
Die Sound-Komponenten-Klasse könnte so aussehen:
public class SoundComponent {
public AudioClip clip;
public AnimationCurve curve;
public Color color; // Zu Debug-Zwecken.
public PointCloudAudioSource source;
}
public SoundComponent[] soundComponents;
Um zu vermeiden, dass Kurven für Tausende von Punkten pro Frame ausgewertet werden, können wir diese Daten bereits beim Registrieren vorab berechnen. Grundsätzlich hat jede Punktprobe eine separate Quellvolumen pro Sound-Komponente. In meiner Implementierung speichere ich diese als Parallel-Arrays statt eines kleinen Arrays innerhalb jeder Punktprobe.
(Code-Beispiel: Struktur SoundPointSample mit Punkt, Radius; keine Volumen hier. Liste von Samples; sampleVolumesPerComp als Array-Liste pro Komponente; AddSoundPointSample berechnet Fläche und Volumen; Vorberechnete Volumen pro Komponente pro Probe speichern.)
Die Point-Cloud-Sound erzeugt eine Audioquelle-Objekt pro Sound-Komponente. Einige der Berechnungen pro Frame werden zwischen den Komponenten geteilt, andere müssen pro Komponente separat erfolgen.
(Code-Beispiel: MaxDistSqr, Threshold, Schleife über Samples; Volumen pro Komponente speichern; Gewichtung und Richtung je Komponente aufsummieren; danach Lautstärke, Richtung, Spread pro Komponente setzen.)
Zusätzliche Funktionalität
Der obige Überblick ist die Kernaussage, wie die Point-Cloud-Sound-Technik funktioniert. Sie können sie in vielen Weisen an Ihre speziellen Anwendungsfälle und Präferenzen anpassen. Hier eine kurze Beschreibung einiger Anpassungen, die ich selbst vorgenommen habe.
Richtungsabhängige Parameter
Sie können den Klang eines Point-Cloud-Sounds richtungsreicher oder weniger richtungsabhängig gestalten, indem Sie einen Richtungs-Parameter (Standardwert: 1) hinzufügen und den Spread auf die Potenz dieses Richtungswertes erhöhen.
Spread, beeinflusst durch einzelne Proben
Der Spread-Wert, den wir berechnet haben, basiert darauf, wie gleichmäßig die Sample-Richtungen um den Zuhörer verteilt sind. Man könnte aber argumentieren, dass selbst wenn nur eine einzige Probe aktiv ist, der Spread größer werden sollte, je näher der Zuhörer an diesem einzelnen Sample liegt. Das lässt sich leicht erreichen, indem man die Berechnung der normalisierten Richtung so ändert:
Vector3 dirNorm = dir / (distance + sample.radius * 0.5f);
Dies verkürzt den dirNorm-Vektor (der nicht mehr wirklich normalisiert ist), je näher der Zuhörer daran ist, und der Spread wird entsprechend größer. Bei dem Zehnfachen des Radius beträgt der Spread 0,05, beim Doppeln des Radius 0,2, am Radius 0,33, bei der Hälfte des Radius 0,5 und im Zentrum 1,0.
Endgültige Volumen-Tweak-Parameter
Die implementierte Version hat einen Multiplikatorwert zur Steuerung der Gesamtlautstärke, aber Sie möchten möglicherweise zusätzlich einen Parameter hinzufügen, um das Endvolumen zu steuern, das nach der Berechnung des durchschnittlichen Volumens angewendet wird, das bereits zwischen Null und Eins begrenzt wurde. Das entspricht der Anpassung der Lautstärke innerhalb des Audio-Clips, ist aber schneller anpassbar. Wenn Sie Sound-Komponenten implementiert haben, können Sie dieses Endvolumen pro Komponente festlegen.
Volumen-Funktion für parametrisierte Klänge
Für mein Wasser-Anwendungsfall, bei dem der Parameterwert einer Probe die Intensität angibt, benötigte ich, dass Proben mit höheren Parameterwerten nicht nur unterschiedliche Audio-Clips verwenden, sondern generell lauter sind.
Ich habe dies mit einer Volumen-Funktion implementiert, die einer Exponentialkurve folgt, aber auch eine benutzerdefinierte Kurve (AnimationCurve in Unity) oder Ähnliches verwenden könnte. Für jede Probe wird die Volumen-Funktion anhand des Parameterwertes der Probe ausgewertet. Das Ergebnis wird auf jede der vorab berechneten pro-Komponenten-Volumenwerte der Probe multipliziert.
Debug-Visualisierungen
Um Ihre Point-Cloud-Sounds effizient debuggen zu können, könnten Sie Debug-Visualisierungen implementieren, die zeigen, wo sich die Punktproben befinden, welche Radien sie haben, und – bei parametrierten Sounds – welches berechnete Volumen eine Probe für jede Sound-Komponente hat.
Sie können auch Visualisierungen erstellen, wo sich jede End-Audioquelle befindet und wie ihr Volumen und Spread aussehen (siehe Video am Anfang dieses Artikels).
Kollision-Sounds
Wie zu Beginn erwähnt, verwende ich auch meine Point-Cloud-Sound-Technik für Kollisionsgeräusche, wenn der Spieler durch Gebüsch wie Büsche und Baumkronen gleitet.
Dies funktioniert ganz anders als bisher behandelt und ist ein etwas weniger offensichtlicher Anwendungsfall, da der Spieler üblicherweise nur eine oder zwei Proben gleichzeitig trifft. Aber wenn Sie ohnehin schon ein Point-Cloud-Sound-Setup für andere Anwendungsfälle haben, ist es einfach, es auch für diesen zusätzlichen Zweck zu verwenden. In meinem Fall hatte ich bereits einen Point-Cloud-Sound für Rascheln von Blättern, den ich auch für Kollisionsgeräusche nutzen konnte.
Kollisionsgeräusche könnten auf viele Arten implementiert werden, aber in meinem Fall funktioniert es so:
– Sound-Komponenten haben eine Checkbox, um zu steuern, ob es sich um ein Kollisionsgeräusch handelt.
– Sound-Komponenten haben einen Parameter speedThreshold (nur für Kollisionen), der angibt, ab welcher Geschwindigkeit der Spieler die Kollisionsgeräusche auslösen muss. In meiner Implementierung erreicht es die volle Wirkung bei dem Zweifachen dieser Geschwindigkeit, könnte aber alternativ ein zusätzlicher Parameter sein.
– Für Kollisionsgeräusche verwendet man statt der normalen attenuierten Lautstärke in der Frame-Bewertung die Lautstärke von Null am Radius bis Eins am Zentrum, multipliziert mit dem geschwindigkeitsbasierten Multiplikator. Dieser Wert wird auf Null bis Eins begrenzt.
– Die Distanz des Spielers zum Geräusch ist nicht mehr einfach die Distanz zum Zuhörer-Punkt. Stattdessen wird der kürzeste Abstand zu einem Liniensegment berechnet, das den Körper des Spielers repräsentiert. So werden Kollisionsgeräusche auch von den Füßen und dem Körper des Spielers ausgelöst und nicht nur vom Kopf.
Wie Sie erkennen können, gibt es in dieser Implementierung eine Menge willkürlich wirkender Entscheidungen, und Ihre Kollisions-Use-Cases könnten andere Entscheidungen erfordern.
Ich hoffe, Sie fanden das nützlich oder interessant
Lassen Sie mich wissen, wenn Sie etwas mit Point-Cloud-Sounds tun, insbesondere wenn es um andere Anwendungsfälle geht als meine oder wenn Sie Dinge auf eine andere Weise machen!
June 14, 2026 at 01:43PM