Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

GLTFUtility - A simple glTF plugin

Discussion in 'Assets and Asset Store' started by Siccity, Apr 1, 2019.

  1. jhocking-bundlar

    jhocking-bundlar

    Joined:
    Nov 12, 2019
    Posts:
    24
    On another subject, I noticed the "Loop Time" setting on animation clips can't be toggled (to make animations loop, natch) because it's visible but greyed out. I did eventually figure out how to toggle that in the editor, but it involves an annoying amount of code and if there's a simpler way to make animations loop with your plugin then please tell me and ignore the rest of this post.

    Assuming I'm not missing something simple, I found that you can toggle that in the editor (it depends on the UnityEditor namespace unfortunately, so no runtime manipulation of this setting) with this code:
    https://forum.unity.com/threads/accessing-loop-time-through-c.218649/#post-2971360

    Of course it'd be annoying to have to do that in code if you're manually importing gltf models, so I wrote an editor script as described here:
    https://titanwolf.org/Network/Articles/Article?AID=10fd28c7-4f45-494a-8d5e-d7f787ea8009#gsc.tab=0
    https://answers.unity.com/questions/1327614/how-to-get-the-currently-selected-object-in-the-pr.html

    You may want to add this script in your plugin to add these menu functions to Unity:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. namespace Siccity.GLTFUtility
    5. {
    6.     public class GLTFAnimMenu
    7.     {
    8.         [MenuItem("Tools/GLTFUtility/Loop = true")]
    9.         static void LoopTrue()
    10.         {
    11.             var clip = Selection.activeObject as AnimationClip;
    12.             if (clip == null)
    13.             {
    14.                 Debug.LogError("Select an animation clip to use this function.");
    15.                 return;
    16.             }
    17.             var settings = AnimationUtility.GetAnimationClipSettings(clip);
    18.             settings.loopTime = true;
    19.             AnimationUtility.SetAnimationClipSettings(clip, settings);
    20.         }
    21.  
    22.         [MenuItem("Tools/GLTFUtility/Loop = False")]
    23.         static void LoopFalse()
    24.         {
    25.             var clip = Selection.activeObject as AnimationClip;
    26.             if (clip == null)
    27.             {
    28.                 Debug.LogError("Select an animation clip to use this function.");
    29.                 return;
    30.             }
    31.             var settings = AnimationUtility.GetAnimationClipSettings(clip);
    32.             settings.loopTime = false;
    33.             AnimationUtility.SetAnimationClipSettings(clip, settings);
    34.         }
    35.     }
    36. }
    37.  

    ADDITION: To set looping automatically on all imported models use this editor script
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. class GLBPostprocessor : AssetPostprocessor
    4. {
    5.     static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    6.     {
    7.         foreach (string path in importedAssets)
    8.         {
    9.             // Only operate on glb files
    10.             if (path.IndexOf(".glb") == -1)
    11.             {
    12.                 continue;
    13.             }
    14.             var assets = AssetDatabase.LoadAllAssetsAtPath(path);
    15.             foreach (var asset in assets)
    16.             {
    17.                 var clip = asset as AnimationClip;
    18.                 if (clip != null)
    19.                 {
    20.                     var settings = AnimationUtility.GetAnimationClipSettings(clip);
    21.                     settings.loopTime = true;
    22.                     AnimationUtility.SetAnimationClipSettings(clip, settings);
    23.                 }
    24.             }
    25.         }
    26.     }
    27. }
    28.  
     
    Last edited: Nov 12, 2020
    Siccity likes this.
  2. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    281
    Hey, this looks really cool !
    Just wondering what the status is on runtime export ?
     
  3. viveadam

    viveadam

    Joined:
    May 4, 2020
    Posts:
    5
    Hey just wanted to say this thing rules! I wanted to check out a simple glTF file in Unity and everything just worked. Plus it spit out some nice textures based on the custom material I made in Blender.
     
    Siccity likes this.
  4. Siccity

    Siccity

    Joined:
    Dec 7, 2013
    Posts:
    245
    Thanks! I added some basic per-file loop setting (not per-animation yet)

    I am currently occupied with other projects, so probably not soon.

    Thanks! :)
     
  5. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    792
    I would be concerned about people thinking they can set that for runtime loading though, since it's exposed through the ImportSettings object. Which incidentally is a limitation I asked about in a separate thread that hopefully someone from Unity notices; it seems dumb that you can't make an animation clip loop outside the editor:
    https://forum.unity.com/threads/feature-request-edit-loop-setting-at-runtime.1004655/

    On a separate topic, I've noticed an animation glitch that maybe you know how to address? The model/animation is this one:


    The animation looks correct both on Sketchfab and https://gltf-viewer.donmccurdy.com/ but has a significant glitch in Unity. The first joint in the stem flips around pretty wildly; it looks like that joint is going back and forth between just under and just over 360 degrees, and instead of making the small rotation to 361 it's flipping around to 1.

    Here's the gltf file if you want to take a look:
    https://drive.google.com/file/d/1Kc6IHFDxspqS8Mon7KLdre8V0GPWmaV3/view?usp=sharing
     
    Siccity likes this.
  6. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    83
    Hello veryone!!

    First things first, Thank you @Siccity for such a great Library.

    Then, I'm kind of new on the gLTF files, I have things working so far using this library and testing with some gLTF files on Editor.

    My questions is what are the pros and cons of "Single thread" and "Multithread" Run time import? Does the use depends on the gLTF file? I kind of confuse in here.

    have you tried Multithread on Android or IOS?
     
    WylieFoxxx likes this.
  7. BenrajSD

    BenrajSD

    Joined:
    Dec 17, 2020
    Posts:
    6
    Hi, I am using GltfUtility to import glb files into unity, I am having vast difference in colors and metalic properties of materials as compared with it's source file in blender and in gltf web viewer. Please do find the screenshots attached, what could be the issue and the solution for it.
     

    Attached Files:

  8. Siccity

    Siccity

    Joined:
    Dec 7, 2013
    Posts:
    245
    It could be your HDRI map. Reflections have a big impact on how metallic surfaces look. Could also be texture color mode, or post processing, or just the fact that blender and unity do not use the same renderer.
     
  9. BenrajSD

    BenrajSD

    Joined:
    Dec 17, 2020
    Posts:
    6
    Though I have removed entire light, HDRI map, same issue. There is a huge difference how material values got manipulated comparing glb and fbx, is there any option to make it some more realistic as like in gltf web view https://gltf-viewer.donmccurdy.com/
     

    Attached Files:

  10. WylieFoxxx

    WylieFoxxx

    Joined:
    Oct 27, 2016
    Posts:
    1
    Thanks a ton for the amazing plugin!

    I can confirm the multithreaded, async approach works wonders and keeps the program from freezing while loading large models... which is awesome compared to a lot of other object importing plugins out there.

    One thing our team is weary of at the moment, however, is this plugin's performance on the Hololens 2. Can anyone confirm this plugin works with MRTK on Hololens 2?
     
    Siccity likes this.
  11. radicalrhinorider

    radicalrhinorider

    Joined:
    Sep 29, 2020
    Posts:
    4
    Hey Siccity, amazing plugin. We are using ImportGLBAsync() to load glb files from our server at runtime inside our unity MRTK environment. So pleased. Thank you for writing this library, truly.

    The only issue I'm facing now, is after compressing a glb with draco compression on our server using gltf-pipeline, the model will not show up on our IOS device. No error logs or anything, just an invisible object within our scene. However, the compressed glb's show up just fine on our Android device as well as the unity editor.

    Do you or anyone know a possible cause of this and anything we might be able to try? In the meantime, we are just turning off our draco compression and leaving the glb files as is, but it would be amazing to be able to use the compressed files at their much smaller file size on IOS. Thank you for any insights!
     
  12. jhocking-bundlar

    jhocking-bundlar

    Joined:
    Nov 12, 2019
    Posts:
    24
    hm I just had a thought, the importer probably needs support for Mecanim's Humanoid rig type. I'll dig a bit more into this issue shortly, for now just tossing out this thought.
     
    Siccity likes this.
  13. radicalrhinorider

    radicalrhinorider

    Joined:
    Sep 29, 2020
    Posts:
    4
    Thank you for looking into this. I look forward to any insights you dig up!
     
  14. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    792
    (I meant to respond to this post months ago, but uh better late than never right)

    So first off, note that transparency is a headache for 3D graphics in general (especially realtime 3D, although frankly it's a thorn for offline rendering too) not just a Unity problem. Like, this character model also looks pretty screwy in the don mccurdy gltf viewer, and that's sort of seen as a baseline standard for gltf support.

    It just comes down to the specific shader Sketchfab is applying to that model's material on their site. I whipped up a shader that I think does the same things as theirs (the end effect certainly looks the same). Create a material, set it to this shader, drag the texture into the material, and then assign that material to the model (make sure to get both body and hair meshes):

    Code (CSharp):
    1. // addresses https://forum.unity.com/threads/gltfutility-a-simple-gltf-plugin.654319/page-3#post-6041123
    2.  
    3. // relevant documentation:
    4. // https://docs.unity3d.com/Manual/SL-Blend.html
    5. // https://docs.unity3d.com/Manual/SL-CullAndDepth.html
    6. // https://forum.unity.com/threads/function-of-the-clip-command.93179/
    7. // clip() is basically the same as 'discard' https://learnopengl.com/Advanced-OpenGL/Blending
    8. // https://answers.unity.com/questions/1242982/discard-pixels-from-fragment-shader-based-on-scree.html
    9.  
    10. // if you don't want 'float4 _MainTex_ST;' and TRANSFORM_TEX(v.uv, _MainTex);
    11. // https://docs.unity3d.com/ScriptReference/MaterialProperty.PropFlags.NoScaleOffset.html
    12.  
    13. Shader "Custom/UnlitTransparentWithDepth" {
    14.  
    15.     Properties {
    16.         [NoScaleOffset] _MainTex ("Albedo (RGB)", 2D) = "white" {}
    17.     }
    18.  
    19.     // multiple render passes, in order to write to the zbuffer before drawing visible surfaces
    20.     SubShader {
    21.         Tags {
    22.             "Queue" = "Transparent"
    23.         }
    24.  
    25.         Pass {
    26.             ZWrite On
    27.             Cull Off // make double sided
    28.             ColorMask 0 // don't draw any color
    29.  
    30.             CGPROGRAM
    31.             #pragma vertex vert
    32.             #pragma fragment frag
    33.  
    34.             #include "UnityCG.cginc"
    35.  
    36.             struct appdata
    37.             {
    38.                 float4 vertex : POSITION;
    39.                 float2 uv : TEXCOORD0;
    40.             };
    41.  
    42.             struct v2f
    43.             {
    44.                 float2 uv : TEXCOORD0;
    45.                 float4 vertex : SV_POSITION;
    46.             };
    47.  
    48.             sampler2D _MainTex;
    49.  
    50.             v2f vert (appdata v)
    51.             {
    52.                 v2f o;
    53.                 o.vertex = UnityObjectToClipPos(v.vertex);
    54.                 o.uv = v.uv; // just pass through with no scale/offset
    55.                 return o;
    56.             }
    57.  
    58.             fixed4 frag (v2f i) : SV_Target
    59.             {
    60.                 fixed4 col = tex2D(_MainTex, i.uv);
    61.                 clip(col.a - .97); // remove non-opaque pixels from writing to zbuffer
    62.                 return col;
    63.             }
    64.             ENDCG
    65.         }
    66.  
    67.         Pass
    68.         {
    69.             ZWrite Off
    70.             Cull Off // make double sided
    71.             Blend SrcAlpha OneMinusSrcAlpha
    72.  
    73.             CGPROGRAM
    74.             #pragma vertex vert
    75.             #pragma fragment frag
    76.  
    77.             #include "UnityCG.cginc"
    78.  
    79.             struct appdata
    80.             {
    81.                 float4 vertex : POSITION;
    82.                 float2 uv : TEXCOORD0;
    83.             };
    84.  
    85.             struct v2f
    86.             {
    87.                 float2 uv : TEXCOORD0;
    88.                 float4 vertex : SV_POSITION;
    89.             };
    90.  
    91.             sampler2D _MainTex;
    92.  
    93.             v2f vert (appdata v)
    94.             {
    95.                 v2f o;
    96.                 o.vertex = UnityObjectToClipPos(v.vertex);
    97.                 o.uv = v.uv; // just pass through with no scale/offset
    98.                 return o;
    99.             }
    100.  
    101.             fixed4 frag (v2f i) : SV_Target
    102.             {
    103.                 fixed4 col = tex2D(_MainTex, i.uv);
    104.                 return col;
    105.             }
    106.             ENDCG
    107.         }
    108.     }
    109. }
    110.  
    The majority of that code is basically shader boilerplate for rendering a textured object. It's written as a fragment shader (rather than a Surface shader) so that it'll be unlit. I'll just explain the tricks specific to this situation, of rendering this model's transparency.

    Most importantly, note that there are two rendering passes, one with ZWrite on and one with ZWrite off. The first pass simply draws to the depth buffer and (thanks to the ColorMask) doesn't actually draw anything visible. The second pass will still test against the zbuffer, even though it isn't writing, and because of the first pass there will be depth values for this model.

    If you're wondering why we need to write depth values and color values in separate passes, as opposed to a single pass that renders both, it's because rendering transparency requires rendering on top of previously drawn polygons. Indeed, this is why the default transparency rendering behavior doesn't do the first pass of depth values, and only does the second pass of color values.

    And again, that part is not unique to Unity, but rather is pretty common for realtime 3D graphics, and usually it's just on the game's artists to make sure the assets in the game are designed around that limitation. As pointed out on Sketchfab's blog about how their transparency settings work (I reverse engineered the shader from this description) "Blending mode is slow". Doing the extra rendering pass is worth it for things that need the improved depth sorting, but it's better for performance if the game only does one rendering pass.

    Now notice the line clip() in the first pass. That means "discard this fragment if the alpha is less than 1". That means only fully opaque pixels will write to the zbuffer. You still incur the cost of a texture lookup here, but this improves the visuals immensely by not including transparent parts in the zbuffer. If transparent parts were in the zbuffer, the final rendering would have unsightly holes in the model. Incidentally, if the alpha channel of the texture had lots of semi-transparency then it might not look great (since all those areas would be missing from the zbuffer) but the texture in this case only has hard edged cutouts

    After that trickery in the first pass, the second pass sets up alpha transparency with the Blend. Oh and both passes need "Cull Off" since this model has a lot of polygons that need to render double sided (not a great idea to model in a way that prohibits backface culling, but hey this is the model we've got).
     
    Last edited: Mar 1, 2021
    TheJavierD and DerrickBarra like this.
  15. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    792
    Since that was an unlit shader in my last post, I decided to make a Surface shader version to have one that handles lighting too.

    Code (CSharp):
    1. // surface shader version of https://forum.unity.com/threads/gltfutility-a-simple-gltf-plugin.654319/page-4#post-6854009
    2.  
    3. // how to enable transparency for surface shaders
    4. // https://forum.unity.com/threads/transparency-with-standard-surface-shader.394551/
    5. // https://forum.unity.com/threads/simply-adding-alpha-fade-makes-my-shader-only-work-in-scene-view.546852/
    6.  
    7. Shader "Custom/LitTransparentWithDepth"
    8. {
    9.     Properties
    10.     {
    11.         _Color ("Color", Color) = (1,1,1,1)
    12.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    13.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    14.         _Metallic ("Metallic", Range(0,1)) = 0.0
    15.     }
    16.     SubShader
    17.     {
    18.         Tags { "Queue" = "Transparent" "RenderType"="Transparent" }
    19.         LOD 200
    20.  
    21.         Pass {
    22.             ZWrite On
    23.             //Cull Off // make double sided
    24.             ColorMask 0 // don't draw any color
    25.  
    26.             CGPROGRAM
    27.             #pragma vertex vert
    28.             #pragma fragment frag
    29.  
    30.             #include "UnityCG.cginc"
    31.  
    32.             struct appdata
    33.             {
    34.                 float4 vertex : POSITION;
    35.                 float2 uv : TEXCOORD0;
    36.             };
    37.  
    38.             struct v2f
    39.             {
    40.                 float2 uv : TEXCOORD0;
    41.                 float4 vertex : SV_POSITION;
    42.             };
    43.  
    44.             sampler2D _MainTex;
    45.             float4 _MainTex_ST;
    46.  
    47.             v2f vert (appdata v)
    48.             {
    49.                 v2f o;
    50.                 o.vertex = UnityObjectToClipPos(v.vertex);
    51.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    52.                 return o;
    53.             }
    54.  
    55.             fixed4 frag (v2f i) : SV_Target
    56.             {
    57.                 fixed4 col = tex2D(_MainTex, i.uv);
    58.                 clip(col.a - .97); // remove non-opaque pixels from writing to zbuffer
    59.                 return col;
    60.             }
    61.             ENDCG
    62.         }
    63.  
    64.         // ---------- Start Pass 2 ----------
    65.         ZWrite Off
    66.         //Cull Off // make double sided
    67.         Blend SrcAlpha OneMinusSrcAlpha
    68.  
    69.         CGPROGRAM
    70.         // Physically based Standard lighting model, and enable shadows on all light types
    71.         #pragma surface surf Standard fullforwardshadows alpha:fade
    72.  
    73.         // Use shader model 3.0 target, to get nicer looking lighting
    74.         #pragma target 3.0
    75.  
    76.         sampler2D _MainTex;
    77.  
    78.         struct Input
    79.         {
    80.             float2 uv_MainTex;
    81.         };
    82.  
    83.         half _Glossiness;
    84.         half _Metallic;
    85.         fixed4 _Color;
    86.  
    87.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    88.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    89.         // #pragma instancing_options assumeuniformscaling
    90.         UNITY_INSTANCING_BUFFER_START(Props)
    91.             // put more per-instance properties here
    92.         UNITY_INSTANCING_BUFFER_END(Props)
    93.  
    94.         void surf (Input IN, inout SurfaceOutputStandard o)
    95.         {
    96.             // Albedo comes from a texture tinted by color
    97.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    98.             o.Albedo = c.rgb;
    99.             // Metallic and smoothness come from slider variables
    100.             o.Metallic = _Metallic;
    101.             o.Smoothness = _Glossiness;
    102.             o.Alpha = c.a;
    103.         }
    104.         ENDCG
    105.     }
    106.     FallBack "Diffuse"
    107. }
    108.  
    Here are screenshots in Unity of the character from Sketchfab with the lit shader and the original unlit version:
     
    Last edited: Mar 11, 2021
    TheJavierD and DerrickBarra like this.
  16. ar2056

    ar2056

    Joined:
    Oct 17, 2018
    Posts:
    8
    Hello could you please tell me how I can load draco compressed models ?
     
  17. Siccity

    Siccity

    Joined:
    Dec 7, 2013
    Posts:
    245
    Draco compression is supported, there is no need to do anything extra.
     
  18. ar2056

    ar2056

    Joined:
    Oct 17, 2018
    Posts:
    8
    Ok thanks for the quick reply! I raised an issue here: 127

    So I should be able to do so like this ?

    Code (CSharp):
    1.  
    2. string modelPath = Application.persistentDataPath + "/gina.drc.bytes";
    3. Importer.ImportGLTFAsync(modelPath, new ImportSettings(), OnFinishAsync);
    4.  
    I am just a bit confused on how to use it ? Do we need the ".bytes" extension ?

    Also do we use the
    Code (CSharp):
    1. ImportGLTFAsync()
    method or the
    Code (CSharp):
    1. LoadFromFileAsync()
    method ?

    The method
    Code (CSharp):
    1. LoadFromFileAsync()
    only checks for glb or gltf extensions so that confuses me even more.

    Could you provide an example please ?

    Thanks!
     
  19. Siccity

    Siccity

    Joined:
    Dec 7, 2013
    Posts:
    245
    I don't know what that .bytes extension is. GLTFUtility only reads draco compressed models through gltf files. It can't read raw draco compressed data.
     
  20. ar2056

    ar2056

    Joined:
    Oct 17, 2018
    Posts:
    8
    Ok got it here! https://github.com/CesiumGS/gltf-pipeline ! Thanks!
     
  21. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    14
    After reviewing the post from @jhocking I extended the original shader code to allow for the additional PBR textures and the results so far are pretty good. I've tested it on several models that have transparency order issues and it resolves them.

    The image below is of the Buster Drone on Sketchfab which has given us issues with this draw order in the past.



    Code (CSharp):
    1. /*******************************************************
    2. * A Square's PBR Shader with Transparency fixes.
    3. *
    4. * Per feedback and research into shaders, we created a PBR shader with access to
    5. * all maps and properties and combined it with the transparency fixes from jhocking's
    6. * post.
    7. *
    8. * https://forum.unity.com/threads/gltfutility-a-simple-gltf-plugin.654319/page-4
    9. *
    10. *******************************************************/
    11.  
    12.  
    13. Shader "GLTFUtility/A2 Standard Transparent (Metallic)" {
    14.     Properties
    15.     {
    16.         _Color ("Color", Color) = (1,1,1,1)
    17.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    18.         _MetallicGlossMap ("Metallic (B) Gloss (G)", 2D) = "white" {}
    19.         _Roughness ("Roughness", Range(0,1)) = 1
    20.         _Metallic ("Metallic", Range(0,1)) = 1
    21.         [Normal] _BumpMap ("Normal", 2D) = "bump" {}
    22.         _BumpScale("NormalScale", Float) = 1.0
    23.         _OcclusionMap ("Occlusion (R)", 2D) = "white" {}
    24.         _EmissionMap ("Emission", 2D) = "black" {}
    25.         _EmissionColor ("Emission Color", Color) = (0,0,0,0)
    26.     } // END Properties
    27.  
    28.     SubShader
    29.     {
    30.         Tags { "RenderType"="Transparent" "Queue"="Transparent" }
    31.         LOD 200
    32.  
    33.         // ---------- Start Pass 1 ----------
    34.         Pass
    35.         {
    36.             ZWrite On
    37.             //Cull Off
    38.             ColorMask 0
    39.  
    40.             CGPROGRAM
    41.             #pragma vertex vert
    42.             #pragma fragment frag
    43.  
    44.             #include "UnityCG.cginc"
    45.  
    46.             struct appdata
    47.             {
    48.                 float4 vertex : POSITION;
    49.                 float2 uv : TEXCOORD0;
    50.             };
    51.  
    52.             struct v2f
    53.             {
    54.                 float2 uv : TEXCOORD0;
    55.                 float4 vertex : SV_POSITION;
    56.             };
    57.  
    58.             sampler2D _MainTex;
    59.             float4 _MainTex_ST;
    60.  
    61.             v2f vert(appdata v)
    62.             {
    63.                 v2f o;
    64.                 o.vertex = UnityObjectToClipPos(v.vertex);
    65.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    66.                 return o;
    67.             }
    68.  
    69.             fixed4 frag(v2f i) : SV_Target
    70.             {
    71.                 fixed4 col = tex2D(_MainTex, i.uv);
    72.                 clip(col.a - .97);
    73.                 return col;
    74.             }
    75.  
    76.             ENDCG
    77.  
    78.         } // ---------- END Pass 1----------
    79.  
    80.         // ---------- Start Pass 2 ----------
    81.             ZWrite Off
    82.             //Cull Off
    83.             Blend SrcAlpha OneMinusSrcAlpha
    84.  
    85.             CGPROGRAM
    86.             // Physically based Standard lighting model, and enable shadows on all light types
    87.             #pragma surface surf Standard fullforwardshadows alpha:fade
    88.             // Use shader model 3.0 target, to get nicer looking lighting
    89.             #pragma target 3.0
    90.  
    91.             sampler2D _MainTex;
    92.             sampler2D _MetallicGlossMap;
    93.             sampler2D _BumpMap;
    94.             sampler2D _OcclusionMap;
    95.             sampler2D _EmissionMap;
    96.  
    97.             struct Input
    98.             {
    99.                 float2 uv_MainTex;
    100.                 float2 uv_BumpMap;
    101.                 float2 uv_MetallicGlossMap;
    102.                 float2 uv_OcclusionMap;
    103.                 float2 uv_EmissionMap;
    104.                 float4 color : COLOR;
    105.             };
    106.  
    107.             half _Roughness;
    108.             half _Metallic;
    109.             half _AlphaCutoff;
    110.             half _BumpScale;
    111.             fixed4 _Color;
    112.             fixed4 _EmissionColor;
    113.  
    114.             // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    115.             // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    116.             // #pragma instancing_options assumeuniformscaling
    117.             UNITY_INSTANCING_BUFFER_START(Props)
    118.             // put more per-instance properties here
    119.             UNITY_INSTANCING_BUFFER_END(Props)
    120.  
    121.             void surf (Input IN, inout SurfaceOutputStandard o)
    122.             {
    123.                 // Albedo comes from a texture tinted by color
    124.                 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    125.                 o.Albedo = c.rgb * IN.color;
    126.                 o.Alpha = c.a;
    127.                 // Metallic comes from blue channel tinted by slider variables
    128.                 fixed4 m = tex2D (_MetallicGlossMap, IN.uv_MetallicGlossMap);
    129.                 o.Metallic = m.b * _Metallic;
    130.                 // Smoothness comes from blue channel tinted by slider variables
    131.                 o.Smoothness = 1 - (m.g * _Roughness);
    132.                 // Normal comes from a bump map
    133.                 o.Normal = UnpackScaleNormal(tex2D (_BumpMap, IN.uv_BumpMap), _BumpScale);
    134.                 // Ambient Occlusion comes from red channel
    135.                 o.Occlusion = tex2D (_OcclusionMap, IN.uv_OcclusionMap).r;
    136.                 // Emission comes from a texture tinted by color
    137.                 o.Emission = tex2D (_EmissionMap, IN.uv_EmissionMap) * _EmissionColor;
    138.             }
    139.  
    140.             ENDCG
    141.         // ---------- END Pass 2 ----------
    142.     }
    143.  
    144.     FallBack "Diffuse"
    145. }

    Thanks for posting the original shader code fixes, that was super helpful!
     

    Attached Files:

    jhocking-bundlar likes this.
  22. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    14
    Btw, if you are in a need of a double-sided material, but want to be able to toggle it at runtime you can also add
    Code (CSharp):
    1. [Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 2
    in the Properties section below your other parameters and then in script use:
    Code (CSharp):
    1. renderer.material.SetFloat("_Cull", 0);
    to change the mode from backface culled to no culling.

    Also see: https://docs.unity3d.com/ScriptReference/Rendering.CullMode.html
     
    jhocking-bundlar likes this.
  23. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    83
    Hello

    I'm making a project with the GLTFUtility and is running good so far, but, I have tryed both shaders, yours and @jhocking's with "Lucina" and "Buster_drone" models in both URP and Built-in RP (I have 2 projects to test) but I just can't make it works. I have added the shader in "Project Setting - Graphics - Built-In Shader Settings - Alwais Include Shaders. What I'm I missing? do I need to change something in the GLTFUtility scripts? maybe in the importer?

    In fact I have errors when trying to import the "Buster_Drone" by drag & drop and by script.

    NullReferenceException: Object reference not set to an instance of an object
    Siccity.GLTFUtility.GLTFTexture+ImportResult+<GetTextureCached>d__3.MoveNext () (at Assets/GLTFUtility-master/Scripts/Spec/GLTFTexture.cs:28)
    Siccity.GLTFUtility.GLTFMaterial+PbrMetalRoughness+<CreateMaterial>d__5.MoveNext () (at Assets/GLTFUtility-master/Scripts/Spec/GLTFMaterial.cs:160)
    Siccity.GLTFUtility.GLTFMaterial+<CreateMaterial>d__14.MoveNext () (at Assets/GLTFUtility-master/Scripts/Spec/GLTFMaterial.cs:42)
    Siccity.GLTFUtility.GLTFMaterial+ImportTask+<OnCoroutine>d__4.MoveNext () (at Assets/GLTFUtility-master/Scripts/Spec/GLTFMaterial.cs:306)
    Siccity.GLTFUtility.Importer+ImportTask`1[TReturn].RunSynchronously () (at Assets/GLTFUtility-master/Scripts/Importer.cs:221)
    Siccity.GLTFUtility.Importer.LoadInternal (Siccity.GLTFUtility.GLTFObject gltfObject, System.String filepath, System.Byte[] bytefile, System.Int64 binChunkStart, Siccity.GLTFUtility.ImportSettings importSettings, UnityEngine.AnimationClip[]& animations) (at Assets/GLTFUtility-master/Scripts/Importer.cs:265)
    Siccity.GLTFUtility.Importer.ImportGLTF (System.String filepath, Siccity.GLTFUtility.ImportSettings importSettings, UnityEngine.AnimationClip[]& animations) (at Assets/GLTFUtility-master/Scripts/Importer.cs:200)
    Siccity.GLTFUtility.Importer.LoadFromFile (System.String filepath, Siccity.GLTFUtility.ImportSettings importSettings, UnityEngine.AnimationClip[]& animations, Siccity.GLTFUtility.Format format) (at Assets/GLTFUtility-master/Scripts/Importer.cs:28)
    Siccity.GLTFUtility.GLTFImporter.OnImportAsset (UnityEditor.Experimental.AssetImporters.AssetImportContext ctx) (at Assets/GLTFUtility-master/Scripts/Editor/GLTFImporter.cs:15)
    UnityEditor.Experimental.AssetImporters.ScriptedImporter.GenerateAssetData (UnityEditor.Experimental.AssetImporters.AssetImportContext ctx) (at <a8e33794c0064f2aa201ade069162226>:0)
    UnityEditorInternal.InternalEditorUtility:projectWindowDrag(HierarchyProperty, Boolean)
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr)


    Thanks in advance!
     
  24. jhocking-bundlar

    jhocking-bundlar

    Joined:
    Nov 12, 2019
    Posts:
    24
    Well changing the shader on a material is as simple as using the Shader menu at the top of the Inspector when you select the material. That's to change it manually, although your script errors kinda suggest you are attempting to have the shader changed automatically in the importer, rather than changing it manually.

    When you say "I just can't make it works" can you be more specific about what is happening? "Doesn't work" can mean a lot of things.

    Also, what exactly did you do before getting those script errors? In particular, did you change anything in the plugin's code?
     
  25. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    83
    Yep, That's exactly what I did, if I change the material manually it looks good. My intentions was to have this working "automatically" when you drag and drop the gltf model in the editor or when the user import the model n the player.

    Sorry for not being clear, I mean the model doesn't looks good, as I say when I drag & drop it or importing it in the player.

    Nop, just a couple of modiffication by following this thread and the github project but as I say it works good so far. In fact, I have tested almost all the models probided by KhronosGroup "glTF-Sample-Models-master"

    LucinaErrorSRP.png

    LucinaErrorURP.png

    LucinaOK_SRP.png

    Thanks for the answer!
     
  26. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    792
    Ok, well you didn't tell us what you did, all you said is "I tried to use the shader and it didn't work."

    So... yes. A couple of modifications is changing something. Not to be a dick, but how do you expect anyone to help you if you don't tell them what you did?

    You didn't even say what you're trying to do in your original post, but at least we know that now: have the new shaders applied automatically on import. Simply asking that ("how do I make the importer use the new shader?") would've been a lot more straightforward in this case. When I'm back at my work computer (which has this plugin installed) I can probably explain.
     
    Last edited: Mar 12, 2021
  27. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    83
    Maybe it sounds like your shader didn't work, sorry for that, i didn't explain myself. It totally works.

    Nothing that change the main behavior of the GltfUtility, that's why i didn't mention it.

    I just try to keep my app updated, but nevermind.

    Thanks for the answer!.
     
  28. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    14
    Not entirely sure where the error lies, but I do want to point out that if you are making changes to a shader at runtime these changes affect the instance of the shader not the origin. Meaning if you spawn two objects in the scene and reference one of them, that object's shader will update with the changes passed at runtime but the other will not unless you specify both.

    The object needs to be loaded first and the renderer needs to be referenced first and changes need to be made at the end of the loading process after the asset exists or you will get a Null error.

    In the event you aren't making changes at runtime and you are making custom shaders but not overwriting the original Standard Metallic Blend shader provided by GLTFUtility then you need to go to the ShaderSettings.cs and get a new reference to your shader by it's string name in the Shader.Find() method. I.E. You made the new shader, but GLTFUtility doesn't know to use that one instead.

    Code (CSharp):
    1. public Shader GetDefaultMetallic() {
    2. #if UNITY_2019_1_OR_NEWER
    3.             if (GraphicsSettings.renderPipelineAsset) return Shader.Find("GLTFUtility/URP/Standard (Metallic)");
    4.             else
    5. #endif
    6.                 return Shader.Find("GLTFUtility/Standard (Metallic)");
    7.         }
     
    jhocking and marck_ozz like this.
  29. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    83
    Thanks for the help!!

    yeah, so much confusion because of my question, I'm really sorry about that, I mean, for not explaining myself.


    Ok, I get it. that's what I need. I really didn't know how or where the import process "matches" the custom shaders with the imported object.
     
    ASGS_DumbFox likes this.
  30. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    14
    @jhocking question for ya. So when doing some additional testing I noticed that the shader fixes for the draw order do indeed fix most of the rendering issues, but not all. Essentially what we are seeing is if an object has only transparency shaders, there are still details that can be rendered out of the correct draw order. In the case of Lucina, we are noticing that the frill in her dress will disappear by being drawn over by her hair. It seems the polygons that intersect can run into this issue.

    Now, I want to preface this by saying I know that order independent transparency is a pretty massive undertaking and not everything can be solved by some shader changes. There is a lot that may have to go into creating a 100% solution and I'm not expecting a miracle or anything.

    Have you come across anything else on the shader side that may fix the issues in the attached images below.

    I got pretty close to finding a resolution through Z-Testing. Parts that would intersect would appear properly, but they would look like a cutout texture with no fading or blending. I'm going to give it another shot later when I get a moment to see if I can figure something out.
     

    Attached Files:

  31. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    792
    Well I'm not sure, but the first thing I'd be suspecting is that the frills are not perfectly opaque but rather slightly semi-transparent in the alpha channel. In my explanation I mentioned "Incidentally, if the alpha channel of the texture had lots of semi-transparency then it might not look great (since all those areas would be missing from the zbuffer)".

    The clip() function in this shader discards any fragments that aren't completely opaque, which means anything that's semi-transparent will not be in the depth buffer and can have rendering glitches. This is still a huge improvement over having those rendering glitches apply to the entire model, and allows for rendering smooth semi-transparency (as opposed to unsightly holes in the mesh, or hard cutouts like you saw).
     
  32. Boemak

    Boemak

    Joined:
    May 29, 2013
    Posts:
    44
    How do you get the materials to be editable? Everything I import is readonly, which is pretty annoying when you just need to adjust a slider. I know Unity does this with FBX also so I guess it's a Unity thing, can we fix this?
     
  33. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    14
    That makes sense. No worries. The only way I was able to sort of combat it was through the z-testing and having both passes be ZWriteOn, which was creating some issues if it wasn't in this very specific configuration.
     
  34. ASGS_DumbFox

    ASGS_DumbFox

    Joined:
    Sep 23, 2017
    Posts:
    14
    Not sure if this is related to this forum or if this is a general question but regardless:

    Any asset that is imported will have it's imported materials / animations as read-only. There are two things you can do to resolve this:

    1. Create new materials and reassign them to your assets.
    2. Extract Materials - With the FBX selected, in the inspector, go to Materials tab > Materials > Extract Materials which should create editable versions of your materials.

    I would recommend doing number 1 and getting into the habit of creating materials in engine as part of your pipeline. It really depends on your art pipeline, but for our team it's more practical to create the material and assign the textures during import instead of extracting.
     
  35. Boemak

    Boemak

    Joined:
    May 29, 2013
    Posts:
    44
    I
    I know the idea behind it, it is just dumb. I use GLTF because it exports the principled BSDF nicely from Blender. Maybe I would like to tweak some emission slider, I first need to copy the material, re-apply it and tweak it.

    It is just a hassle. I saw the FR for an automatic extraction ala FBX on GitHub.
     
  36. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    83
    Hello guys!

    I just realize a BIG mistake I was making while trying to import a .gltf in my builded app and was part of the confusion in my last question.

    When importing a gltf by script (player running), I copy all the files needed (textures, .bin, .gltf itself) to the "Application.persistentDataPath" and from there import to the scene, but I "extract" all the textures files from their folder and I put them all into a single folder with the bin and gltf, the problem is that the import process will look for those textures whit their "full path", I mean inside their original folder, like this:

    upload_2021-3-31_12-2-7.png

    what couses a "NullReference error" in the import process if not find them like this. That didn't happened when drag&drop because I drag just the folder with all the files and didn' happen before because all models that I have tested have all the files in a single folder.

    Maybe it is kind of obvious but I'm just silly haha and I want to pointed out this mistake in case someone is struggling with the same ̶s̶i̶l̶l̶i̶n̶e̶s̶s̶ issue.

    :V
     
  37. zhengjw

    zhengjw

    Joined:
    Mar 3, 2021
    Posts:
    1
    I also found some errors in the animation handling that resulted in incoherent animations.
     
unityunity