• Announcements

    • Lars

      Allgemeine Forenregeln   03/13/2017

      Forenregeln Nimm dir bitte einen Moment um die nachfolgenden Regeln durchzulesen. Wenn du diese Regeln akzeptierst und die Registration fortsetzen willst, klick einfach auf den "Mit der Registrierung fortfahren"-Button. Um diese Registration abzubrechen, klick bitte einfach auf den "Zurück" Button deines Browsers. Wir garantieren nicht für die Richtigkeit, Vollständigkeit und Brauchbarkeit der Nachrichten und sind auch nicht dafür verantwortlich. Die Beiträge drücken die Meinung des Autors des Beitrags aus, nicht zwangsläufig das, wofür die Forensoftware steht. Jeder Nutzer, der denkt, dass ein veröffentlichter Beitrag unzulässig bzw. störend ist, ist aufgefordert uns unverzüglich per E-Mail zu kontaktieren. Wir haben das Recht störende Beiträge zu löschen und bemühen uns, das in einem realistischem Zeitraum zu erledigen (sofern wir beschlossen haben, dass die Löschung notwendig ist). Du akzeptierst, durchgehend während der Nutzung dieses Services, dass du dieses Forum nicht dazu missbrauchen wirst, Inhalte zu veröffentlichen, welche bewusst falsch und/oder verleumderisch, ungenau, beleidigend, vulgär, hasserfüllt, belästigend, obszön, sexuell belästigend, bedrohlich, die Privatsphäre einer Person verletzend oder in irgend einer Art und Weise das Gesetz verletzen. Des Weiteren akzeptierst du, dass du keine urheberrechtlich geschützte Inhalte ohne Erlaubnis des Besitzers in diesem Forum veröffentlichst. Mit dem Klick auf den "Mit der Registrierung fortfahren"-Button, akzeptierst du zudem unsere Datenschutzerklärung und stimmst der Speicherung deiner IP-Adresse und personenbezogenen Daten zu, die dafür benötigt werden, um dich im Falle einer rechtswidrigen Tat zurückverfolgen zu können bzw. permanent oder temporär aus dem Forum ausschließen zu können. Es besteht keine Pflicht zur Abgabe der Einwilligung, dies erfolgt alles auf freiwilliger Basis.   Zusatzinformationen Der Forenbetreiber hat das Recht, Nutzer ohne Angabe von Gründen permanent aus dem Forum auszuschließen. Des Weiteren hat er das Recht, Beiträge, Dateianhänge, Umfrage, Blogeinträge, Galleriebilder oder Signaturen ohne Angabe von Gründen zu entfernen. Mit der Registrierung verzichtest du auf alle Rechte an den von dir erstellten Inhalten, bzw. treten diese an das Unity-Insider.de und Unity-Community.de ab. Dies bedeutet im Klartext, dass das Unity-Insider.de und Unity-Community.de frei über deine Texte verfügen kann, sofern diese nicht wiederum die Rechte anderer verletzen. Es besteht weiterhin kein Anspruch von registrierten Nutzern bzw. ehemaligen registrierten Nutzern darauf, dass erstellte Inhalte und/oder die Mitgliedschaft (User) wieder gelöscht werden (Erhaltung der Konsistenz dieses Forums).   Einwilligungserklärung Wenn du mit der Speicherung deiner personenbezogenen Daten sowie den vorstehenden Regeln und Bestimmungen einverstanden bist, kannst du mit einem Klick auf den Mit der Registrierung fortfahren-Button unten fortfahren. Ansonsten drücke bitte Zurück. Stand: 07.03.2011

Zer0Cool

Members
  • Content count

    263
  • Joined

  • Last visited

  • Days Won

    14

Zer0Cool last won the day on March 10

Zer0Cool had the most liked content!

Community Reputation

56 Excellent

About Zer0Cool

  • Rank
    Advanced Member
  • Birthday 01/04/1974

Contact Methods

  • Website URL
    http://https://www.facebook.com/huginmuninstudios
  • Skype
    zer0f0rce

Profile Information

  • Gender
    Male
  • Location
    Germany

Recent Profile Visitors

1,323 profile views
  1. Ja, genau wie Life sagt, Unitys Koroutinen laufen derzeit auf dem gleichen CPU-Kern wie Unity selbst. Bei der GPU Verwendung bin ich mir nicht sicher, die Stärke von GPUs ist es schon 1000de von kleinen Berechnungen durchzuführen, was für eine große Menge an KI-Einheiten schon nicht verkehrt wäre, es kommt aber eben auch auf die aktuelle Auslastung der GPU an... Wenn man allerdings den Weg geht, die KIs zu clustern - wie Life sagt -, dann braucht man es wieder weniger. Je mehr Gameobjekts sich in der Szene befinden und an jeden Gameobjekt ein Skript hängt, desto mehr Rechenzeit wird allein dadurch "verbraten", daß Unity die einzelnen Objekte durchlaufen und ansteuern muss (inklusive dem Durchlaufen der angehängten Skripte). Wenn man allerdings ein einzelnes Kontrollerskript verwendet,, welches die Objekte in der Szene selbst durchläuft und dann Aktionen auf diesen Objekten ausführt spart wiederum einiges an Rechenzeit. Dieser Effekt wird umso grösser, je mehr Objekte sich in der Szene befinden.
  2. Naja, wie es scheint ist es zwar mit "Unity" gemacht, aber sämtliche Komponenten sind Marke Eigenbau. Bei den Shadern angefangen, ich denke kein Unity Pfadsystem, kein Unity Animator etc. verwendet und alles extrem auf Leistung getrimmt, also KI auf 4 Kerne verteilt (Unity ist ja bislang nur auf einem Kern unterwegs) und vermutlich selbst Hintergrundroutinen in die GPU verlagert. Aber nochmal zurück zum Thema: - Low Poly Meshes verwenden (und möglichst nur 1 Material), ggf. nicht den Unity Standardshader verwenden (zu langsam) - dieses Asset verwenden, es umgeht den Unity Animator und spart so extrem viel Rechenzeit: https://www.assetstore.unity3d.com/en/#!/content/26009 - kein Unity Navmesh fürs Pathfinding verwenden (leider kenne ich hier noch kein gutes Asset für Mass Crowds, so ein Asset sollte mit einem gebackenden Terrain, Multithreading und zuschaltbaren GPU Routinen arbeiten) - KI Routinen in "echte" gethreadete Koroutinen auslagern: https://www.assetstore.unity3d.com/en/#!/content/15717 - KI Routinen (Skripte) hängen nicht mehr an den AI-Gameobjekts, sondern durchlaufen alle existierenden KI-Einheiten (spart wieder einiges an CPU Rechenzeit) Wenn du mal ein Ergebnis hast, wie viele Einheiten du damit schaffst, gib mir mal bescheid
  3. Mal schauen, wenn er sich der Specular Shader nicht groß unterscheidet, setz ich mich da nochmal ran
  4. Das "Repeat" bezieht sich nur auf die Importeinstellungen der Textur, damit die Textur auch tatsächlich wiederholt wird und nicht abgeschnitten. Der Shader oben sollte funktionieren, wenn du ihn auf dein generiertes Mesh anwendest und die UVs der Textur in voller Breite auf das Mesh projiziert hast (UVs von 0..1). Verwendest du den Unity Standardshader für dein generiertes Mesh, dann sollte die Textur nur 1x aufs Mesh gelegt werden, mit dem Shader oben wird die Textur dann je nach Größe des Objektes und nach "Tiling" entsprechend wiederholt. Ich habe auf die Schnelle keinen Spriteshader anpassen können, daher die "Diffuse"-Shader-Version.
  5. Wenn du kein Array nehmen möchtest, dann nimm doch ein Dictionary: Dictionary<Vector3, GameObject> cubes = new Dictionary<Vector3, GameObject>(); IndexOf(positionToString) ist von der Performance her nicht zu empfehlen.
  6. Ich habe das Include noch einmal geändert, damit auch der Emissionschannel mit einbezogen wird, allerdings merkt man das im Endeffekt so gut wie gar nicht. Der Shader kann gerne nach "Code Snippets" verschoben werden.
  7. Du kannst die Kamera an einem Bone ausrichten aber nicht andersherum. Was du möchtest, dafür verwendet man: https://docs.unity3d...Kinematics.html Das IK-Target wird dann in Richtung der Blickrichtung der Kamera verschoben.
  8. Ich habe mal einen Shader (kein Spriteshader) zusammengebastelt, der funktioniert aber nur mit normalen Texturen und diese müssen auf "Repeat" gestellt werden. Zum Testen kann man den mal auf ein Quad ziehen. Die Kacheln bleiben dabei in ihrer Größe konstant, egal wie man die Größe des Meshes verändert. Über Tiling kann man die Größe der Kacheln festlegen: Shader "Legacy Shaders/SpriteTiled" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} _Tiling("Textur Tiling", Range(0,100)) = 1 } SubShader { Tags { "RenderType"="Opaque" } LOD 250 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; sampler2D _DecalTex; fixed4 _Color; float _Tiling; struct Input { float2 uv_MainTex; float2 uv_DecalTex; }; void surf (Input IN, inout SurfaceOutput o) { float2 tiledUv = mul(unity_ObjectToWorld, float4(IN.uv_MainTex*_Tiling, 0, 0)).xy; fixed4 c = tex2D(_MainTex, tiledUv); c *= _Color; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } Fallback "Legacy Shaders/Diffuse" }
  9. Bin mir nicht sicher, ob ich die Frage verstehe und ob dein Video nun der gewünschte Zustand ist oder nicht. Aber wenn du dein Mesh aufziehst und die UVs nach dem Aufziehen des Meshs neu berechnest, dann sollte sich die Größe der Textur nicht ändern. Ich vermute, du darfst die UVs nicht über den gesamten Mesh ziehen und die Textur musst du beim Import auf Repeat stellen. Ansonsten hilft eventuell solch ein Shader, d.h. ein Shader der sich nicht direkt nach den UVs des Meshes richtet: https://www.assetsto...!/content/20333 Oder man steuert das Texturscaling über eine Skript nach: http://answers.unity3d.com/questions/517555/texture-tiling-based-on-object-sizescale.html
  10. So ich habe das Lichtproblem gelöst, war noch einiges an Zusatzarbeit, aber so kann ich den Shader nun auch in meinem Spiel verwenden. Der Shader besteht nun aus 2 Dateien (der Shader selbst und einem Include). Ich gebe diesen Shader für das gesamte Forum frei... Shader "Standard Double Sided.shader": Shader "Standard Double Sided" { // Created by Zer0f0rce (Skype) for Unity Insider Forum // and the Game "Twin Destiny" by Hugin Munin Studios LLC // Version: 5.4.1f1 // Includes UnityStandardCoreDoubleSided.cginc // Only works for the deferred lightning pass Properties { _Color("Color", Color) = (1,1,1,1) _MainTex("Albedo", 2D) = "white" {} _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 [Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0 [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 _MetallicGlossMap("Metallic", 2D) = "white" {} [ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0 _BumpScale("Scale", Float) = 1.0 _BumpMap("Normal Map", 2D) = "bump" {} _Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02 _ParallaxMap ("Height Map", 2D) = "black" {} _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 _OcclusionMap("Occlusion", 2D) = "white" {} _EmissionColor("Color", Color) = (0,0,0) _EmissionMap("Emission", 2D) = "white" {} _DetailMask("Detail Mask", 2D) = "white" {} _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {} _DetailNormalMapScale("Scale", Float) = 1.0 _DetailNormalMap("Normal Map", 2D) = "bump" {} [Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0 // Blending state [HideInInspector] _Mode ("__mode", Float) = 0.0 [HideInInspector] _SrcBlend ("__src", Float) = 1.0 [HideInInspector] _DstBlend ("__dst", Float) = 0.0 [HideInInspector] _ZWrite ("__zw", Float) = 1.0 } CGINCLUDE #define UNITY_SETUP_BRDF_INPUT MetallicSetup ENDCG SubShader { Tags { "RenderType"="Opaque" "PerformanceChecks"="False" } LOD 300 // ------------------------------------------------------------------ // Base forward pass (directional light, emission, lightmaps, ...) Pass { Name "FORWARD" Tags { "LightMode" = "ForwardBase" } Blend [_SrcBlend] [_DstBlend] ZWrite [_ZWrite] CGPROGRAM #pragma target 3.0 // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF #pragma shader_feature _PARALLAXMAP #pragma multi_compile_fwdbase #pragma multi_compile_fog #pragma vertex vertBase #pragma fragment fragBase #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Additive forward pass (one light per pass) Pass { Name "FORWARD_DELTA" Tags { "LightMode" = "ForwardAdd" } Blend [_SrcBlend] One Fog { Color (0,0,0,0) } // in additive pass fog should be black ZWrite Off ZTest LEqual Cull off CGPROGRAM #pragma target 3.0 // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _PARALLAXMAP #pragma multi_compile_fwdadd_fullshadows #pragma multi_compile_fog #pragma vertex vertAdd #pragma fragment fragAdd #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Shadow rendering pass Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual Cull off CGPROGRAM #pragma target 3.0 // ------------------------------------- #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma multi_compile_shadowcaster #pragma vertex vertShadowCaster #pragma fragment fragShadowCaster #include "UnityStandardShadow.cginc" ENDCG } // ------------------------------------------------------------------ // Deferred pass 1 Pass { Name "DEFERRED" Tags { "LightMode" = "Deferred" } Cull Back ZWrite On ZTest LEqual CGPROGRAM #pragma target 3.0 #pragma exclude_renderers nomrt // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _PARALLAXMAP #pragma multi_compile ___ UNITY_HDR_ON #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON #pragma multi_compile ___ DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON #pragma vertex vertDeferred #pragma fragment fragDeferred #include "UnityStandardCoreDoubleSided.cginc" ENDCG } // ------------------------------------------------------------------ // Deferred pass 2 Pass { Name "DEFERRED" Tags{ "LightMode" = "Deferred" } Cull Front ZWrite On ZTest LEqual CGPROGRAM #pragma target 3.0 #pragma exclude_renderers nomrt // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _PARALLAXMAP #pragma multi_compile ___ UNITY_HDR_ON #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON #pragma multi_compile ___ DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON #pragma vertex vertDeferred #pragma fragment fragDeferredBackSide #include "UnityStandardCoreDoubleSided.cginc" ENDCG } // ------------------------------------------------------------------ // Extracts information for lightmapping, GI (emission, albedo, ...) // This pass it not used during regular rendering. Pass { Name "META" Tags { "LightMode"="Meta" } Cull Off ZWrite On ZTest LEqual CGPROGRAM #pragma vertex vert_meta #pragma fragment frag_meta #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature ___ _DETAIL_MULX2 #include "UnityStandardMeta.cginc" ENDCG } } SubShader { Tags { "RenderType"="Opaque" "PerformanceChecks"="False" } LOD 150 // ------------------------------------------------------------------ // Base forward pass (directional light, emission, lightmaps, ...) Pass { Name "FORWARD" Tags { "LightMode" = "ForwardBase" } Cull off Blend [_SrcBlend] [_DstBlend] ZWrite [_ZWrite] CGPROGRAM #pragma target 2.0 #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF // SM2.0: NOT SUPPORTED shader_feature ___ _DETAIL_MULX2 // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE #pragma multi_compile_fwdbase #pragma multi_compile_fog #pragma vertex vertBase #pragma fragment fragBase #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Additive forward pass (one light per pass) Pass { Name "FORWARD_DELTA" Tags { "LightMode" = "ForwardAdd" } Blend [_SrcBlend] One Fog { Color (0,0,0,0) } // in additive pass fog should be black ZWrite Off ZTest LEqual Cull off CGPROGRAM #pragma target 2.0 #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP #pragma skip_variants SHADOWS_SOFT #pragma multi_compile_fwdadd_fullshadows #pragma multi_compile_fog #pragma vertex vertAdd #pragma fragment fragAdd #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Shadow rendering pass Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual Cull off CGPROGRAM #pragma target 2.0 #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma skip_variants SHADOWS_SOFT #pragma multi_compile_shadowcaster #pragma vertex vertShadowCaster #pragma fragment fragShadowCaster #include "UnityStandardShadow.cginc" ENDCG } // ------------------------------------------------------------------ // Extracts information for lightmapping, GI (emission, albedo, ...) // This pass it not used during regular rendering. Pass { Name "META" Tags { "LightMode"="Meta" } Cull Off ZWrite On ZTest LEqual CGPROGRAM #pragma vertex vert_meta #pragma fragment frag_meta #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature ___ _DETAIL_MULX2 #include "UnityStandardMeta.cginc" ENDCG } } FallBack "VertexLit" CustomEditor "StandardShaderGUI" } Include "UnityStandardCoreDoubleSided.cginc": #include "UnityCG.cginc" #include "UnityShaderVariables.cginc" #include "UnityInstancing.cginc" #include "UnityStandardConfig.cginc" #include "UnityStandardInput.cginc" #include "UnityPBSLighting.cginc" #include "UnityStandardUtils.cginc" #include "UnityStandardBRDF.cginc" #include "AutoLight.cginc" //------------------------------------------------------------------------------------- // counterpart for NormalizePerPixelNormal // skips normalization per-vertex and expects normalization to happen per-pixel half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow { #if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE return normalize(n); #else return n; // will normalize per-pixel instead #endif } half3 NormalizePerPixelNormal (half3 n) { #if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE return n; #else return normalize(n); #endif } //------------------------------------------------------------------------------------- UnityLight MainLight (half3 normalWorld) { UnityLight l; #ifdef LIGHTMAP_OFF l.color = _LightColor0.rgb; l.dir = _WorldSpaceLightPos0.xyz; l.ndotl = LambertTerm (normalWorld, l.dir); #else // no light specified by the engine // analytical light might be extracted from Lightmap data later on in the shader depending on the Lightmap type l.color = half3(0.f, 0.f, 0.f); l.ndotl = 0.f; l.dir = half3(0.f, 0.f, 0.f); #endif return l; } UnityLight AdditiveLight (half3 normalWorld, half3 lightDir, half atten) { UnityLight l; l.color = _LightColor0.rgb; l.dir = lightDir; #ifndef USING_DIRECTIONAL_LIGHT l.dir = NormalizePerPixelNormal(l.dir); #endif l.ndotl = LambertTerm (normalWorld, l.dir); // shadow the light l.color *= atten; return l; } UnityLight DummyLight (half3 normalWorld) { UnityLight l; l.color = 0; l.dir = half3 (0,1,0); l.ndotl = LambertTerm (normalWorld, l.dir); return l; } UnityIndirect ZeroIndirect () { UnityIndirect ind; ind.diffuse = 0; ind.specular = 0; return ind; } //------------------------------------------------------------------------------------- // Common fragment setup // deprecated half3 WorldNormal(half4 tan2world[3]) { return normalize(tan2world[2].xyz); } // deprecated #ifdef _TANGENT_TO_WORLD half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3]) { half3 t = tan2world[0].xyz; half3 b = tan2world[1].xyz; half3 n = tan2world[2].xyz; #if UNITY_TANGENT_ORTHONORMALIZE n = NormalizePerPixelNormal(n); // ortho-normalize Tangent t = normalize (t - n * dot(t, n)); // recalculate Binormal half3 newB = cross(n, t); b = newB * sign (dot (newB, ); #endif return half3x3(t, b, n); } #else half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3]) { return half3x3(0,0,0,0,0,0,0,0,0); } #endif half3 PerPixelWorldNormal(float4 i_tex, half4 tangentToWorld[3]) { #ifdef _NORMALMAP half3 tangent = tangentToWorld[0].xyz; half3 binormal = tangentToWorld[1].xyz; half3 normal = tangentToWorld[2].xyz; #if UNITY_TANGENT_ORTHONORMALIZE normal = NormalizePerPixelNormal(normal); // ortho-normalize Tangent tangent = normalize (tangent - normal * dot(tangent, normal)); // recalculate Binormal half3 newB = cross(normal, tangent); binormal = newB * sign (dot (newB, binormal)); #endif half3 normalTangent = NormalInTangentSpace(i_tex); half3 normalWorld = NormalizePerPixelNormal(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z); // @TODO: see if we can squeeze this normalize on SM2.0 as well #else half3 normalWorld = normalize(tangentToWorld[2].xyz); #endif return normalWorld; } #ifdef _PARALLAXMAP #define IN_VIEWDIR4PARALLAX(i) NormalizePerPixelNormal(half3(i.tangentToWorldAndParallax[0].w,i.tangentToWorldAndParallax[1].w,i.tangentToWorldAndParallax[2].w)) #define IN_VIEWDIR4PARALLAX_FWDADD(i) NormalizePerPixelNormal(i.viewDirForParallax.xyz) #else #define IN_VIEWDIR4PARALLAX(i) half3(0,0,0) #define IN_VIEWDIR4PARALLAX_FWDADD(i) half3(0,0,0) #endif #if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME #define IN_WORLDPOS(i) i.posWorld #else #define IN_WORLDPOS(i) half3(0,0,0) #endif #define IN_LIGHTDIR_FWDADD(i) half3(i.tangentToWorldAndLightDir[0].w, i.tangentToWorldAndLightDir[1].w, i.tangentToWorldAndLightDir[2].w) #define FRAGMENT_SETUP(x) FragmentCommonData x = \ FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX(i), i.tangentToWorldAndParallax, IN_WORLDPOS(i)); #define FRAGMENT_SETUP_FWDADD(x) FragmentCommonData x = \ FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX_FWDADD(i), i.tangentToWorldAndLightDir, half3(0,0,0)); struct FragmentCommonData { half3 diffColor, specColor; // Note: oneMinusRoughness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level. // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots. half oneMinusReflectivity, oneMinusRoughness; half3 normalWorld, eyeVec, posWorld; half alpha; #if UNITY_OPTIMIZE_TEXCUBELOD || UNITY_STANDARD_SIMPLE half3 reflUVW; #endif #if UNITY_STANDARD_SIMPLE half3 tangentSpaceNormal; #endif }; #ifndef UNITY_SETUP_BRDF_INPUT #define UNITY_SETUP_BRDF_INPUT SpecularSetup #endif inline FragmentCommonData SpecularSetup (float4 i_tex) { half4 specGloss = SpecularGloss(i_tex.xy); half3 specColor = specGloss.rgb; half oneMinusRoughness = specGloss.a; half oneMinusReflectivity; half3 diffColor = EnergyConservationBetweenDiffuseAndSpecular (Albedo(i_tex), specColor, /*out*/ oneMinusReflectivity); FragmentCommonData o = (FragmentCommonData)0; o.diffColor = diffColor; o.specColor = specColor; o.oneMinusReflectivity = oneMinusReflectivity; o.oneMinusRoughness = oneMinusRoughness; return o; } inline FragmentCommonData MetallicSetup (float4 i_tex) { half2 metallicGloss = MetallicGloss(i_tex.xy); half metallic = metallicGloss.x; half oneMinusRoughness = metallicGloss.y; // this is 1 minus the square root of real roughness m. half oneMinusReflectivity; half3 specColor; half3 diffColor = DiffuseAndSpecularFromMetallic (Albedo(i_tex), metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity); FragmentCommonData o = (FragmentCommonData)0; o.diffColor = diffColor; o.specColor = specColor; o.oneMinusReflectivity = oneMinusReflectivity; o.oneMinusRoughness = oneMinusRoughness; return o; } inline FragmentCommonData FragmentSetup (float4 i_tex, half3 i_eyeVec, half3 i_viewDirForParallax, half4 tangentToWorld[3], half3 i_posWorld) { i_tex = Parallax(i_tex, i_viewDirForParallax); half alpha = Alpha(i_tex.xy); #if defined(_ALPHATEST_ON) clip (alpha - _Cutoff); #endif FragmentCommonData o = UNITY_SETUP_BRDF_INPUT (i_tex); o.normalWorld = PerPixelWorldNormal(i_tex, tangentToWorld); o.eyeVec = NormalizePerPixelNormal(i_eyeVec); o.posWorld = i_posWorld; // NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha) o.diffColor = PreMultiplyAlpha (o.diffColor, alpha, o.oneMinusReflectivity, /*out*/ o.alpha); return o; } inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections) { UnityGIInput d; d.light = light; d.worldPos = s.posWorld; d.worldViewDir = -s.eyeVec; d.atten = atten; #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON) d.ambient = 0; d.lightmapUV = i_ambientOrLightmapUV; #else d.ambient = i_ambientOrLightmapUV.rgb; d.lightmapUV = 0; #endif d.boxMax[0] = unity_SpecCube0_BoxMax; d.boxMin[0] = unity_SpecCube0_BoxMin; d.probePosition[0] = unity_SpecCube0_ProbePosition; d.probeHDR[0] = unity_SpecCube0_HDR; d.boxMax[1] = unity_SpecCube1_BoxMax; d.boxMin[1] = unity_SpecCube1_BoxMin; d.probePosition[1] = unity_SpecCube1_ProbePosition; d.probeHDR[1] = unity_SpecCube1_HDR; if(reflections) { Unity_GlossyEnvironmentData g; g.roughness = 1 - s.oneMinusRoughness; #if UNITY_OPTIMIZE_TEXCUBELOD || UNITY_STANDARD_SIMPLE g.reflUVW = s.reflUVW; #else g.reflUVW = reflect(s.eyeVec, s.normalWorld); #endif return UnityGlobalIllumination (d, occlusion, s.normalWorld, g); } else { return UnityGlobalIllumination (d, occlusion, s.normalWorld); } } inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light) { return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, true); } //------------------------------------------------------------------------------------- half4 OutputForward (half4 output, half alphaFromSurface) { #if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON) output.a = alphaFromSurface; #else UNITY_OPAQUE_ALPHA(output.a); #endif return output; } inline half4 VertexGIForward(VertexInput v, float3 posWorld, half3 normalWorld) { half4 ambientOrLightmapUV = 0; // Static lightmaps #ifndef LIGHTMAP_OFF ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; ambientOrLightmapUV.zw = 0; // Sample light probe for Dynamic objects only (no static or dynamic lightmaps) #elif UNITY_SHOULD_SAMPLE_SH #ifdef VERTEXLIGHT_ON // Approximated illumination from non-important point lights ambientOrLightmapUV.rgb = Shade4PointLights ( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, posWorld, normalWorld); #endif ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, ambientOrLightmapUV.rgb); #endif #ifdef DYNAMICLIGHTMAP_ON ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif return ambientOrLightmapUV; } // ------------------------------------------------------------------ // Base forward pass (directional light, emission, lightmaps, ...) struct VertexOutputForwardBase { float4 pos : SV_POSITION; float4 tex : TEXCOORD0; half3 eyeVec : TEXCOORD1; half4 tangentToWorldAndParallax[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV SHADOW_COORDS(6) UNITY_FOG_COORDS(7) // next ones would not fit into SM2.0 limits, but they are always for SM3.0+ #if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME float3 posWorld : TEXCOORD8; #endif #if UNITY_OPTIMIZE_TEXCUBELOD #if UNITY_SPECCUBE_BOX_PROJECTION half3 reflUVW : TEXCOORD9; #else half3 reflUVW : TEXCOORD8; #endif #endif UNITY_VERTEX_OUTPUT_STEREO }; VertexOutputForwardBase vertForwardBase (VertexInput v) { UNITY_SETUP_INSTANCE_ID(v); VertexOutputForwardBase o; UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float4 posWorld = mul(unity_ObjectToWorld, v.vertex); #if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME o.posWorld = posWorld.xyz; #endif o.pos = UnityObjectToClipPos(v.vertex); o.tex = TexCoords(v); o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); float3 normalWorld = UnityObjectToWorldNormal(v.normal); #ifdef _TANGENT_TO_WORLD float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0]; o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1]; o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2]; #else o.tangentToWorldAndParallax[0].xyz = 0; o.tangentToWorldAndParallax[1].xyz = 0; o.tangentToWorldAndParallax[2].xyz = normalWorld; #endif //We need this for shadow receving TRANSFER_SHADOW(o); o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld); #ifdef _PARALLAXMAP TANGENT_SPACE_ROTATION; half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex)); o.tangentToWorldAndParallax[0].w = viewDirForParallax.x; o.tangentToWorldAndParallax[1].w = viewDirForParallax.y; o.tangentToWorldAndParallax[2].w = viewDirForParallax.z; #endif #if UNITY_OPTIMIZE_TEXCUBELOD o.reflUVW = reflect(o.eyeVec, normalWorld); #endif UNITY_TRANSFER_FOG(o,o.pos); return o; } half4 fragForwardBaseInternal (VertexOutputForwardBase i) { FRAGMENT_SETUP(s) #if UNITY_OPTIMIZE_TEXCUBELOD s.reflUVW = i.reflUVW; #endif UnityLight mainLight = MainLight (s.normalWorld); half atten = SHADOW_ATTENUATION(i); half occlusion = Occlusion(i.tex.xy); UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, mainLight); half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect); c.rgb += UNITY_BRDF_GI (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, occlusion, gi); c.rgb += Emission(i.tex.xy); UNITY_APPLY_FOG(i.fogCoord, c.rgb); return OutputForward (c, s.alpha); } half4 fragForwardBase (VertexOutputForwardBase i) : SV_Target // backward compatibility (this used to be the fragment entry function) { return fragForwardBaseInternal(i); } // ------------------------------------------------------------------ // Additive forward pass (one light per pass) struct VertexOutputForwardAdd { float4 pos : SV_POSITION; float4 tex : TEXCOORD0; half3 eyeVec : TEXCOORD1; half4 tangentToWorldAndLightDir[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:lightDir] LIGHTING_COORDS(5,6) UNITY_FOG_COORDS(7) // next ones would not fit into SM2.0 limits, but they are always for SM3.0+ #if defined(_PARALLAXMAP) half3 viewDirForParallax : TEXCOORD8; #endif UNITY_VERTEX_OUTPUT_STEREO }; VertexOutputForwardAdd vertForwardAdd (VertexInput v) { VertexOutputForwardAdd o; UNITY_INITIALIZE_OUTPUT(VertexOutputForwardAdd, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float4 posWorld = mul(unity_ObjectToWorld, v.vertex); o.pos = UnityObjectToClipPos(v.vertex); o.tex = TexCoords(v); o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); float3 normalWorld = UnityObjectToWorldNormal(v.normal); #ifdef _TANGENT_TO_WORLD float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); o.tangentToWorldAndLightDir[0].xyz = tangentToWorld[0]; o.tangentToWorldAndLightDir[1].xyz = tangentToWorld[1]; o.tangentToWorldAndLightDir[2].xyz = tangentToWorld[2]; #else o.tangentToWorldAndLightDir[0].xyz = 0; o.tangentToWorldAndLightDir[1].xyz = 0; o.tangentToWorldAndLightDir[2].xyz = normalWorld; #endif //We need this for shadow receiving TRANSFER_VERTEX_TO_FRAGMENT(o); float3 lightDir = _WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w; #ifndef USING_DIRECTIONAL_LIGHT lightDir = NormalizePerVertexNormal(lightDir); #endif o.tangentToWorldAndLightDir[0].w = lightDir.x; o.tangentToWorldAndLightDir[1].w = lightDir.y; o.tangentToWorldAndLightDir[2].w = lightDir.z; #ifdef _PARALLAXMAP TANGENT_SPACE_ROTATION; o.viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex)); #endif UNITY_TRANSFER_FOG(o,o.pos); return o; } half4 fragForwardAddInternal (VertexOutputForwardAdd i) { FRAGMENT_SETUP_FWDADD(s) UnityLight light = AdditiveLight (s.normalWorld, IN_LIGHTDIR_FWDADD(i), LIGHT_ATTENUATION(i)); UnityIndirect noIndirect = ZeroIndirect (); half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, light, noIndirect); UNITY_APPLY_FOG_COLOR(i.fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass return OutputForward (c, s.alpha); } half4 fragForwardAdd (VertexOutputForwardAdd i) : SV_Target // backward compatibility (this used to be the fragment entry function) { return fragForwardAddInternal(i); } // ------------------------------------------------------------------ // Deferred pass struct VertexOutputDeferred { float4 pos : SV_POSITION; float4 tex : TEXCOORD0; half3 eyeVec : TEXCOORD1; half4 tangentToWorldAndParallax[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UVs #if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME float3 posWorld : TEXCOORD6; #endif #if UNITY_OPTIMIZE_TEXCUBELOD #if UNITY_SPECCUBE_BOX_PROJECTION half3 reflUVW : TEXCOORD7; #else half3 reflUVW : TEXCOORD6; #endif #endif UNITY_VERTEX_OUTPUT_STEREO }; VertexOutputDeferred vertDeferred (VertexInput v) { UNITY_SETUP_INSTANCE_ID(v); VertexOutputDeferred o; UNITY_INITIALIZE_OUTPUT(VertexOutputDeferred, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float4 posWorld = mul(unity_ObjectToWorld, v.vertex); #if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME o.posWorld = posWorld; #endif o.pos = UnityObjectToClipPos(v.vertex); o.tex = TexCoords(v); o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); float3 normalWorld = UnityObjectToWorldNormal(v.normal); #ifdef _TANGENT_TO_WORLD float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0]; o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1]; o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2]; #else o.tangentToWorldAndParallax[0].xyz = 0; o.tangentToWorldAndParallax[1].xyz = 0; o.tangentToWorldAndParallax[2].xyz = normalWorld; #endif o.ambientOrLightmapUV = 0; #ifndef LIGHTMAP_OFF o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #elif UNITY_SHOULD_SAMPLE_SH o.ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, o.ambientOrLightmapUV.rgb); #endif #ifdef DYNAMICLIGHTMAP_ON o.ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif #ifdef _PARALLAXMAP TANGENT_SPACE_ROTATION; half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex)); o.tangentToWorldAndParallax[0].w = viewDirForParallax.x; o.tangentToWorldAndParallax[1].w = viewDirForParallax.y; o.tangentToWorldAndParallax[2].w = viewDirForParallax.z; #endif #if UNITY_OPTIMIZE_TEXCUBELOD o.reflUVW = reflect(o.eyeVec, normalWorld); #endif return o; } void fragDeferred ( VertexOutputDeferred i, out half4 outDiffuse : SV_Target0, // RT0: diffuse color (rgb), occlusion (a) out half4 outSpecSmoothness : SV_Target1, // RT1: spec color (rgb), smoothness (a) out half4 outNormal : SV_Target2, // RT2: normal (rgb), --unused, very low precision-- (a) out half4 outEmission : SV_Target3 // RT3: emission (rgb), --unused-- (a) ) { #if (SHADER_TARGET < 30) outDiffuse = 1; outSpecSmoothness = 1; outNormal = 0; outEmission = 0; return; #endif FRAGMENT_SETUP(s) #if UNITY_OPTIMIZE_TEXCUBELOD s.reflUVW = i.reflUVW; #endif // no analytic lights in this pass UnityLight dummyLight = DummyLight (s.normalWorld); half atten = 1; // only GI half occlusion = Occlusion(i.tex.xy); #if UNITY_ENABLE_REFLECTION_BUFFERS bool sampleReflectionsInDeferred = false; #else bool sampleReflectionsInDeferred = true; #endif UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, dummyLight, sampleReflectionsInDeferred); half3 color = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb; color += UNITY_BRDF_GI (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, occlusion, gi); #ifdef _EMISSION color += Emission (i.tex.xy); #endif #ifndef UNITY_HDR_ON color.rgb = exp2(-color.rgb); #endif outDiffuse = half4(s.diffColor, occlusion); outSpecSmoothness = half4(s.specColor, s.oneMinusRoughness); outNormal = half4(s.normalWorld*0.5+0.5,1); outEmission = half4(color, 1); } // Added by Zer0f0rce (Skype) for the Game "Twin Destiny" by Hugin Munin Studios LLC void fragDeferredBackSide( VertexOutputDeferred i, out half4 outDiffuse : SV_Target0, // RT0: diffuse color (rgb), occlusion (a) out half4 outSpecSmoothness : SV_Target1, // RT1: spec color (rgb), smoothness (a) out half4 outNormal : SV_Target2, // RT2: normal (rgb), --unused, very low precision-- (a) out half4 outEmission : SV_Target3 // RT3: emission (rgb), --unused-- (a) ) { #if (SHADER_TARGET < 30) outDiffuse = 1; outSpecSmoothness = 1; outNormal = 0; outEmission = 0; return; #endif FRAGMENT_SETUP(s) #if UNITY_OPTIMIZE_TEXCUBELOD s.reflUVW = i.reflUVW; #endif s.normalWorld = -s.normalWorld; // no analytic lights in this pass UnityLight dummyLight = DummyLight(s.normalWorld); half atten = 1; // only GI half occlusion = Occlusion(i.tex.xy); #if UNITY_ENABLE_REFLECTION_BUFFERS bool sampleReflectionsInDeferred = false; #else bool sampleReflectionsInDeferred = true; #endif UnityGI gi = FragmentGI(s, occlusion, i.ambientOrLightmapUV, atten, dummyLight, sampleReflectionsInDeferred); half3 color = UNITY_BRDF_PBS(s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb; color += UNITY_BRDF_GI(s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, occlusion, gi); #ifdef _EMISSION color += Emission(i.tex.xy); #endif #ifndef UNITY_HDR_ON color.rgb = exp2(-color.rgb); #endif outDiffuse = half4(s.diffColor, occlusion); outSpecSmoothness = half4(s.specColor, s.oneMinusRoughness); outNormal = half4(s.normalWorld*0.5 + 0.5, 1); outEmission = half4(color, 1); s.normalWorld = -s.normalWorld; } // // Old FragmentGI signature. Kept only for backward compatibility and will be removed soon // inline UnityGI FragmentGI( float3 posWorld, half occlusion, half4 i_ambientOrLightmapUV, half atten, half oneMinusRoughness, half3 normalWorld, half3 eyeVec, UnityLight light, bool reflections) { // we init only fields actually used FragmentCommonData s = (FragmentCommonData)0; s.oneMinusRoughness = oneMinusRoughness; s.normalWorld = normalWorld; s.eyeVec = eyeVec; s.posWorld = posWorld; #if UNITY_OPTIMIZE_TEXCUBELOD s.reflUVW = reflect(eyeVec, normalWorld); #endif return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, reflections); } inline UnityGI FragmentGI ( float3 posWorld, half occlusion, half4 i_ambientOrLightmapUV, half atten, half oneMinusRoughness, half3 normalWorld, half3 eyeVec, UnityLight light) { return FragmentGI (posWorld, occlusion, i_ambientOrLightmapUV, atten, oneMinusRoughness, normalWorld, eyeVec, light, true); }
  11. Hab's mal getestet und ich glaube du hast das Sprite in X oder Y gedreht bzw. den Container in dem das Sprite eingebettet ist und damit drehst du das Sprite quasi auf die Rückseite. Ich würde dein Sprite bzw. den Container entsprechend umstellen, so daß du es als Gesamtheit wieder um Z drehen kannst, weil dann ändert sich der Lichteinfall nicht. Das heißt die blaue Achse deines Sprites sollte immer in Richtung vom Bildschirm auf das Sprite zeigen, tut sie das nicht (ist meine Vermutung), dann ist in deinem Transform oder dem Container was verdreht und das solltest du korrigieren. Ist alles korrigiert, dann kannst du den ganzen Container auch wieder um Z drehen, ohne das sich der Lichteinfall ändert. PS: Habs gerade gemerkt, daß dir die Drehung um Z so nichts bringt, dann hilft dir hier nur "Flip" weiter oder ein anderer Shader.
  12. Es hat alles Vor- und Nachteile. Wenn man die Laufbewegung über die Rootmotions bewerkstelligen möchte, ist es am besten, man hat mehrere Laufanimationen für die verschiedenen Geschwindigkeiten, Gehen, langsames Laufen, schnelles Laufen und man verwendet einen Blendtree um sanft zwischen diesen Animationen zu überblenden. Steuert man die Bewegung des Charakters über einen Rigidbody oder Transform, so muss man sehr darauf achten, daß die Geschwindigkeit des Charakters zu den Geschwindigkeiten der Animationen bzw. die Parameter des Blendtree's und der Blendtree selbst entsprechend eingestellt sind, oft entsteht hier eine Art "Moonwalk", wenn diese nicht exakt zueinander passen. Kurzum, wenn man mit Rootmotions arbeitet, vermeidet man dieses Problem (aber man braucht eben entsprechend gute und variable Animationen: Laufen vorwärts, Laufen zur Seite, Laufen nach Links etc.).
  13. Hatte ich ja oben bereits geschrieben, aber gut zu wissen welche der 3 Varianten es war
  14. Wundert mich, das eurer Charakter keine Rootmotion besitzen soll. Prüfe die Einstellungen mal bei den Import Settings unter Animations: Root Transform XZ - "Bake Into Pose" sollte nicht angehakt sein Im Animator sollte dann bei Apply Root Motion ein Haken sein. Ansonsten, wenn dein Charakter einen Rigidbody besitzt (ich kenne den Etan-Controller nicht), dann müsstest du die Position über: https://docs.unity3d...vePosition.html und die Rotation über: https://docs.unity3d...veRotation.html entsprechend dem Playerinput anpassen. Sollte der nicht vorhanden sein, dann reicht es, wenn du die Position und die Rotation des Transforms entsprechend anpasst.
  15. Ich hab mal ein paar Tests damit gemacht, "Lightning" könnte besser sein bei meinem verwendeten Modell. Es könnte sein, daß die Lichtberechnungen beim Unity-Standardshader nicht mit Backfaces gut funktionieren, vielleicht fehlt bei mir auch eine gute Reflektiontextur, wie gesagt war nur ein schneller Versuch den Standardshader umzubiegen, vielleicht reicht er für deine Fälle Ich habe bei mir auch einen Rock am Player befestigt, aber leider sind die Clothrenderersettings teilweise extrem empfindlich (die gesetzten Constraints scheinen sich ab und an "seltsam" zu verstellen). Im Prinzip ist es aber bei mir wie folgt gelöst: - die oberen 3 Reihen des Rocksaumes sind mit "max distance" und "surface penetration" auf 0 fixiert - eine Übergangsreihe des Rocksaumes ist mit "max distance" 0.2 und "surface penetration" auf 0 fixiert (- mögliche weitere Übergangsreihen wären distance 0.4 (+0.2) und surface penetration auf 0) - alle weiteren unten Rock-Verticesreihen sind nur noch mit "surface penetration" auf 0 fixiert