Ga verder dan Retro Pixel Art met Flat Shaded 3D in Unity

In deze zelfstudie laat ik je zien hoe je platte 3D-afbeeldingen maakt voor je Unity-game en uitleg waarom je dit in de eerste plaats wilt doen.

Tegenwoordig is er een overvloed aan 3D-gereedschappen en -motoren waarmee iedereen 3D-spellen kan maken. De uitdagingen van 3D-kunst zijn echter angstaanjagend en vereisen vaak een enorme hoeveelheid tijd, moeite en expertise die de solo-gamedev of hobbyist niet heeft. Low-polygon-modellen, in combinatie met vlakke arcering, brengen de stijl van de vroege jaren '90 terug, met behulp van technieken die iedereen kan leren. En het is niet alleen een nostalgische erfenis; Vlakschaduw kan eenvoudig worden gecombineerd met moderne technieken zoals ambient occlusion-kaarten om uw spel een opvallende, avantgarde uitstraling te geven.

Klik hier voor het voorbeeldproject Unity

Deze tutorial gaat ervan uit dat je al weet hoe je 3D-modellering moet doen, of dat je in staat bent om gratis 3D-modellen op internet te vinden. Ik zal voorbeeldmodellen uit het niets trekken; er zijn honderden tutorials op het internet om te beginnen met 3D-modellering. Als je net begint, kan ik Wings 3D en SketchUp ten zeerste aanbevelen. Beide hebben uiterst toegankelijke interfaces in vergelijking met professionele modellerings-apps en zullen exporteren naar formaten die Blender en Unity kunnen gebruiken.


Waarom Flat Shading gebruiken?

Dus je hebt besloten om je handen vuil te maken met Unity en een volledig 3D-spel te maken. Misschien heb je geen eerdere vaardigheden voor het spelen van spellen, of misschien heb je wat kunst gemaakt voor 2D-spellen; in beide gevallen zul je snel leren dat 3D-spellen een hele reeks vaardigheden vereisen om te creëren. U hoeft niet alleen te leren hoe u 3D-modellen maakt, u moet die modellen uitpakken om een ​​textuur op het oppervlak van uw model te tekenen. Je moet natuurlijk ook nauwgezet de textuur creëren.

Wat als je het model zou kunnen maken, maar heb je het klaar en klaar voor je spel na een paar extra stappen om het te kleuren en te verduisteren? Je zou kunnen eindigen met zoiets als dit:

Of dit:

Natuurlijk, de look is spartaans en lo-fi - maar dat is het punt! Of je nu op zoek bent naar nostalgie uit de vroege jaren 90, een moderne abstracte look, of gewoon veel tijd wilt besparen met het maken van een jam-game, flat shading is een uitstekende stijlkeuze voor zowel beginners als 3D-experts..

Als je net begint met gameart, kun je je met de eenvoud van de workflow concentreren op de basisprincipes: leren hoe je een 3D-model kunt maken met een mooi silhouet en vorm, en het kunt kleuren met een kleine set met zorgvuldig geselecteerde kleuren. Door je te concentreren op deze grondbeginselen leer je de basisvaardigheden van kunst zonder afleiding.


Hoe Flat Shading werkt

Elk 3D-model bestaat uit een set hoekpunten die de vorm van dat model bepalen. Voor elke vertex is er ook een vector met de naam a normaal-beschouw dit als een kleine speld die uit de top steekt.

De rendering-engine gebruikt de normaalwaarde voor elke vertex en vergelijkt de richting met de richting van een inkomende lichtbron (nen) en de richting waarin de camera wordt geplaatst, om de hoeveelheid licht te bepalen die op die vertex moet worden toegepast.

De renderer vervaagt langzaam de hoeveelheid licht van de ene vertex naar de volgende, waardoor een eenvoudig 3D-model een 'zachte' look krijgt. Tenzij je een textuur aanbrengt (en vaak, zelfs als je dat wel doet), ziet dit er echt verschrikkelijk uit op iets dat niet echt een bochtig, "kussenachtig" oppervlak is:

Bij vlakke arcering krijgt het gehele oppervlak van een polygoon een uniforme hoeveelheid licht, berekend op basis van een normaal naar buiten steken vanuit het midden van de polygoon:

Moderne modelleringstoepassingen gebruiken "harde randen" of "afvlakkingsgroepen" om de hoekpuntnormen van uw model aan te passen aan de polygoon waar ze naastliggen, waardoor deze gelijkmatig en egaal gearceerd worden. Een bekwame 3D-kunstenaar zal deze gebruiken om scherpe randen er scherp en plat uit te laten zien, maar we willen het hele model er scherp en plat uit laten zien. Gelukkig maakt Unity dit heel eenvoudig.


Basistechniek

Als u voldoende bekend bent met uw modelleertool, kunt u uw model er vlak uit laten zien door alle randen als "hard" in te stellen. In Unity kunt u er echter eenvoudig voor kiezen om Unity harde randen automatisch te laten maken:

Stap 1

Klik op uw model in de project venster om zijn Instellingen importeren in de Inspecteur paneel.

Stap 2

Ga naar de Normen en Tangenten sectie en, in de normalen dropdown, kies Berekenen.

Stap 3

Stel de Gladmakende hoek naar 0 en klik Van toepassing zijn.

Unity zal elke rand maken die een scherpere hoek heeft dan deze in een harde rand. We willen dat al onze randen hard zijn, dus dat we deze natuurlijk instellen 0 geeft dit effect.

Experimenteer met verschillende afvlakhoeken, afhankelijk van de geometrie van uw model, het kan een verbazingwekkend eenvoudige manier zijn om het een compleet ander uiterlijk te geven.

Stap 4

Nu we ons model vlak grijs hebben, moeten we het wat kleur geven! Er zijn veel manieren om dit te doen, maar sommige zijn beter dan andere:

  • Selecteer gedeelten van uw model en stel ze in op een ander materiaal voor elke kleur die u wilt gebruiken.
  • Wijs vertex-kleuren toe aan uw modelleringsprogramma.
  • Maak een "palettextuur" met een aantal gekleurde vierkanten en structureer hier je modelstructuur van.

Ik geef de voorkeur aan de laatste methode, die ik hieronder aan u zal beschrijven. Normaal gesproken moet u, nadat u een 3D-model hebt gemaakt, het moeiteloos uitpakken om het overeen te laten komen met een handgemaakte textuur. Omdat we echter alleen geïnteresseerd zijn in een enkele kleur voor elke polygoon, maakt het niet echt uit hoe je UV-uitpakopdracht eruit ziet, maar het kan gewoon een willekeurig warboel zijn van hoekpunten, zolang het maar op de goede plaats zit kleur!

De eerste stap in kleuren is het maken van de textuur. Laten we voor ons voorbeeld zeggen dat we vier kleuren willen:

Laad vervolgens uw voltooide 3D-model in uw gewenste modelleur en laad uw textuur op. Selecteer alle vlakken van het model waarvan u een bepaalde kleur wilt hebben en trek ze automatisch automatisch uit. Het resultaat zal waarschijnlijk een verwarrend wirwar van polygonen zijn.

Maar zoals ik al zei, dat doet er eigenlijk niet toe. Verplaats alle polygonen boven op elkaar en schaal ze uit tot een kleine klodder die past in een van de vierkanten op je paletstructuur. Sleep ze vervolgens naar de kleur van uw keuze.

Bekijk je model; de textuursecties hebben nu de juiste kleur! Herhaal dit proces voor de rest van de gezichten van uw model, opnieuw selecteren en uitpakken op basis van de kleur die u wilt dat ze zijn. Als je een fout maakt, is dat geen probleem, selecteer gewoon de gezichten opnieuw, wikkel ze indien nodig opnieuw uit en leg ze op de juiste plaats op de textuur. Hetzelfde kan niet gezegd worden voor "echt" UV uitpakken!

Voilà! Je hebt een gekleurd, vlak gearceerd model dat je in je spel kunt importeren.


Hoe zit het met de andere methoden?

In het geval dat je je afvroeg, hier zijn enkele redenen om de andere twee methoden te vermijden:

Meerdere materialen

Deze methode zorgt voor een heleboel materialen die je in Unity moet bijhouden, en wat nog belangrijker is, Unity zal je modellen niet dynamisch batchen en een volledige draw-call gebruiken voor elk materiaal, wat vaak de kleinste bottleneck is op moderne grafische hardware..

Simpel gezegd, je krijgt vreselijke prestaties als je deze methode uitgebreid gebruikt.

Vertex Colors

Dit werkt eigenlijk redelijk goed, en je kunt dit eigenlijk wel gebruiken, afhankelijk van je specifieke behoeften of kunstworkflow. U zult echter onmiddellijk iets opmerken: wanneer u uw model importeert en een eenvoudige diffuse shader gebruikt, lijken uw vertex-kleuren niet te verschijnen!

Dit komt omdat de standaard shaders ze negeren; u moet speciale shaders gebruiken die de vertex-kleurgegevens gebruiken. Deze kunnen gemakkelijk worden gevonden, maar het wordt ingewikkeld als je ook andere rendereffecten van andere shaders wilt: deze shaders gebruiken vaak ook geen vertex-kleuren en je moet de shader zelf aanpassen.

Als je niet al weet hoe je shaders moet schrijven, kan dit leiden tot veel tijd en moeite die je liever aan de rest van je spel besteedt. Ook kan ik het zijn, maar ik vind het een stuk eenvoudiger om meerdere kleuren tegelijkertijd te veranderen met een textuur in plaats van ze handmatig in een modelleur of in-game met een script in te stellen.


Optimaliseren

Nu je een texture-palet en een basistechniek hebt uitgedacht, kun je doorgaan met het maken van de rest van de modellen voor je game. Zoals je misschien vermoedt, kun je gewoon kleuren blijven toevoegen aan je palet en dezelfde textuur gebruiken voor de hele game.

Er zijn eigenlijk enkele grote prestatievoordelen om dit te doen: als je vasthoudt aan het gebruik van hetzelfde materiaal voor je hele game, zal Unity meestal al je objecten efficiënter tekenen door ze te "batchen". Zoals ik eerder al zei, zijn "tekenoproepen" een belangrijk knelpunt in computergraphics en het is een goed idee om ze tot een minimum te beperken.

Unity zal automatisch proberen om je scène in zo weinig mogelijk draw-calls te tekenen als je voor alles een enkel materiaal gebruikt, hoewel elk model op dezelfde manier moet worden geschaald en minder dan ongeveer 300 hoekpunten bevat. Het zal u informeren hoe goed het is gedaan in de Stats venster:

Tip: Als u meer wilt weten over batches, moet u de Unity-documenten over het onderwerp bekijken. Dit moet verplicht gelezen worden voor iedereen die geïnteresseerd is in de uitvoering van hun spel!


Veranderende kleuren on the fly

Je hebt een reeks modellen die vlak en grijs zijn en alles lijkt op hun plaats, maar wat als je de kleuren wilt veranderen terwijl het spel wordt gespeeld?

Laten we bijvoorbeeld zeggen dat je een script hebt dat je vliegtuig zal spawnen, maar dat je het daarna blauw wilt kleuren als het vriendelijk of rood is als het een vijand is. Je kunt zeker alleen afzonderlijke paletten en afzonderlijke materialen maken, maar het betekent dat je de prestatieverbetering van het batchen van deze twee soorten vliegtuigen verliest.

Dat is niet erg als er maar een paar tegelijk in beeld zijn. Neem het voorbeeld van een procedureel gegenereerd terrein dat bestaat uit tonnen en tonnen tegels of kubussen, van veel verschillende terreinsoorten, zoals een bepaald populair sandbox-spel. Dit zou een hoop tekenbezoeken betekenen, maar wees niet bang, er is een manier om slechts één materiaal te gebruiken!

Weet je nog hoe je je model hebt gekleurd door de UV-coördinaten in gekleurde dozen te schuiven? Met Unity kun je de hoekpunten van je model on the fly aanpassen, inclusief de UV-coördinaten, dus voor elk type terreintype kun je de UV-coördinaten eenvoudig verplaatsen naar het juiste kleurvak via script.

Maak een nieuw C # -script in Unity genaamd PaletteColorizer en plak deze code erin:

gebruikmakend van UnityEngine; met behulp van System.Collections; public class PaletteColorizer: MonoBehaviour public int coloursPerRow = 4; openbare int colorIndex = 0; public bool overrideUVs = false; void Awake () if (! enabled) return;  SetUVsToColor (colorIndex);  void Update ()  public void SetUVsToColor (int colorIndex) if (overrideUVs) SetUVs (gameObject, GetColorOffset (colorIndex));  else TranslateUVs (gameObject, GetColorOffset (colorIndex));  Vector2 GetColorOffset (int colorIndex) Vector2-offset = nieuwe Vector2 (); zwevende rij = Mathf.Floor (colorIndex / colorsPerRow); zweeftrap = 1.0f / colorsPerRow; offset.x = (colorIndex - (rij * colorsPerRow)) * step; offset.y = (1.0f - (rij / colorsPerRow)); terugkeer offset;  static public void TranslateUVs (GameObject obj, Vector2 offset) var meshFilter = obj.GetComponent (); Mesh mesh = meshFilter.mesh; var newUVs = new Vector2 [mesh.uv.Length]; voor (int i = 0; i < mesh.uv.Length; i++)  newUVs[i] = new Vector2(mesh.uv[i].x + offset.x, mesh.uv[i].y + offset.y);  mesh.uv = newUVs;  static public void SetUVs(GameObject obj, Vector2 offset)  var meshFilter = obj.GetComponent(); Mesh mesh = meshFilter.mesh; var newUVs = new Vector2[mesh.uv.Length]; for(int i=0; i < mesh.uv.Length; i++)  newUVs[i] = new Vector2(offset.x + 0.01f, offset.y - 0.01f);  mesh.uv = newUVs;  

Als u dit script wilt gebruiken, voegt u het toe als een onderdeel van een game-object met een materiaal dat een paletstructuur gebruikt, stelt u het aantal kleuren per rij in en stelt u de kleurindex in (te beginnen met 0 in de linkerbovenhoek en te tellen tot rechts en naar beneden).

Als de UV-coördinaten van uw model niet zodanig zijn ingesteld dat ze in de paletvakken passen (zoals in het geval van de "water" -vierkant rond de zeskanten), controleert u de Negeer UV's checkbox; Zoals je hierboven kunt zien, zal het script volledig nieuwe coördinaten schrijven in plaats van bestaande te veranderen.

Eén ding om in gedachten te houden over deze methode is dat, bij het wijzigen van een netwerk, Unity stil een nieuwe mesh in het geheugen zal creëren. Als u dit met name vaak op een groot aantal mazen doet, kunt u geheugenproblemen tegenkomen en moet u zoeken naar een manier om mazen die op dezelfde manier zijn ingekleurd, te cachen en delen. Voor een redelijk aantal low-poly-modellen hoeft u zich er waarschijnlijk nooit zorgen over te maken.


Gebakken Ambient Occlusie

Vlakschaduw hoeft niet altijd te worden gepaard met uniforme kleurblokken. Een manier om subtiele details toe te voegen en een realistische "stoffige" look op elk oppervlak, is om er occlusie-occlusie aan toe te voegen. Unity Pro biedt manieren om omgevingsocclusie toe te voegen als een nabewerkingsfilter, maar ik wil u laten zien hoe u dat extra beetje polish kunt toevoegen zonder de Pro-versie te hoeven gebruiken en zonder dat u zelfs speciale shaders nodig hebt.

Het enige dat u hoeft te doen, is uw model uitpakken en het ambient occlusie-effect op een textuur "bakken". Dit vereist wel dat je echt wat tijd en moeite spendeert om je model correct uit te pakken, maar na die stap is het een kwestie van een paar klikken en een beetje gehannes in je verfprogramma om je model een iets meer echte, avantgarde uitstraling te geven.

Stap 1

Eerst wil je Blender opstarten met een lege scène: Druk op EEN om alle objecten in de opstartscène te selecteren, drukt u op Verwijder, druk vervolgens op D bevestigen. U wilt geen lampen of camera's omdat deze als lege ongewenste objecten in Unity worden geïmporteerd.

Stap 2

Importeer vervolgens uw model erin. (Bestand> Importeren> Wavefront (.obj)). Laten we voor dit voorbeeld beginnen met een rotsblok.

Stap 3

Open de UV-editor en maak een textuur die in staat is om ongeveer de hoeveelheid details te bevatten die u wilt. Ik ben behoorlijk gierig, dus ik hou het bij 256x256px voor alles over de grootte van de speler (een rots of een boom) en alleen groter voor zeer grote objecten (zoals de berg waarop ze lopen).

Stap 4

Pak nu je model uit. Er zijn veel manieren om dit aan te pakken, die veel gedetailleerder zijn dan ik ooit had kunnen hopen. Raadpleeg daarom de documentatie van de Blender of andere online handleidingen over hoe u uw model correct en efficiënt uitpakt..

Stap 5

Nu je een onverpakt model hebt, ben je klaar om de ambient-occlusie op je textuur te bakken. Blender maakt de omgevingsafsluiting direct op uw textuur, met respect voor de UV-coördinaten die u zojuist hebt uitgepakt. Volg eenvoudig deze stappen:

  1. Klik op de geven knop (het camerapictogram) in het deelvenster Eigenschappen aan de rechterkant van het scherm.
  2. Blader omlaag naar de Bakken subsectie (onderaan) en breid het uit.
  3. Verander de Bakmodus van Volledige weergave naar Ambient Occlusion.
  4. Klik op de Bakken knop direct daarboven.

Stap 6

Nu heb je de gebakken AO-textuur en een model dat de juiste UV-coördinaten heeft om het te gebruiken. Sla de textuur op in een afbeeldingsbestand en exporteer het model in Blender naar een formaat dat Unity kan gebruiken (zoals .FBX).

Stap 7

Afhankelijk van uw behoeften, kunt u de textuur in de huidige staat mogelijk gebruiken. Maak eenvoudig een nieuw diffuus materiaal dat je nieuwe gebakken AO-structuur gebruikt en stel de kleur in op iets dat er leuk uitziet.

U zult echter waarschijnlijk modellen met meerdere kleuren willen hebben, zoals een boom. U hoeft slechts een paar extra stappen te volgen. Volg de bovenstaande aanwijzingen om een ​​gebakken AO-structuur voor uw boommodel te maken. Deze keer wilt u echter bijhouden waar u uw UV-coördinaten hebt geplaatst, omdat u die locaties handmatig op de textuur moet inkleuren..

Het is verstandig om uw UV-eilanden op kleur te groeperen. In dit voorbeeld plaats ik de stamdelen aan de bovenkant van de textuur en de bladdelen aan de onderkant.

Stap 8

Open je gebakken AO-textuur met je verfprogramma naar keuze (alles wat lagen ondersteunt, zoals GIMP). Maak een nieuwe laag en plaats deze boven je AO-laag, met behulp van de AO-laag als richtlijn om de nieuwe laag in te kleuren volgens de kleuren die je in het model wilt zien.

Gebruik de Lasso gereedschap of een ander selectiegereedschap van uw keuze, om de delen van de textuur die u wilt kleuren te selecteren en vervolgens die met de juiste kleur te vullen.

Stap 9

Je hebt nu de kleuren ingesteld, dus het is tijd voor de laatste taak: het mengen van de AO bovenop de kleuren. Verplaats de AO-laag bovenop de gekleurde laag en wijzig de overvloeimodus in Vermenigvuldigen.

Zet de laagdekking op wat er maar goed uitziet. Gebruik uw eigen oordeel, maar noteer dit percentage, want om een ​​uniform effect op al uw texturen te krijgen, wilt u dezelfde mengmethode en hoeveelheid gebruiken.

Sla deze structuur op in een bestand en importeer het in Unity naast het boommodel. Maak een materiaal zoals je deed voor het rotsblok, met behulp van de textuur die je zojuist hebt gemaakt.

Dat is het eigenlijk wel! Gebruik deze techniek op al uw modellen om de hele scène een meer gepolijst, tastbaar uiterlijk te geven dan u zou kunnen krijgen met standaard vlakke arcering.

U zult merken dat uw materialen alleen basis diffuse shaders gebruiken. Een van de mooie dingen over het gebruik van gebakken AO die direct op de kleurtextuur is gemengd, is dat je deze textuur kunt gebruiken met elke andere arcering die een diffuse textuur heeft ... zonder AO-specifieke code vereist!


Conclusie

Nu heb je een handige toolbox met grafische technieken die je kunt gebruiken om een ​​volledig vlakschaduwspel te maken. Met voldoende oefening kun je verbluffende visuals maken die snel worden geproduceerd en efficiënt worden weergegeven.