Impacter et Unreal Engine | Comment contrôler le plugiciel Impacter en utilisant la physique du moteur de jeu

Conception sonore / Audio spatialisée / Outils et conseils pour Wwise

Introduction

Impacter est un nouveau prototype de plugiciel de modélisation de sons d'impacts pour Wwise, consultez ce lien pour un aperçu. Dans cet article, nous allons voir comment utiliser Impacter afin d'intégrer et implémenter des sons dans un environnement de jeu conçu avec Unreal Engine. Nous commencerons par un bref aperçu des principales caractéristiques d'Impacter avant d'entrer plus en détail sur la façon dont il peut être utilisé dans l'environnement d'Unreal Engine. Nous allons principalement nous concentrer sur la manière dont le système physique a été utilisé pour contrôler les paramètres de masse (« Mass ») et de vélocité (« Velocity ») d'Impacter. D'autres moteurs de jeu sont disponibles sur le marché, cependant, les points à retenir ici peuvent s'appliquer quel que soit votre choix d'outils de travail.

Impacter

Impacter est un plugiciel de source audio qui fonctionne en effectuant de la synthèse croisée sur des propriétés audio de différents sons, et en appliquant à ces sons des transformations basées sur la physique. Pour explorer plus en détail le plugiciel Impacter, vous pouvez lire cet article écrit par Ryan Done ou consulter la documentation. Mais voici un rapide aperçu des principales fonctionnalités :

 

Synthèse Croisée

  • Il est possible de charger plusieurs sons dans Impacter. Ces sons sont ensuite analysés en interne et divisés en deux composants : une partie « impact » (« Impact ») et une partie « corps » (« Body »). L'impact fait référence à la collision initiale lorsqu'un objet est frappé. Le corps fait référence à la résonance de l'objet après la frappe initiale.
  • Les composants d'impact et de corps peuvent être mélangés et combinés ensemble. Impacter choisira aléatoirement un composant impact et un composant corps différent à chaque lecture.

 

Paramètres basés sur la physique

  • Le paramètre de masse (« Mass ») correspond à la taille de l'objet frappé.
  • Le paramètre de vélocité (« Velocity ») correspond à la force avec laquelle l'objet est frappé.
  • Le paramètre de position (« Position ») fait référence à l'emplacement de l'impact sur l'objet frappé. Ce paramètre est inspiré du phénomène des modes acoustiques. Changer le paramètre de position permet de faire subtilement varier la résonance du son.
  • L'agressivité (« Roughness ») fait référence à l'agressivité auditive et se traduit par l'ajout d'une modulation de fréquence (FM) sur la résonance du son.

 

Démo Unreal d'Impacter

La démo Unreal d'Impacter (« The Impacter Unreal Demo ») a été développée pour tester et illustrer différentes utilisations d'Impacter dans un environnement de jeu (rudimentaire). Nous verrons dans les sections suivantes quelques cas concrets d'utilisation d'Impacter, et comment le contrôler efficacement en utilisant des paramètres physiques du moteur de jeu.

Course à pied (Bruits de pas)

La configuration pour les bruits de pas dans la démo est assez simple. Dans Wwise, un Switch Container contenant des bruits de pas sur différentes surfaces est contrôlé par un State Group (nommé « FootstepMaterial »). Dans le jeu, les différentes surfaces du sol déterminent dans Wwise le State actif de ce State Group FootstepMaterial.

FootstepSwitchWwise

Puisque chaque SFX de pas contient une instance d'Impacter, nous pouvons pousser plus loin notre système - en d'autres termes, tirer plus de variations de nos échantillons - par l'usage de la synthèse croisée. Néanmoins, jusqu'à présent, nous sommes dans un scénario assez commun de bruits de pas.

FootstepsCrossSynthFootstepsVelMass

Les choses deviennent plus intéressantes lorsque les paramètres de masse et vélocité entrent en jeu. Ces paramètres peuvent être utilisés pour adapter nos bruits de pas à la taille des différents personnages qui les émettent. Un RTPC additionnel (nommé « CharacterSize ») est utilisé pour contrôler à la fois la masse et la vélocité de chacun de ces sons de pas. Dans Unreal, le RTPC CharacterSize est défini par la taille de l'objet personnage. La taille de l'objet personnage affecte également de manière inverse la vitesse du personnage (et son animation lorsqu'il court). Ce système permet de simuler l'effet que l'on obtient en passant d'un personnage énorme et lourd à un personnage plus petit et agile. En connectant le RTPC CharacterSize aux paramètres de masse et de vélocité d'Impacter, il devient facile de recréer cette sensation dans les bruits de pas.

Quand le monde s'entrechoque

À chaque objet et à chaque surface de l'environnement correspond un Event Wwise qui déclenche une ou plusieurs instances d'Impacter. Les paramètres de vélocité et de masse de chaque instance d'Impacter sont reliés à des RTPC (« ImpactVelocity » et « ImpactMass ») contrôlés par le jeu lorsque des collisions se produisent.

Lors de la création de la démo Unreal et de l'intégration d'Impacter, l'une des tâches les plus importantes a été d'interroger le système physique d'Unreal lors des collisions afin de fournir des valeurs exploitables pour les paramètres de masse et de vélocité, de sorte que les sons d'Impacter suivent un comportement naturel. Cela est implémenté dans l'élément ImpacterComponent, qui est un Blueprint SceneComponent personnalisé. Chaque Blueprint de classe d'Actor dans le jeu possède un ImpacterComponent (certains en ont plusieurs). Lorsqu'une collision se produit entre deux objets, leurs ImpacterComponent respectifs appellent l'élément ImpactComponentCollision. C'est là que sont calculées les valeurs des RTPC ImpactVelocity et ImpactMass qui sont envoyées à Wwise, avant que les évènements d'Impacter soient déclenchés sur chaque objet.

ImpactComponentCollision

À ce stade, il est utile de préciser notre terminologie. Un objet statique (« static object ») est un objet qui ne bouge jamais, par opposition à un objet dynamique (« dynamic object ») qui, lui, peut se déplacer dans l'environnement. Lorsque deux objets entrent en collision, deux événements de collision sont déclenchés dans Unreal - un pour l'élément ImpacterComponent de chaque objet. 

CheckComponentCollision

Chaque objet gère les collisions de cette manière. L'événement On Component Hit appelle l'élément CheckImpactComponentCollision sur l'élément ImpactComponent. L'élément CheckImpactComponentCollision vérifie alors si l'élément connecté au paramètre « Other Actor » possède un ImpactComponent. S'il y a un élément ImpactComponent, l'élément ImpactComponentCollision est appelé.

CheckImpactComponentCollision

Pour clarifier ce point, prenons l'exemple spécifique d'un projectile entrant en collision avec un mur. Du point de vue du mur, l'objet qui entre en collision (connecté à son paramètre « Other Actor ») est le projectile. Du point de vue du projectile, l'objet d'impact (son « Other Actor ») est le mur. Il peut sembler contre-intuitif de penser que le mur a un impact sur le projectile et que le projectile a un impact sur le mur, mais il est utile de garder ces deux contextes à l'esprit pour la suite de cette section. L'idée principale est que chaque objet déclenche son Event Wwise correspondant et qu'il utilise ses propres caractéristiques physiques ainsi que celles de l'autre objet pour calculer les valeurs des RTPC ImpactVelocity et ImpactMass.

Puisque l'élément ImpacterComponent est utilisé pour tous les objets du jeu, l'objectif ici est d'implémenter des systèmes physiquement plausibles et globalement exploitables, depuis la physique des collisions dans le moteur de jeu jusqu'aux valeurs de RTPC. De cette façon, les caractéristiques physiques des objets seront suffisantes pour contrôler les sons, sans que le-la concepteur-ice sonore n'ait à effectuer d'autres réglages manuels additionnels. Les concepteurs-ices de niveaux peuvent concevoir, positionner et modifier les objets avec l'assurance que les sons répondront de manière appropriée, pour autant que le-la concepteur-ice sonore ait judicieusement ajusté les courbes de vélocité et de masse.

En gardant cela à l'esprit, voyons comment l'élément ImpactComponent calcule les valeurs de RTPC lors des événements de collision, à l'aide de la fonction ImpactComponentCollision.

Masse et vélocité

Les valeurs des RTPC ImpactMass et ImpactVelocity sont calculées respectivement dans les éléments GetImpactMass et GetImpactForce. Ils sont tous deux appelées par l'élément ImpactComponentCollision.

GetMassAndVelocity

Masse (GetImpactMass)

Le paramètre de masse est pris directement depuis le système physique d'Unreal pour les objets dynamiques. (Remarque : il est important de configurer les paramètres « Physical Materials » de nos objets avec des valeurs de densité appropriées afin qu'ils aient une masse adéquate.) Les objets statiques, eux, ne simulent pas de comportement physique. Ils n'ont donc pas de valeur correspondant à la masse. À la place, on leur attribue une valeur de masse explicite. Pour les murs et les sols, leur valeur de masse est pondérée par la masse de l'objet impactant, lors des collisions, lorsque la valeur du RTPC est déterminée.

GetImpactMass

Vélocité (GetImpactForce)

Il est possible de faire directement correspondre la vélocité d'un objet au paramètre de vélocité dans Impacter. Cependant, ce procédé provoquerait des impacts anormalement forts pour de petits objets légers. Par exemple, une petite balle molle percutant une surface métallique à grande vitesse pourrait faire en sorte que cette surface déclenche un fort son d'impact. Afin d'éviter cela, il est préférable de faire correspondre la force de l'impact au paramètre de vélocité d'Impacter. De fait, nous devrions utiliser la quantité de mouvement (ou « momentum », soit le résultat du produit : vélocité x masse), plutôt que la vélocité seule. De cette manière, les objets plus légers produiront des valeurs plus faibles sur le RTPC ImpactVelocity, et donc des sons d'impact moins agressifs. Nous devons également tenir compte du momentum des deux objets lors du calcul de la valeur du RTPC ImpactVelocity de chacun. Enfin, nous pouvons également inclure le paramètre de densité directement dans notre mapping de paramètres, de sorte que des objets à la textures plus molle produisent des impacts moins agressifs.

Comme c'est le cas pour la masse, le calcul de la vélocité diffère légèrement selon que l'objet percutant est dynamique ou statique. Lorsque l'objet d'impact est statique, la fonction ImpactedByStaticObject est utilisée pour calculer la force. Lorsque l'objet d'impact est dynamique, la fonction ImpactedByDynamicObject est utilisée.

ImpactedByStaticObject

StaticForce

Ici, nous prenons le momentum de l'objet impacté et nous le multiplions par la densité de l'objet impactant pour obtenir la valeur du RTPC ImpactVelocity. Gardons en mémoire que dans cette situation, l'objet d'impact sera un mur ou un sol.

ImpactedByDynamicObject

DynamicForce

Ici, nous utilisons la somme des momentums de chaque objet, pondérée par la plus petite des densités des deux objets. Notons que dans cette situation, l'objet impacté peut être statique, auquel cas son momentum sera égal à 0. La somme des momentums sera donc égale à celle de l'objet impactant.

À ce stade, il est utile de présenter les différentes situations possibles dans un tableau de collisions. L'image 1 montre comment les RTPC de vitesse et de masse sont calculés pour différents scénarios de collision. Notons que deux objets statiques ne peuvent jamais entrer en collision.

RTPCCalcMatrix
Image 1 : tableau de calcul des valeurs de RTPC

Essais & affinage

Une fois ce mapping configuré, il est désormais possible de lancer un projectile sur une surface afin de tester le son qu'il produit.

Quel son horrible ! C'est parce que le système physique d'Unreal envoie continuellement des évènements de collision lorsque la balle roule sur le sol. Puisque le roulement de la balle ne contient pas d'évènements d'impact distincts, nous pourrions tout simplement désactiver les impacts pour les surfaces du sol et nous arrêter là (ou peut-être utiliser un plugiciel différent tel que SoundSeed Grain pour implémenter les sons de roulement). Cependant, il s'avère que nous pouvons utiliser les collisions continues à notre avantage et simuler le son d'un objet qui roule comme un grand nombre de petits impacts - « frapper le sol en roulant », pour ainsi dire. Pour commencer, nous pouvons limiter la fréquence selon laquelle les Event Wwise sont déclenchés par l'ImpacterComponent.

C'est un peu mieux, mais la cadence reste un peu trop régulière, ce qui peut sembler peu naturel. Pour atténuer ce problème, nous pouvons ajouter un paramètre aléatoire à la fréquence avec laquelle les Event Wwise sont appelés. Pour ce faire, nous allons donc ajouter un décalage aléatoire sur le temps entre chaque Event, à chaque réinitialisation du compteur.

Le son commence à s'améliorer, mais les impacts répétés déclenchés lorsque la balle roule restent trop forts pour ce type de mouvement. On dirait plutôt que quelqu'un frappe continuellement le sol. Afin de contourner ce problème, nous pouvons prendre en compte la direction du mouvement. Plus précisément, nous pouvons utiliser le produit scalaire entre le vecteur vitesse de l'objet et le vecteur allant du centre de l'objet au point d'impact sur sa surface. Ce concept est un peu jargonneux, nous allons donc l'illustrer avec ce diagramme.

DP

d = v.i où v = vecteur vitesse et i = point d'impact sur la surface - centre de l'objet.

Nous utilisons d pour pondérer la valeur du RTPC ImpactVelocity.

StaticForce_DP

Si l'objet se déplace directement vers le point d'impact, alors d = 1. Lorsque la balle roule sur le sol, la valeur d est faible, et donc la valeur du RTPC est réduite.

Cela améliore encore notre intégration sonore. Nous pouvons clairement entendre la différence entre le son de balle qui rebondit initialement sur le sol, et celui de la balle qui roule ensuite sur le sol.

Notons que l'ajout du facteur peut améliorer notre calcul du RTPC dans d'autres contextes qu'un roulement sur le sol. Par exemple, il permet de tenir compte du cas où un objet se déplaçant rapidement ne fait que glisser sur le côté d'un autre objet plutôt que de le frapper de plein fouet. Pour les impacts dynamiques (lorsque les deux objets sont en mouvement), chaque objet a une valeur d. Nous prenons alors le maximum de ces valeurs que nous utilisons pour pondérer les valeurs des RTPC de vélocité de chacune. Pour les objets statiques (sols et murs), d = 1 (maximum), donc la valeur d de l'objet dynamique sera toujours utilisée lorsque l'objet impactant est statique et que l'objet impacté est dynamique.

DynamicForce_DP

Sur le chemin de la destruction

Impacter a été conçu pour des types de sons très spécifiques. L'algorithme part du principe que l'enveloppe d'amplitude décroît de manière exponentielle et qu'il existe une région comprenant une transitoire principale. En d'autres termes, des sons qui devraient « ressembler » à quelque chose comme ça :

ImpactWaveformsLateral

Cela dit, il est possible d'explorer ce qui se passe avec d'autres types de sons. Dans la démo Unreal d'Impacter, nous avons intégrés des sons de craquements et de destruction, qui ne respectent plus ce principe de transitoire unique supposé par l'algorithme, en ce qu'ils contiennent plus d'une transitoire.

MultipleImpactWaveforms

Le problème, ici, est que les enveloppes d'amplitude varient sensiblement d'un son à l'autre, ce qui ouvre la possibilité d'une « résonance » peu naturelle dans la partie corps du son (la partie résonante). Les amplitudes de l'oscillateur et de la banque de filtres suivent l'enveloppe d'amplitude du son original. Si elles sont combinées avec la composante d'impact d'un son dont l'enveloppe d'amplitude est clairement distincte, le résultat aura une sonorité assez artificielle.

Les cases d'inclusion / exclusion dans l'interface d'Impacter sont précisément là pour ce genre de situations. Elles donnent la possibilité d'exclure toutes les combinaisons impact-modèle problématiques qui se présentent lors de l'exploration de la synthèse croisée pour un ensemble de sons.

Dans la démo Unreal, les Destructible Mesh ont été utilisés pour créer des cubes qui peuvent se briser lorsqu'ils sont percutés avec suffisamment de force. Des instances d'Impacter ont été configurées pour les sons de destruction et, tout comme pour les sons d'impacts, ces sons de destruction ont une masse et une vélocité liées aux RTPC.

Une autre approche possible lors de l'implémentation de ces types de sons de destruction est de faire en sorte que chaque morceau de l'objet détruit déclenche individuellement des sons d'Impacter dans Wwise lorsque celui-ci se brise, et que ces morceaux entrent en collision avec l'environnement (et avec d'autres morceaux de l'objet). De cette manière, les multiples sons d'impact individuels pourront se combiner ensemble pour former un son global de « bris / destruction » qui émergera comme le résultat direct des interactions physiques se produisant dans le jeu. Les boîtes destructibles dans la démo Unreal en sont un bon exemple. Au départ, un son de « destruction » se déclenchait lorsque les boîtes se brisaient.

Le problème était que ce son avait un profil dynamique très marqué avec plusieurs transitoires. Comme vous pouvez l'entendre dans la vidéo, la grande boîte se brise et on peut alors entendre plusieurs transitoires alors qu'il ne semble pas y avoir d'interaction physique correspondante. J'ai alors décidé d'attacher des ImpacterComponent à chacune des parties individuelles de la boîte. Initialement, ces ImpacterComponent sont inactifs. Mais lorsque la boîte se brise, les ImpacterComponent présents sur les pièces individuelles deviennent actifs et commencent à réagir aux collisions, déclenchant des Event Wwise. Par conséquent, lorsque la boîte se brise, les impacts individuels de ses différents morceaux créent naturellement un son de bris et de fracas.

Mapping du paramètre Position

La plupart du temps, le paramètre de position est aléatoire afin d'ajouter une variation supplémentaire aux sons tout au long de la démo Unreal. Ce paramètre fait varier la résonance en réduisant le gain de certains filtres et oscillateurs. Le composant corps du son est modifié par des courbes de gain (« Gain Ramps ») non linéaires et dépendant de la fréquence. Le paramètre de position permet de contrôler la position de ces courbes de gain internes. En d'autres termes, la variation de la position produit des modifications subtiles de la résonance du son. Lorsque la position est réglée sur 0, le son a une résonance « intégrale ». C'est-à-dire qu'aucune réduction de gain n'est appliquée. Les courbes de gain internes réduisent et augmentent progressivement les gains des pics de fréquences à mesure que la position passe de 0 à 1.

position

Dans la démo d'Impacter, le RTPC ImpactPosition varie selon la distance entre l'emplacement de l'impact sur les grands murs de verre, et le centre de ces murs. Ce mapping a été fait de manière inversée, de sorte que les coins et les bords du mur seront plus « résonnants », et que les différents pics fréquentiels seront amortis à mesure que les impacts se rapprochent du centre.

À retenir

Lorsque l'on accorde suffisamment d'attention aux connections entre la physique du jeu et les RTPC, Impacter peut s'avérer être un outil très utile pour intégrer des sons d'impact. Voici quelques principes généraux à garder en tête lors de l'intégration de sons avec Impacter :

Adaptez votre échelle

  • Testez vos sons en poussant les paramètres de masse et de vélocité aux extrêmes afin de trouver l'expressivité optimale lorsqu'ils seront connectés à la physique du jeu.

Utilisez la Force

  • Le paramètre de vélocité d'Impacter doit être déterminé par la force de la collision. Celle-ci dépendra de divers facteurs, dont la densité et le momentum des deux objets.

Changez constamment de position

  • Si vous voulez maximiser vos variations, il est généralement une bonne idée de rendre aléatoire le paramètre de position. Cela vous permettra d'obtenir de subtiles variations dans la résonance du son, ce qui sera particulièrement utile dans des situations comme les impacts de balles ou les bruits de pas. 

Enfreignez les règles, mais restez bref

  • Bien qu'Impacter soit conçu pour les sons d'impact, il est toujours intéressant de voir les résultats que l'on peut obtenir à partir de différents types de sons sources. Faites cependant attention lorsque vous ajoutez des échantillons particulièrement longs. L'étape d'analyse est assez rapide pour des impacts simples, mais elle peut prendre un certain temps pour l'analyse de sons plus longs.

Restez à l'écoute pour un troisième article sur les possibilités de variations qu'offre la synthèse croisée !

Sean Soraghan

Développeur Logiciel

Audiokinetic

Sean Soraghan

Développeur Logiciel

Audiokinetic

Sean Soraghan est développeur logiciel chez Audiokinetic, travaillant sur le logiciel Wwise ainsi que sur les modules d'intégration pour Unreal Engine et Unity. Titulaire d'un doctorat en ingénierie au cours duquel il a effectué des recherches sur la représentation et la visualisation du timbre musical, il a par ailleurs collaboré au développement d'installations et expositions audiovisuelles à grande échelle. Il aime également développer des jeux et outils logiciels sur son temps libre.

Commentaires

Laisser une réponse

Votre adresse électronique ne sera pas publiée.

Plus d'articles

Présentation du Wwise Authoring Query Language

« Wwise est un gros tableur ». C'est une phrase que nous entendons souvent en tant que membres de...

28.4.2022 - Par Bernard Rodrigue

Amélioration de l'intégration Wwise dans Unreal

L'introduction du workflow de gestion d’assets de type Event-Based Packaging (EBP) incluse dans...

29.6.2022 - Par Guillaume Renaud

Réintroduction de Wwise Audio Lab (WAL)

Wwise Audio Lab (WAL) est un environnement 3D open-source semblable à un jeu vidéo, développé avec...

15.7.2022 - Par Damian Kastbauer

Wwise 2023.1 Nouveautés

Wwise 2023.1 est en ligne et peut être installé à partir de l'Audiokinetic Launcher. Voici un résumé...

7.7.2023 - Par Audiokinetic

WAQL 2.0

Cela fait déjà quelques années que la première version du Wwise Authoring Query Language (WAQL) a...

11.8.2023 - Par Bernard Rodrigue

Travailler en équipe avec WAAPI et Python, et exemples pratiques

Dans cet article, j'aimerais décrire une approche de travail avec WAAPI un peu particulière,...

7.11.2023 - Par Eugene Cherny

Plus d'articles

Présentation du Wwise Authoring Query Language

« Wwise est un gros tableur ». C'est une phrase que nous entendons souvent en tant que membres de...

Amélioration de l'intégration Wwise dans Unreal

L'introduction du workflow de gestion d’assets de type Event-Based Packaging (EBP) incluse dans...

Réintroduction de Wwise Audio Lab (WAL)

Wwise Audio Lab (WAL) est un environnement 3D open-source semblable à un jeu vidéo, développé avec...