Jump to content
Unity Insider Forum

Zer0Cool

Members
  • Content count

    1,865
  • Joined

  • Last visited

  • Days Won

    132

Everything posted by Zer0Cool

  1. Hallo zusammen, ich beschäftige mich gerade relativ viel mit Shadern und da ich der Community auch mal etwas zurückgeben wollte, habe ich einmal einen ganz brauchbaren Shader von der Seite http://glslsandbox.com/e#35099.0 nach Unity portiert, der eine plasmaähnliche Oberfläche simuliert. Ich würde ihn für spezielle Effekte verwenden, wie magische Portale, Wände, kleine magische Gegenstände oder einfach als Hintergrund für einen Splashscreen. Bei Objekten die in der Szene bewegt werden, würde ich ihn nicht verwenden (außer die Objektgeometrie spielt keine Rolle), da er ein Pixelshader ist und die räumliche Lage des Models im Raum ignoriert. Was man damit auch machen könnte, wäre einen "Schutzschild" um einen Spieler herum zu visualisieren. Einfach eine Sphere nehmen, diesen Shader zuordnen und den Alphakanal herunterregeln z.B. 0.5 und die Sphere auf einen Charakter Controller ziehen. Zum Ausprobieren den Shader einfach einem Material zuweisen und die gewünschten Farbwerte und Transparenz einstellen. Dann bspw. eine Plane in die Scene ziehen und das Material setzen. Aufpassen, dass ihr mit der Camera auf die Vorderseite der Plane schaut. Ich habe den Shader zusätzlich transparent gemacht und die Farben lassen sich wie gewünscht über einen Slider einstellen. PS: Wenn man das Material des Shaders auf ein Quad (oder Plane) legt, über eine Kamera "abfilmt" und so eine Rendertextur erzeugt, dann kann man diese Textur auch für beliebige 3D-Objekte verwenden. Viel Spaß beim Austesten PlasmaWaves.shader
  2. Zer0Cool

    GameObjekt wird direkt Zerstört. Hilfe. :(

    Malzbie hat recht, nur hat er vermutlich das "!" übersehen. Sind alle deine Spielfigurobjekte mit dem Tag "Player" getaggt? Sollten sie sein, ansonsten wird das Buch bereits durch ggf. vorhandene Trigger am Spieler zerstört. Objekte die das Buch treffen soll, dürfen diesen Tag dann allerdings nicht haben!
  3. Zer0Cool

    Dynamischer Text auf Mesh

    In Unity gibt es den alten Textmesh: https://docs.unity3d.com/Manual/class-TextMesh.html oder https://assetstore.unity.com/packages/essentials/beta-projects/textmesh-pro-84126 (kostenlos)
  4. Zer0Cool

    Custom Base-Textur für Terrain

    Der Terrainshader bekommt die 4 Splatmap + Controltextur + Basemap als Input ... Unity verwendet die berechnete Basetextur des Terrain ja von Haus aus, wenn die Kamera einen bestimmten Abstand zum Terrain hat. Man kann fürs Terrain unter den Settings auch einen eigenen Terrainshader definieren, aber ich denke das würde zu weit führen. Ich vermute man kommt an die Basetextur des Terrain von Außen nicht ran... Der Unityterrainshader ist ohnehin sehr performant, von daher würde ich mir hier keine Gedanken machen ...
  5. Zer0Cool

    Custom Base-Textur für Terrain

    Ich denke nein, Unity berechnet soweit ich weiß die Basetextur aus den Splatmaptexturen + Controltexturen. Du kannst aber deine "Basetextur" als Splatmaptextur 1 (bzw. 0) des Terrains übergeben. Unity füllt das Terrain ja mit der Splatmaptextur 1 vollständig aus (sozusagen die Grundierung). Wenn du die "Size" der Splatmaptextur auf die Größe deines Terrains ziehst, dann wird deine Textur über das komplette Terrain gezogen (und nicht gekachelt). Allerdings wird die Textur des Terrain damit pixelig, da Unity ja nun nicht mehr die Auflösung der Splatmaptextur erhöhen kann, wenn die Kamera dichter an's Terrain kommt ...
  6. Zer0Cool

    Billboards

    Hab deine Grafik angeschaut und deine Alpha geht bis an den unteren Rand und dies ist schlecht! Im Alphachannel sollte unten ein schwarzer Rand sein mit mind. 2-3 Pixel Breite ...
  7. Zer0Cool

    Billboards

    Wie werden denn die Billboard in Unity dargestellt? Beim "Edge Padding" werden im Endeffekt die Ränder der Textur nach außen gezogen und der Hintergrund an die Textur angeglichen. Hier ein Beispiel. Damit soll ein "Color Bleeding" verhindert werden, aber dein Problem sieht eher nach einem "Randproblem" aus, d.h. die UV greift über die Textur hinaus...
  8. Zer0Cool

    Objekteigenschaften ansprechen per Script

    Sieht ein wenig "konfus" aus. Dies hier ist völlig verkehrt: public class Spawner : MonoBehaviour { void Start () { TileClass tileClass = new TileClass(); tileClass.init(); } } Eine MonoBehaviour-Klasse wird nie mit "new" erzeugt! Was genau lädst du mit?: tileObject = Resources.Load("Tile") as GameObject; Resources.Load sollte man wenn es geht vermeiden, da dies eigentlich nur für bestimmte Spezialfälle gut ist und ich glaub du ganz etwas anderes machen willst: Du solltest folgendermaßen vorgehen: erstelle ein GameObject in deiner Szene und hänge die Klassen dran die du brauchst (z.b. die TileClass-Klasse) mache ein Prefab aus diesem GameObject in der Szene: das Szenenobjekt mit der Maus in deinen Projektfolder ziehen ( = Prefab) Szeneobjekt aus der Szene löschen dieses Prefab übergibst du deinem Spawnerskript (siehe unten) Der Code könnte dann folgendermaßen aussehen: using UnityEngine; public class Spawner : MonoBehaviour { private GameObject[] entities; public GameObject prefab; // Hier dein erzeugtes Prefab draufziehen mit deiner TileClass Klasse void Start() { // Ich erzeuge hier mal nur 1 Objekt GameObject tileGO = Instantiate(prefab, new Vector3(0, 0, 0), Quaternion.identity) as GameObject; TileClass tile = tileGO.GetComponent<TileClass>(); tile.value = 10; } } using UnityEngine; public class TileClass : MonoBehaviour { public int value; private void OnMouseDown() { this.value; } }
  9. Zer0Cool

    Objekteigenschaften ansprechen per Script

    Ich sehe gerade da war noch ein Fehler in der Unity-Doku (woraus ich Teile des Codes kopiert hatte), hier sollte man nicht Transform als Datentyp fürs Prefab nehmen, sondern GameObject (das führt später sonst zu allerlei Problemen): //public Transform prefab; public GameObject prefab;
  10. Zer0Cool

    Objekteigenschaften ansprechen per Script

    // Instantiates 10 copies of prefab each 2 units apart from each other using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { private GameObject[] entities; public GameObject prefab; void Start() { entities = new GameObject[10]; for (int i = 0; i < 10; i++) { entities[i]= Instantiate(prefab, new Vector3(i * 2.0F, 0, 0), Quaternion.identity) as GameObject; } } } Obiges Array "entities" speichert die 10 erzeugten GameObjekts. Für ein Zugriff auf eine Klasse die am jeweiligen GameObjekt hängt kannst du noch folgendes zusätzlich machen: entities[i] = Instantiate(prefab, new Vector3(i * 2.0F, 0, 0), Quaternion.identity) as GameObject; // auf die Klasse "Missile" zugreifen die am GameObjekt hängt (also zuvor am Prefab) Missile missile = entities[i].GetComponent<Missile>(); missile.speed = 5.0f; // Eigenschaft speed der Klasse Missile setzen
  11. Zer0Cool

    Billboards

    Schwer zu sagen ohne weitere Informationen. Wie hast du dieses Billboard dargestellt? Oft tritt dieses Problem auf, wenn die Grafiken die auf einer Atlastextur platziert werden einen zu geringen Abstand zueinander haben (kann beispielsweise bei Detailtexturen des Unityterrains passieren. Diese werden nämlich von Unity intern auf einer 1024-Altastextur angeordnet, um die Performance zu optimieren. Hier hilft dann auch nur ein "Edge Padding" der jeweiligen Detailtextur die verschwimmt). Zudem gibt es auch noch einen ähnlichen Effekt beim internen erstellen von MipMaps in Unity. Hier kann es passieren, das bei einer Textur die UV-Ränder verwaschen, da beim MipMapping die Textur verkleinert wird. Auch hier hilft nur ein ensprechend breiterer Rand zwischen den "UV-Shapes". Meine Vermutung in deinem Fall wäre, daß ein entsprechend vergrößerter Rand um deine Billboardtextur helfen könnte. PS: Zu beachten ist auch, daß der Alphachannel-Rand ebenfalls groß genug sein sollte (= schwarzer Rand im Alphachannel)
  12. Zer0Cool

    Mehrere Canvas-Objekte in Szene

    Ich denke mehrere Canvas(e) im "World Space"-Mode sind kein Problem. Damit kann man das Canvas im 3D-Raum positionieren und die Größe der Anzeige skaliert mit dem Abstand des Spielers/NPC zur Kamera. Möchte man dies nicht, dann ist denke die Methode von @Thariel besser, damit bleibt die Anzeigengröße unabhängig vom Abstand zur Kamera.
  13. Zer0Cool

    Sprite Shader- Color Tint

    So, nun hab ich aber was gut Hier der Shader (ich habe noch ein paar Zeilen aus dem Original Sprite Shader eingefügt für's PixelSnap und Flipping): Shader "Sprites/Beat/Diffuse-Shadow" { Properties { [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {} _Color("Tint", Color) = (1,1,1,1) [MaterialToggle] PixelSnap("Pixel snap", Float) = 0 [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1) [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1) _Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5 } SubShader { Tags { "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" } LOD 200 Cull Off Lighting On ZWrite Off CGPROGRAM #pragma surface surf Lambert vertex:vert addshadow alphatest:_Cutoff #pragma multi_compile _ PIXELSNAP_ON #include "UnitySprites.cginc" struct Input { float2 uv_MainTex; fixed4 color; }; void vert(inout appdata_full v, out Input o) { v.vertex.xy *= _Flip.xy; #if defined(PIXELSNAP_ON) v.vertex = UnityPixelSnap(v.vertex); #endif UNITY_INITIALIZE_OUTPUT(Input, o); o.color = v.color * _Color * _RendererColor; } void surf(Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } Fallback "Legacy Shaders/Transparent/Cutout/VertexLit" } Dieses Skript ist auch noch notwendig, damit der Sprite Renderer auch Schatten weiterleitet: using UnityEngine; using UnityEngine.Rendering; public class ControlSpriteRenderer : MonoBehaviour { private Renderer render; // Use this for initialization void Start () { render = GetComponent<Renderer>(); render.receiveShadows = true; render.shadowCastingMode = ShadowCastingMode.On; } } Der Schattenwurf scheint aber nur für's Directional-Light zu funktionieren. Bei einem Spot-Light scheinen keine Schatten zu entstehen ...
  14. Zer0Cool

    IEnumerator

    Du startest die Coroutine "Lebenregeneration" mehrfach, was denke ich dazuführt, daß im Prinzip nach 3 Sekunden + X Frames das Leben wieder voll ist (jedes neue Frame wird dabei die Coroutine erneut gestartet). Ich würde es so machen: IEnumerator Lebenregeneration() { lebenreg = true; while (SAktuellesLeben < Maxleben) { SAktuellesLeben = SAktuellesLeben + 1; yield return new WaitForSeconds(3); } lebenreg = false; } if (!Spieler.infight) { if(SAktuellesLeben < Maxleben) { if (!lebenreg) { StartCoroutine(Lebenregeneration()); } } }
  15. Zer0Cool

    Audio Bei Distance

    Evtl. kommst du mit dem Pitchwert der Audiosource zum gewünschten Ergebnis: https://docs.unity3d.com/ScriptReference/AudioSource-pitch.html Ansonsten kann man auch den Clip "vorspulen", damit spielt er dann nur einen Teil des Audios ab. Einfach auf time ein paar Sekunden draufaddieren (wenn der Sound mehrere Sekunden lang ist). Ggf. die Länge des Clips vorher auslesen, damit man die Restlänge berechnen kann: https://docs.unity3d.com/ScriptReference/AudioSource-time.html Beispiel: Cliplänge: 3 Sekunden (kann man aus dem Clip auslesen) Bogen-Distanz Maximal: 5 (musst du selbst festlegen - siehe Skript unten) using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { private AudioSource audioSource; private float clipLength; private float maxBowDist = 5.0f; private float addedTime; void Start() { audioSource = GetComponent<AudioSource>(); clipLength = audioSource.clip.length; } void Update() { if (Input.GetKeyDown(KeyCode.Return)) { float dist = (stringStartPoint.transform.position - grabpoint.transform.position).magnitude; addedTime = (clipLength/maxBowDist) * dist; audioSource.time = clipLength - addedTime; // Audioclip verkürzt abspielen je nach Bogenspannung audioSource.Play(); } } }
  16. Zer0Cool

    Skript nur für den Editor

    Weiß nicht genau, was du da speichern willst, ggf. könntest du es auch in einer Scriptable-Objekt-Klasse ablegen, dann sind diese Daten eben auch keine Szenendaten mehr (= SO-Asset) und SO's funktionieren im Editor in beide Richtungen (lesen / schreiben). Nach einem Build dann nur noch lesend, aber dies würde dich ja nicht stören.
  17. Zer0Cool

    Custom Leaf Shader

    Ich denke das Tree-Script schreibt Vertexfarben direkt in dem Baummesh ... Ein eigener Shader müsste dann diese Vertexfarben auslesen und könnte damit "Wind" simulieren. Die Vertexfarben definieren dabei aber nur, wie stark der jeweilige Vertex von Wind verändert werden kann ... Der Shader selbst benötigt noch die Daten der (Unity)Windzone (die man aber leider nicht selbst auslesen kann). Ansonsten berechnet der Shader nun anhand der Winddaten und einer Zeitfunktion über Sinus und Cosinus die jeweiligen Positionen der Vertices der Blätter und der Baumäste (ganz grob erklärt).... Eventuell kann man die Unity-WIndzone auch anzapfen, wenn man seine Schnittstelle des Shader so wie die Shader des Tree Creators definiert, aber ob dies funktioniert, da bin ich auch überfragt. Zudem kann es sein, daß man Windzonendaten nur bekommt, wenn man den Baummesh über das Terrain (Paint) setzt. Frei stehende Bäume haben dann also überhaupt keine Chance an die Unity-WInddaten zu kommen .. Laut meinen Versuchen braucht man aber eigentlich die Unity-Winddaten nicht unbedingt, man kann eine WIndrichtung und Stärke auch selber im Shader definieren ... Hier ein sehr simpler Shader der die Vertexfarben darstellt. Wenn du den Tree-Creator-Baummesh mal damit darstellst solltest du die Vertexfarben sehen (habs aber noch nicht getestet): Shader "Example/Diffuse Vertexcolor" { SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float4 color : COLOR; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = color.rgb; // ggf. rausnehmen wenn man nix sieht o.Alpha = color.a; } ENDCG } Fallback "Diffuse" }
  18. Zer0Cool

    Weiße Flecken auf Lightmap

    Lightmaps ist ein komplexes Thema, nach meiner Erfahrung kann es passieren, daß Unity die UV2 (Lightmap UV) "ungünstig" beim Modelimport berechnet (oder man hat es vergessen beim Import anzuwählen, dann generiert er überhaupt keine UV2 = ganz schlecht). Oft kann man das daraus resultierende schlechte Ergebnis zwar mit den Lighmapper-Settings kaschieren, aber es wird nie perfekt. Auch bei kombinierten Meshes (Mesh Kombiner Tools in Unity) hatte ich viele Lighmap-Probleme. Hier werden die UVs der Teilmeshes zwar kombiniert, passen aber eigentlich nicht "harmonisch" zusammen, eine Neugenerierung der UV2 in Unity kann helfen (muss aber nicht). Notfalls kann man die UV2 in einem 3D-Programm selbst erzeugen, hier reicht es oft eine automatische UV2 aufs Modell zu projizieren. Wenn die Lightning Probleme nur an den Rändern auftauchen, kann es schon auch ein Padding Problem sein ... Gibt glaube ich auch ein Setting fürs Padding beim Importer und der Erzeugung der UV2 beim Import des Meshes (hier mal ein anderes Padding wählen).
  19. Zer0Cool

    Missing Prefabs

    Meinst du Prefabs oder Assets? Sind 2 verschiedende Sachen in der Unitywelt. Wenn du beispielsweise ein Prefab erzeugst und später die Assets des Projektes veränderst (verschiebst oder löscht) kann dies ein Prefab zerstören. Das Prefab findet dann seine Assets nicht mehr (Assets sind im Prefab verlinkt)...
  20. Generell kann man sagen, die Anzahl der GameObjekte und Skripte in einer Szene möglichst auf ein Minimum zu beschränken. Alles in eine Klasse zu packen, nur damit man Skripte spart, macht allerdings auch keinen "Sinn". Vielmehr sollte man darauf achten, die Zahl die sich ergibt aus GameObjekte je Szene * Anzahl Skripte pro GameObjekt zu begrenzen. Zudem ist nach meinen Erfahreungen ein GameObjekt mit mehreren Skripten prinzipiell besser ist als viele GameObjekte mit einem Skript (die Performance der Skripte mal außer acht gelassen).
  21. Aus meinen Erfahrungen kann es zu Performanceproblemen führen, wenn man zahlreiche Objekte "gleichen Typs" in der Szene hat und diese jeweils mehrere Skripte enthalten. Ein Negativbeispiel wären Coins in einem einem 2D-Spiel die zu hunderten in der Szene vorkommen und an diesen Coins jeweils mehrere Skripte hängen (Collect / Trigger / Raycast etc). Hier sollte man lieber die Coins ohne ein GameObjekt (Graphics.DrawMesh oder Graphics.DrawMeshInstanced) und ohne Skripte pro Frame darstellen und die Coins jeweils über ein "ControllerSkript" verwalten. Dieses besitzt dann eine Datenstruktur die alle Positionen und Rotationen der Coins in der Szene enthält (also im Endeffekt die Informationen eines GameObjektes abbildet). EIn einzelnes Objekt in der Szene (wie ein Spielerobjekt) mit einer handvoll Skripten (5-10) halte ich eher für unkritisch. Hier würde ich dann eher darauf achten, daß diese Skripte nur wenn "unbedingt notwendig" etwas in der Update- oder LateUpdate-Methode ausführen.
  22. Zer0Cool

    Custom Leaf Shader

    Ich hatte mir die Tree Creator Shader ja mal angeschaut und sie gehen (soweit ich gesehen habe) nicht über die 2. UV Map (die nutzt Unity ja für Lightmaps) sondern sie gehen über die Vertexfarben. Die Vertexfarbe bestimmt dabei, ob der entsprechende Vertex (im Shader) bewegt wird oder nicht. Bei einem Blatt würden sich beispielsweise die beiden Vertices die nicht am Ast anliegen eine Farbwert bekommen, die eine maximale Beweglichkeit definiert (hoher Farbwert). Ich denke die Vertexfarben für die Äste werden entsprechend gesetzt. Vertices die sich nah am Hauptstamm befinden bekommen einen niedrigen Farbwert (=geringe Beweglichkeit), mit zunehmendem Abstand vom Hauptstamm (bzw. Teilast) nimmt die Beweglichkeit der Vertices zu (höhere Farbwerte). Ob nun der R / G oder B Channel der Vertexfarbe verwendet wird um die Intensität der Windbewegung zu setzen wird dabei im Shader definiert. Felsen würden bei deinem Shader dann die "0" Entsprechung der Vertexfarbe (R / G / B = 0) bekommen. RenderMode: Man definiert einen entsprechenden (Light)Pass für den jeweiligen Rendermode. Der eingestellte Rendermode wählt dann den entsprechenden Pass den Shaders. Für einen spezifischen Rendermode muss also ein eigener Codeabschnitt im Shader erstellt werden. Der Rendermode wird allerdings über die Kamera definiert (d.h. hier müsste man den Mode per Skript umsetzen)
  23. Hallo zusammen, bin wieder "am Start", war 6 Wochen "am Erholen" , aber nun schau ich wieder regelmäßig rein ;)

    1. Kojote

      Kojote

      Na dann Willkommen zurück! ^_^

  24. Zer0Cool

    Mass Place Trees/Grass/Rocks etc.

    Hab am Shader nur die Schwingfrequenz geändert, verzerren tut sich da eigentlich nix, daß muss dann ein anderes Problem sein, hast du den Mesh geändert? Hier der Shader ohne die Schwingfrequenzänderung, aber ich vermute das dies nicht das Problem war, Vielleicht hattest du auch an den Variablen des Shaders gedreht und diese haben sich nun durch das erneute Einspielen des Shader zurückgesetzt ? Shader "Custom/Grass/GrassBending" { Properties{ _Color("Main Color", Color) = (1,1,1,1) //_MainTex("Base (RGB) Trans (A)", 2D) = "white" {} _MyArr("Tex", 2DArray) = "" {} _Cutoff("Alpha cutoff", Range(0,1)) = 0.5 _ShakeDisplacement("Displacement", Range(0, 1.0)) = 1.0 _ShakeTime("Shake Time", Range(0, 1.0)) = 1.0 _ShakeWindspeed("Shake Windspeed", Range(0, 1.0)) = 1.0 _ShakeBending("Shake Bending", Range(0, 1.0)) = 1.0 } SubShader{ Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" } LOD 200 Cull Off CGPROGRAM // to use texture arrays we need to target DX10/OpenGLES3 which // is shader model 3.5 minimum #pragma target 3.5 #pragma surface surf Lambert alphatest:_Cutoff vertex:vert addshadow UNITY_DECLARE_TEX2DARRAY(_MyArr); // sampler2D _MainTex; // fixed4 _Color; float _ShakeDisplacement; float _ShakeTime; float _ShakeWindspeed; float _ShakeBending; float dist; float _GrassAlpha; struct Input { //float2 uv_MainTex; float2 uv_MyArr; float3 worldPos; }; void FastSinCos(float4 val, out float4 s, out float4 c) { val = val * 6.408849 - 3.1415927; float4 r5 = val * val; float4 r6 = r5 * r5; float4 r7 = r6 * r5; float4 r8 = r6 * r5; float4 r1 = r5 * val; float4 r2 = r1 * r5; float4 r3 = r2 * r5; float4 sin7 = { 1, -0.16161616, 0.0083333, -0.00019841 }; float4 cos8 = { -0.5, 0.041666666, -0.0013888889, 0.000024801587 }; s = val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w; c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w; } // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_CBUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color) UNITY_DEFINE_INSTANCED_PROP(float, _TextureIndex) // put more per-instance properties here UNITY_INSTANCING_CBUFFER_END void vert(inout appdata_full v) { float factor = (1 - _ShakeDisplacement - v.color.r) * 0.5; const float _WindSpeed = (_ShakeWindspeed + v.color.g); const float _WaveScale = _ShakeDisplacement; const float4 _waveXSize = float4(0.048, 0.06, 0.24, 0.096); const float4 _waveZSize = float4 (0.024, .08, 0.08, 0.2); const float4 waveSpeed = float4 (1.2, 2, 1.6, 4.8); float4 _waveXmove = float4(0.024, 0.04, -0.12, 0.096); float4 _waveZmove = float4 (0.006, .02, -0.02, 0.1); float4 waves; waves = v.vertex.x * _waveXSize; waves += v.vertex.z * _waveZSize; waves += _Time.x * (1 - _ShakeTime * 2 - v.color.b) * waveSpeed *_WindSpeed; float4 s, c; waves = frac(waves); FastSinCos(waves, s,c); float waveAmount = v.texcoord.y * (v.color.a + _ShakeBending); s *= waveAmount; s *= normalize(waveSpeed); s = s * s; float fade = dot(s, 1.3); s = s * s; float3 waveMove = float3 (0,0,0); waveMove.x = dot(s, _waveXmove); waveMove.z = dot(s, _waveZmove); v.vertex.xz -= mul((float3x3)unity_WorldToObject, waveMove).xz; } void surf(Input IN, inout SurfaceOutput o) { //fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(_Color); fixed4 c = UNITY_SAMPLE_TEX2DARRAY(_MyArr, float3(IN.uv_MyArr, UNITY_ACCESS_INSTANCED_PROP(_TextureIndex))) * UNITY_ACCESS_INSTANCED_PROP(_Color); o.Albedo = c.rgb; float dist = distance(_WorldSpaceCameraPos, IN.worldPos); dist = clamp(dist / 300, 0.4, 1.0); o.Alpha = c.a - dist - _GrassAlpha; } ENDCG } Fallback "Transparent/Cutout/VertexLit" } Die Textur kannst du hier ändern, 256x1 gibt es nicht, aber du kannst 256x256 einstellen: / See Texture2DArray in unity scripting API. Texture2DArray textureArray = new Texture2DArray(256, 256, slices, TextureFormat.RGBA32, false);
  25. Zer0Cool

    Mass Place Trees/Grass/Rocks etc.

    Ich habe oben das Skript noch einmal verändert, da das Übergeben der Properties im Falle "ohne GOs" noch falsch war. Du kannst das Ganze anwenden wie du lustig bist. Das Problem im Falle ohne GOs ist (also die nicht interaktiven Grasinstanzen), hier sind die Instanzen auf 1023 limitiert und daher müsstest du das obige Beispielskript erweitern, so das es die Gras-Details in Chunks von 1023 gerendert werden. Das bedeutet 1 DC für 1023 Instanzen. "Graphics.DrawMeshInstanced" kann leider nur 1023 Instanzen auf einmal rendern. "Normale Grasmengen" bewegen sich so um die 100000 Instanzen..., d.h. du würdest letztendlich 100 DCs für das Gras benötigen... Das interaktive Gras würdest du dann mit GOs erzeugen. Hier würde ich einem quadratischen Bereich um den Spieler definierten. Also Zusammenfassung: - du berechnest Positionen für alle Grasinstanzen, diese können auch über ein Tool erzeugt werden - diese Positionen werden entweder mit GO oder ohne GO gerendert (siehe Skript oben) - die GOs keinesfalls jedes Frame neu erzeugen, sondern nur die Positionen umsetzen - die Spielerposition definiert die Anzahl und Positionen der interaktiven Instanzen je Frame! - interaktive Instanzen mit GOs werden um den Spieler herum gerendert (beispielsweise 5x5 Meter) - alle anderen nicht interaktiven Grasinstanzen werden ohne GOs in Chunks von 1023 gerendert - die interaktiven Grasinstanzen werden jedes Frame von nicht interaktiven Instanzen abgezogen Besser wäre es evtl. zu tricksen, du kannst auch alle Grasinstanzen einfach ohne GOs rendern! und die interaktiven Grasinstanzen als leere GOs in die Scene packen. Damit musst du das Array für die nicht interaktiven Instanzen nicht jedes Frame ändern und das spart viel FPS! Sobald der Spieler beispielsweise Grasdetails entfernt hat (modifiziert) hat, werden diese aus dem Array für die nicht interaktiven Grasdetails entfernt. Das Ganze ist leider nicht optimal, da eine Änderung am Array immer eine CPU Belastung auslöst, es wäre also günstig, die Änderung des Arrays für die Grasinstanzen nicht jedes Frame zu ändern. Ein anderes Problem ist noch die pure Menge an Grasdetails. Bei "Graphics.DrawMeshInstanced" werden immer alle Grasinstanzen übergeben, die gerendert werden sollen. Diese werden nicht über Distanz oder der Kamera gecullt. Dafür muss man selbst sorgen. Eine Mögliche Lösung ohne Computeshader wäre sein Terrain in Chunks aufzuteilen und Chunks zu rendern die in Spielernähe sind. Jedes Chunk würde dabei seine Grasdetails kennen und diese Rendern. Entfernt sich ein Spieler zu weit vom Chunk wird dieser deaktiviert. Aber wie du siehst, ist das Ganze dennoch recht komplex (auch wenn ich den Weg dargestellt habe), weshalb ich auch mein eigenes Gras-Shader-System gestartet. Zumal man das Ganze mit Computeshadern kombinieren kann und eben auch Instancing Indirekt verwenden kann.
×