Je regardais de la Rocket League et j'ai remarqué qu'il y avait des décalcomanies et des roues animées.
.
Je voudrais implémenter quelque chose de similaire aux effets de l'image ci-dessus.
Comment pourrais-je écrire un Unity Shader pour faire l'effet roue?
Je ne connais pas grand chose aux Shaders, mais puis-je éditer le Unity Shader standard pour faire l'effet d'animation?
_Time
variable intégrée que vous pouvez ajouter à vos coordonnées de texture dans le (vertex) shader pour obtenir un effet de défilement très bon marché. L'effet hexagonal serait également assez simple. Si vous modifiez votre question pour mettre en évidence un seul effet et demandez "comment pourrais-je implémenter cela dans un shader Unity", nous pouvons probablement vous aider. Assurez-vous de spécifier si le shader doit répondre à l'éclairage / à l'ombre, car cela a un impact sur la façon dont il serait écrit.Réponses:
Je vais construire cela en quelques couches afin que vous puissiez voir comment cela se combine.
Commencez par créer un nouveau shader dans Unity en choisissant
Create --> Shader --> Unlit
dans le menu Actifs ou dans le menu contextuel du clic droit de la fenêtre Projet.Dans le bloc supérieur, nous ajouterons un
_ScrollSpeeds
paramètre pour contrôler la vitesse à laquelle la texture se déplace dans chaque direction:Cela expose une nouvelle propriété flottante à 4 composants dans l'inspecteur des matériaux, avec le nom convivial "Vitesse de défilement" (similaire à l'ajout d'une
public
ou d' uneSerialized
variable à unMonoBehaviour
script)Ensuite, nous utiliserons cette variable dans le shader Vertex pour décaler les coordonnées de texture (
o.uv
), en ajoutant seulement deux lignes au shader par défaut:Giflez cela sur un quad (avec une belle texture de girafe gratuite par Kenney ) et vous obtenez:
Pour faire défiler la texture vers l'extérieur dans un anneau, nous pourrions simplement utiliser un maillage subdivisé comme une toile d'araignée, avec la coordonnée uv v augmentant du centre vers l'extérieur. Mais cela donnera à lui seul des artefacts en forme de lame de scie. Au lieu de cela, je vais montrer comment nous pouvons calculer nos UV par fragment.
C'est un peu plus cher, à la fois en raison des opérations de trig et de longueur (qui sont plus chères que les mathématiques de base) et parce qu'il n'est pas aussi efficace de prévoir et de mettre en cache les données de texture dans le matériel lors du calcul des texcoords par fragment, par rapport à simplement les interpoler entre les sommets. Mais pour un petit effet spécial comme celui-ci, ce n'est pas excessif.
Cela nous donne quelque chose comme ça (ici, j'ai augmenté les paramètres de mosaïque dans le matériau afin qu'il soit plus clair ce qui se passe - envelopper une seule répétition de la tuile autour du cercle semble déformé et bizarre)
Enfin, pour teinter la texture par un dégradé de défilement, il suffit d'ajouter le dégradé comme deuxième texture et de les multiplier ensemble.
Nous ajoutons d'abord le nouveau paramètre de texture en haut:
Et déclarez-le dans notre bloc CGPROGRAM pour que le shader CG puisse le voir:
Mettez ensuite à jour notre fragment shader pour utiliser les deux textures:
Et maintenant, notre girafe devient vraiment trippante:
Avec une sélection légèrement plus artistique de textures et de taux de défilement, cela peut créer un effet assez similaire à celui montré dans la question.
Vous remarquerez peut-être deux petits artefacts avec la version que j'ai montrée ci-dessus:
Les visages près du centre du cercle deviennent étirés / maigres / pointus, puis lorsqu'ils se déplacent vers l'extérieur, ils sont écrasés / larges.
Cette distorsion se produit parce que nous avons un nombre fixe de faces autour du périmètre, mais la circonférence qu'elles couvrent s'élargit à mesure que le rayon augmente, tandis que leur hauteur reste la même.
Nous pouvons résoudre ce problème en remappant la composante verticale de l'échantillon de texture pour suivre une courbe logarithmique, de sorte que les répétitions de la texture sont plus éloignées lorsque le rayon augmente et plus proches les unes des autres vers le centre. (En fait, cela nous donne une régression infinie de girafes de plus en plus petites ...)
Il y a une rangée d'un ou deux pixels flous le long du milieu à gauche du quad.
Cela se produit car le GPU examine deux coordonnées d'échantillon de texture adjacentes pour déterminer le filtrage à utiliser. Lorsque les échantillons sont proches les uns des autres, il indique que la texture est affichée grande / proche et montre le niveau de mip le plus détaillé. Lorsque les échantillons sont éloignés, il suppose que nous devons montrer la texture à un zoom minuscule ou loin, et il échantillonne à partir d'un mipmap plus petit / plus flou pour nous assurer que nous n'obtenons pas d'artefacts de crénelage scintillants.
Le problème est ici, nous sommes au point de bouclage en coordonnées polaires, de -180 à 180 degrés. Nous échantillonnons donc à partir de points très similaires dans notre espace de texture répétitif, même si leurs coordonnées numériques leur donnent l'impression d'être éloignées. Nous pouvons donc fournir nos propres vecteurs de gradient d'échantillonnage pour corriger cela.
Voici une version avec ces corrections:
la source
tex2Dgrad
corrige l'artefact de filtrage où l'angle s'enroule de -pi à + pi (c'est la fine ligne de pixels flous sur le côté gauche). Voici le résultat des