A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Discussion in 'Assets and Asset Store' started by LouskRad, May 3, 2018.
Also here is the settings:
It might be a lighting related issue in your scene. Unlike the default Unity grass shader that uses the Lambert lighting model, the GPUI foliage shader is a PBR based shader using the Standard lighting model. As such, it would react to scene lights in a similar way to the Standard Shader. Without changing the lights, you can change the lighting model in the foliage shader to Lambert. If you need help with that, you can contact us via email.
Sorry, but I don't think that problem in this. Actualy I solved problem throught using custom material for each prototype, and color in standard shader looks correctly but here is one problem, it's working only for grass prototypes, I cant attach custom material for detail meshes.
GPUI uses the materials on the original prefab of the prototype for detail meshes; you don't need to attach a custom material for them.
Hello. First, we at the studio are really impressed about this asset, really amazing!
Anyway, we have a couple issues: Our game is a flying simulator and our terrain is 20,000 units long. For months we have struggled trying to show a great ammount of trees in run time with the less popping possible in this terrain, and our tests with 100,000 trees were grea using GPUI, but the view limit is quite low for our needs. Is there a way to increase the render distance of the trees beyond 2000 units? I tought about modifying the distance directly via script, but I'd prefeer to know about any possible issue with this approach, or if you have another tip. This truly could save our project!
If you put the trees in the prefab manager instead of the tree manager, then you can set a 10000 max culling distance:
Ohh, I see, thanks for the help!
@iddqd is right in that you can use the prefab manager for this, but if you want to use the Tree Manager instead, you can increase the maximum culling distance from the GPU Instancer Preferences window with the Max Tree Distance setting.
Awesome, thanks for the help. Yeah, Looking through the documentation now in deep, sometimes I just get too excited and start playing around.
EDIT: This is fantastic. Our tests with 500.000 trees on scene run with 500 / 600 FPS with 18000 of clipping distance: Sir, your product is saving our project <3 <3
MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
GPUInstancer.GPUInstancerPrefabManager.Update () (at Assets/GPUInstancer/Scripts/GPUInstancerPrefabManager.cs:63)
GPUInstancer.GPUInstancerEditorSimulator.CameraOnPreCull (UnityEngine.Camera cam) (at Assets/GPUInstancer/Scripts/GPUInstancerEditorSimulator.cs:126)
UnityEngine.Camera.FireOnPreCull (UnityEngine.Camera cam) (at C:/buildslave/unity/build/Runtime/Export/Camera/Camera.bindings.cs:347)
I am keep getting the above error, that thankfully reproducibly occurs. The error is clearly to do with the fact that the instanced object in question is destroyed without taking care of it. I have a space ship carrier that launches fighters, both the carrier and its fighters are instanced with GPUI and since being a lazy bugger i use enabled runtime modification with auto add/remove instance enabled. The issue only occurs when the carrier is destroyed with instanced crafts "onboard".
By onboard i mean the following:
Upon landing the GPUInstancerAPI.DisableIntancingForInstance() function is used to make it not rendered,
then the root game object is SetActive(false) and its transform is parented to the carrier,
if the craft launches again the process is reversed.
My assumption was onboard craft's instance would be taken care by the auto remove instance option when the carrier is destroyed, clearly my assumption is wrong.
Can you tell me what is the correct way of taking care the removal of temporarily disabled instances?
Many thanks in advance!!!
Hello Again. I'm facing a small problem with a Skybox and GPU Instancer. Looks like in game, a group of planes of the trees instanced is rendered just on top of the sky, and it goes to the void, causing this weird psychodelic effect. Any idea what is causing it? This only happens when I place trees instanced, with regular trees or no trees, there's no problem. The trees are from the asset store (Coniferous forest) And they use (I think) a custom shader. Also, I just have on the scene a tree manager.
Thanks in advance!
Hi, is there any way to get/find instances inside bounds? Removing such instances with API works great but we need to only hide temporary such tree instances.
you can use the AddPrefabInstance and RemovePrefabInstance API methods instead of the EnableInstancingForInstance and DisableIntancingForInstance methods. We do not do null checks for the Auto. Update Transform Data feature because of performance reasons.
looks like the shader for these trees is missing the required Unity instancing setup (UNITY_SETUP_INSTANCE_ID(v). You can take a look at this wiki page to set it up.
There is no functionality to hide instances as such. You can, however, use the Prefab Manager's Auto. Add/Remove functionality (or the API) to add and remove instances at runtime.
Just gotta say--this asset is fantastic and made my project possible! I'm hoping for Probuilder integration in the future! Great work and a great purchase!
I have no experience with Code, so instead I created new materials using the GPU MK4 shaders included and they work great. Thank you!
EDIT: I'm facing another problem. I'm getting this Warning message. "The prefab for this prototype does not use any of the default unity shaders" When I generate the billboards, they look in grayscale, and doesn't replace the LOD Culled, the only way I have to see the Billboard generated is selecting it directly into the Hierarchy tab. My prototype was setup with materials made with the GPU Instancer /MK4 shaders, should I use another type?
It's weird, because in an empty project I got some cool results, but in my project I'm encountering a lot of problems, and currently the trees I set up cannot be instanced.
I've just checked v1.2.0 and have some questions about gpu-performance \ draw calls
I did frame analysis in RenderDoc for details instancing demo
all instance were culled after visibility compute shader:
and there we have empty draw calls:
In my working scene it's even worse:
Is it possible to eliminate empty draws if we know about that after compute pass?
I'm also interested in further steps in optimization, such as combining prototypes in one batch (same mesh + texture arrays for different grasses for example) to reduce number of calls in the very beginning of frame:
I wonder if you have plans for this?
I have a recurring bug with flickering objects. Here's a video of it:
This is caused by the occlusion culling system, or at least can be prevented by disabling occlusion culling. My theory is that these objects are occluding themselves, and that they flicker based on camera position because of floating point rounding -- if they round towards the camera they occlude themselves and blink out, if they round away from the camera they're fine. (This is just a theory.)
This happens on most meshes but not all meshes. I'm not sure what makes the others special. I am creating my prototypes with DefineGameObjectAsPrefabPrototypeAtRuntime.
Here's where it really gets weird:
In the editor, selecting the GPU Instancer Prefab Manager gameobject fixes it. I don't have to tweak any settings or anything -- the problem goes away as soon as I select the Prefab Manager and stays gone until I stop the game and then play it again.
Unfortunately I can't just use that to fix it. The issue happens in builds too, and I don't know what's actually happening when I select the Prefab Manager that causes the issue to go away. I assume there's some kind of initialization I'm supposed to be doing after DefineGameObjectAsPrefabPrototypeAtRuntime but I don't know what it is...
The API documentation doesn't seem to cover the GPUInstancerPrefabManager, as far as I can tell. Does anybody have any insights?
Quick update: we made some real progress while this was sitting in the moderation queue. There are definitely two issues here, at least.
1. minCullingDistance is set to 0 on the new prefab created with DefineGameObjectAsPrototypeAtRuntime, rather than the minCullingDistance value of the prefab manager. Setting the minCullingDistance on the prefab manager through code does not propagate that value to runtime-created prefabs that it manages, either -- you have to set each one individually. (Dragging the slider on the inspector does set all the prefabs it manages to that value, but setting it through code does not.) This is a quick fix for sure.
2. Large objects with open spaces you can see through, like doors and archways, seem to confuse the occlusion culling behind them at certain angles. This one might be hairy.
The grayscale issue is probably because the tree shader you are using does not define a _MainTex property (but uses a different name for the albedo texture). However, I'm not sure I can follow the problem about the billboard not replacing the "culled" stage and breaking instancing. How do you mean that you select it from the hierarchy? The GPUI billboards are generated at runtime and used internally (without instantiation in the hierarchy).
Can you provide a screenshot (or video) of your setup?
GPU Instancer makes the frustum and occlusion culling calculations in the GPU with compute shaders. These compute shaders determine how many instances will be drawn for each draw call. Draw calls are always made because in the CPU thread GPU Instancer does not know if the instances are visible or not. So the draw calls are always there, but if there are no visible objects, it does not draw anything. Which means your draw call count will not change with visibility checks.
So with GPU Instancer, your prototypes define the draw call count and it never changes. It does not matter how many instances there are, or if they are visible or not. Visibility checks (e.g. frustum and occlusion culling) are there to reduce the geometry drawn for each draw call, not for reducing the total draw call count.
If all the objects are culled, for example, you would still see the draw call made for the prototype, but since no instances are appended to the buffer, you will see the draw calls as consuming 0 ms as in your screenshots.
As for using the same mesh with atlases, this is currently not in our roadmap. This would contradict some of our current features and would also cause various problems in some platforms other than DX11.
and thank you for the feedback.
We are currently working on a few fixes for the occlusion culling system, and these will be available quite soon with the next update. We have encountered a flickering issue (and problems with cutout shaders, small holes, etc.) that was caused by the occlusion culling system changes in the 1.2.0 version. This will also be among the fixes in the v1.2.1.
As for the minCullingDistance being set to 0, GPUI sets the values of the manager minCullingDistance to all the prototypes when you change the manager value for this in the inspector; but you are right that when creating the prototype from code, this would be set to 0. In fact, there are various properties for the prototypes that are set to default values when created from code. It is required to set all the values that you would not use the defaults for when creating your prototype from your script.
This is GPUInstancer running in MacOSX and Unity 2019.1.8f1.
Target Platform: IOS
Check out how the tree shadows behave.
And this is what happens when I enable Metal from the build settings:
There is just 1 type of earth prefab and 1 type of tree prefab.
And as you can see they are registered succesfully in both examples.
I attach just in case the shader we are using since I've read sometimes they can give problems.
Here you can see there is no differences between the gameObject tile that is being rendered and the one is not.
Hi, first of all .. what an asset! 100% upgrade for my workflow!
I haven't yet written a review but will as soon as two pesky problems I have are resolved!
Problem #1: A shadow of a generated MapMagic tree follows me around from the sky at all times. I'm not kidding XD
I can even see it in the scene tab when I pause the game and move the Scene camera around. It even follows scene tab camera!
Problem #2: I have trouble setting up billboards for MapMagic trees. I generated them but they won't show up in the game, even if I reduce culling to something like 100 there are no billboards generated.
I'm using latest versions of GPUI and MM. If you need I can post additional screenshots and info.
Thanks for the reply and the suggestions. The issue with the culling was fixed deactivating the complete terrain shader (CTI) component from my terrain, looks like some sort of bug or conflict. also, looks like it was affecting the billboard process because it's fixed now too. O:
I'm using CTS 2019 and tried to deactivate it but it didn't solve my issues.
When I add Speedtree 8 to Unity terrain system, it was fine. But as I add my Speedtree 8 into Tree Manager, all my trees at distance became flickering and have no collider anymore. Since Unity 2018.3 has collider problem with SP8, I add collider to every tree on my own as prefabs.
It looks like the problem is with your surface shader's shadow pass (which is taken from the fallback shader). You can make your surface shader generate a shadow pass for your by changing this line:
#pragma surface surf Lambert noforwardadd
#pragma surface surf Lambert noforwardadd addshadow
This should solve the problem with the shadows.
You might also want to remove the falback line from your shader since this fallback shader is not setup for GPUI and can cause further problems:
However, please notice that GPUI supports only Metal on MacOS and iOS systems. And also please make sure to download the latest (v1.2.1) update.
Hi there, and thanks!
Both problems seem to be related to the shader that your trees are using, which most likely lacks the Unity Instancing Setup (UNITY_SETUP_INSTANCE_ID(v);)
If this is the case, you can take a look at this wiki document to setup your shader manually for GPUI. That should solve Problem #1.
As for #2, can you please post the generated Billboard Albedo Texture? It might be that the billboards are not baked properly because of the shader of these trees.
We have just released v1.2.1, in which we also fixed some bugs related to objects flickering when using the occlusion culling feature. Updating your GPUI should fix this issue.
About SpeedTree and Colliders: GPUI does not do anything additional about the Colliders, so it should exactly result in the same behavior with Unity in terms of them. That is, the behavior of Colliders should be the same when you turn GPUI on and off when using the Tree Manager.
I'm using the latest version, of course! Well... It seems that if I add trees prefab from Unity terrain it's fine, but when add directly to Tree manager, there will be no collider (I think it doesn't work properly yet for SP8). Regarding the flickering, whether I add through Unity terrain or Tree manager, it result the same. It was okay with SP7 tho.
Please, help, Your system has improved performance a lot for my game
Good day. Every time I build a game I get an error for each object. This happens only in the build. There are no errors in the editor. How to fix it??? I saw this message on the forum. I did everything but it did not help me. version of the unit 2019.1.9. Gpu 1.2 version. how to fix it, help. ))
Thanks for the quick response!
So it's intended behavior that runtime-created prototypes don't get the settings of the prefab manager? That's a little weird, but okay. Easy enough to set it, now that I know I have to. Seems like it should be documented though -- none of the examples show you setting a bunch of stuff on new prototypes after they're created.
Is the fact that setting minCullingDistance on a prefabManager in the inspector behaves totally differently from setting it through code also intended behavior? Because that's extremely weird.
I look forward to seeing occlusion culling fixes -- that part of this bug has really baffled us, sometimes it vanishes completely and nothing flickers for minutes or even an hour at a time, and then just as inexplicably it comes back.
Moved to new version. Errors remained. one object shows a prototype. Another object shows a null reference. although everything is set up as needed. all registered and prototypes are also present in the scripts.
First, really great work guys. Amazing job.
I wanted to touch on this one a little bit because while the solution is obvious once you know it, its the getting there that was a serious journey. We only stumbled across this because we were attempting to figure out the flickering issue, and thus were comparing what we did to the examples and wiki.
The fact you have to set these manually is not really intuitive because the wiki and demo for runtime with no objects does not illustrate this, or mention it anywhere that I have seen. Also the fact you can set the minCullingDistance value in the prefab manager from the editor and this value is automatically propagated to everything implies to me it is the 'default' value to be used. Which is what directly leads to the thinking that adding items at runtime should be using this value.
Now, its the behavior of changing minCullingDistance in the editor that causes another false presumption as well.
The presumption is that changing the minCullingDistance on the prefab manager through code (should) propagates this value to all already added protos. This is what happens in the editor, so I would assume setting this value at runtime should perform the same action. It does not however, and nowhere does it say this. Setting the prefab managers minCullingDistance through code does absolutely nothing and you have no way to tell this easily.
Except that is not entirely true. You may be thinking if your in playmode, you can just click on the inspector. Except doing this actually hides the issues. When you click on the prefab manager in the hierarchy and the inspector is loaded, it immediately propagates the minCullingDistance (maybe other values) of the prefab manager to all currently added protos. So you have no way of knowing that setting the minCullingDistance did nothing because when you go to check, it updates right away and looks like it worked. Which reinforces the false presumption that setting the managers minCullingDistance is doing something. Which in turn re-enforces the idea that the prefab manager minCullingDistance is supposed to be like a default value and makes it seem like something is broken when doing it all through runtime.
Also to point out another small related more obscure issue this causes is; like i said bringing up the inspector immediately propagates the prefabManagers current minCullingDistance to all added protos when it is brought up. This means if you set the value of protos through code, and then click on the inspector, it will overwrite the individual values you set through code on each item with the value from the prefab manager. Further reinforcing the incorrect assumption that the prefab manager minCullingDistance is supposed to be like a default global value.
So as you can see, coming to the conclusion that you have to set the values manually on the protos and then not click the inspector for the prefab manager ever again after is not an easy one to come to, and has some issues with it.
From a use/user perspective I think that when adding prototypes at runtime they should automatically inherit the prefab managers settings for these values. If you need them to be different, you can (and already are) setting then individually manually so this has no real impact for those use cases, and falls in line with what I think a natural assumption of how it works is.
I also think that the propagation of setting the prefabManagers minCullingDistance should be moved from something that occurs in the inspector as a result of changing the value, to something that occurs within the prefab manager itself when you change the value. This would again brings what actually happens in line with expectations of what is expected to happen.
Otherwise i think that the wiki and demo project need to be updated to properly show this, and it needs to be noted somewhere as well that you can not ever select the prefab manager object in the hierarchy while in playmode.
Since this post is long enough, I will make a subsequent one later covering the flickering and pop-ing that is occurring (even in the latest 1.2.1 version).
Again great job!
I came to say thanks. This asset worths every dollar. I wish my lead allow me to post a few screenshot haha. Just a small advice to those facing problems: try to disable any component in your terrain; I found that Terrain Composer 2 and Complete Terrain Shader cause troubles and the trees are not instanced, without that problem, 400,000 trees with 15,000 view distance at 200 fps is a reality
So here is the next post. Just gonna apologize ahead of time, its gonna be long as well, but this one comes with solution.
I would also like to point out that the meshes we are using are possibly the worst case scenario for GPUInstancer, and we know this. Think of this test level as the stress test from hell for occlusion culling (ill post a picture at the end).
Flickering and Popping Objects.
These issues exist still in version 1.2.1. Solutions for each problem in each section.
These are two separate main issues that actually encompass a few sub issues each.
There are three separate issue here.
Flickering Issue 1
The first, flickering, is a per frame change in if an item is occlusion culled or not, and is visible when the camera is perfectly still and there are two separate occurrences of this issue.
The first is the flickering of objects directly in front of you, or objects you happen to be inside their bounding box. This happens If the minCullingDistance for the prototype is less then > 2x the length of the longest side of the prototype.
Im not 100% sure the cause of this, or my it needs to be 2x the longest side but is the only way to stop this flickering.
My theory is that since the object is so close to the camera, many if not all the sampled culling points are not on screen, which throws something off, and causes the item to be culled, next time around since the item wasnt supposed to be culled it gets resampled but its not there so its sampling behind it, and thus is in bounds and causes it to pop in cause it to be culled again the next frame. Again just a theory.
The really odd thing is the 2x longest side requirement for the minCullingDistance to prevent this. I could see 1x the longest distance, or even the longest distance from one corner to another, but 2x just seems so odd.
All prototypes must have a minCullingDistance that is 2x the longest side. This will prevent it from attempting to cull objects you are immediately up against, or 'in the bounds of' even if all the culling sample points are off the screen.
Flickering Issue 2
The second occurrence of the flickering issue is not related to the first, and can happen on any of the objects on the screen, at any distance. Sampling the LOD for culling in 1.2.1 helped this some, but not completely.
There are two issues here but with the same root issue, so well just cover that. Its basically floating point precision rounding issues that happen. This impacts both 'fully filled' objects that are on the 'cusp' of being not visible (in terms of the sampled points), and objects with holes in them overlapping at the same z distance from the camera.
isCulled = InstanceDepth > MaxDepth;
isCulled = InstanceDepth >= (MaxDepth + .0001);
adding in the = operator, and the very small bump solves this. Essentially just shifting the cutt-off for culling to error in our favor, instead of against us. I tried lots of different values, and not having the = symbol, but this was the best results i got with this exact line. With this flickering issue 2 is 100% resolved.
Flickering Issue 3
Cascading culling flickers.
What happens here is that due to one of the previous two issues and item is culled or not. Its presence, or lack or it then ends up allowing an item farther away to be able to be drawn, or not, which then does the same thing so on and so forth down the line. This results in a chain of items cycling visibility in a wild and chaotic fashion.
Fixing problems 1 and 2 with their given solutions has obviously removed this from happening.
So the second major issue we are having is objects popping in and out. This is caused by holes in objects, dependent on view angle, and stable across frames on if the object is culled or not when the camera is still.
This is obviously caused by our meshes having lots of holes in them meaning that the occlusion points are all covered fairly often, but the the mesh should clearly be visible.
Its should be noted that the 1.2.1 update actually made this issue a lot worse for us before my fix. Im guessing this is because of sampling the calculated LOD instead of 0 on the HiZ map now.
The solution here was simply to up the number of points sampled. Imagine splitting the boundingRect of the object into a 4x4 grid. I am additionally sampling (1,1), (1,3), (3,1), (3,3). So basically 1/4 the total distance in from each of the corners. This of course brings the number of sampled points up to 9, so it is not without a performance cost. However in our VERY VERY heavily holed meshes, this has removed 99.999999999999999% of any and all popping that occurred. The only popping that i would get would be the very very very occasional very tiny sliver of something view-able at an odd angle in the extremely far distance.
This change also helps improve flickering (if those fixes have not been applied). It would be nice if this was incorporated as an 'option' in some way for culling, like standard and advanced or something. So that based on the given meshes im using in a level I could switch between the two. I could probably cook something like this up myself, but it would be much preferred to be 'in' GPUInstancer, so that i don't have to re-add it every time i update.
It should be noted that using all three outlined solutions, all popping and flickering has been completely fixed without the need for calculating the LOD and using it to sample with for culling as well (shave off a few ops since we added some more sampling).
Also just to give some references here in terms of impact. Before i add in this last solution, i run at about a solid 1200-1300 fps in the demo scene. With the added sampling points, i drop to anywhere from 1000-1200 averaging around 1100. GTX 1660 Ti video card. Well worth the tradeoff in my case.
Below is a screenshot of this test scene we have so you can see why I call it a worse case test of GPUInstancer.
Spoiler: Very large Screenshot of scene
That's right, that scene, with all those arched bridges, with railings with all those holes in are single meshes, culls perfectly now.
Hope this helps someone else.
Thanks, and again, great job.
On a side note, how can I switch cameras with code?
Thanks in advance for the help.
EDIT: Nevermind, we just checked the API docs in depth and figured it out. Thanks!
Please make sure you are using the GPUI version 1.2.1 (it was released 15 minutes before you wrote your answer). If you are still having issues with the colliders, you can:
- remove the GPUI Tree Manager(s) from your scene
- make sure that your trees work with colliders with the default Unity terrain
- if your colliders are working, you can add a new Tree Manager, and the colliders should work exactly as they were without GPUI.
- if not, please send us a small sample project so we can investigate this issue.
looks like the problem is caused by a different execution order in the build, where the Auto. Add/Remove function works before the manager has been initialized. We will provide this fix in the next update, but for now you can change the Start method of the GPUInstancerPrefabRuntimeHandler.cs:
private void Start()
if (gpuiPrefab.state == PrefabInstancingState.None)
if (_prefabManager == null)
_prefabManager = GetPrefabManager();
if (_prefabManager != null)
private void Start()
if (gpuiPrefab.state == PrefabInstancingState.None)
if (_prefabManager == null)
_prefabManager = GetPrefabManager();
if (_prefabManager != null)
Thank you for the detailed feedback. It is a fair point about setting the manager values to the prototypes created from code. We will make the changes for this in the next update.
Flickering Issue 1: You are right that the close up objects can cause issues with the HiZ strategy. Your solution with minCullingDistance in this case is exactly right. We will add this to the Wiki documentation.
Flickering Issue 2: It is true that the HiZ algorithm is ultimately bound by the precision of the depth texture. However, the loss of precision should result in the lack of culling rather than false culling. But it might indeed be a good idea to use an offset for special cases. We will investigate this with a setup similar to yours, and add a solution to the next GPUI update.
Flickering Issue 3: True, solving 1 and 2 would solve this as well.
Popping Objects: We will look into the feasibility of adding an option to the Managers that would increase the amount of sample points. As you have mentioned, this option would slow down the culling feature, but increase its accuracy.
I originally did my GPU instancer integration a while back, and I added a stub method in my abstraction for updating a single matrix which at the time you didn't support. Now that you released the ability to update subsets of matrices, I have implemented this using the new override for UpdateVisibilityBufferWithMatrix4x4Array.
However, the new params being ", int arrayStartIndex = 0, int bufferStartIndex = 0, int count = 0)" - "arrayStartIndex" and "count" I get - but I'm not sure about buffer start index. Right now I am using the index of the matrix in the matrix array for both arrayStartIndex/bufferStartIndex. This appears to work but is that correct? It feels like this requires me to understand the underlying implementation to implement and perhaps doing this way will eventually fall over. What should I be using for bufferStartIndex?
That's what I did. It worked. Also when I unchecked occlusion culling. It stopped flickering as well. But what's the difference between uncheck and check?
Good day. Your decision helped. These errors no longer occur. but there are others. They are associated with shaders. The last thing I did was restart shaders.
Hi, sorry for the late reply. I suspected my issues were caused by Unity 2019.3 so I reimported entire project into 2019.1 and all is well now.
However, even with the latest GPUI, I did experience some flickering when I used occlusion culling but that could be because I have lots of big and irregular objects overlapping in the scene so I switched it off and am just using frustrum culling.
Another question. I use no-gameobject workflows, and I generate all of my templates via code at run-time. When I run a build it clearly is trying to load shaders that were not included in the build. I was always under the assumption that your shader variants file (the one in Resources) exists to pull in the correct files to builds. Mainly because this file is marked dirty (even though it hasn't changed from the last checkin), every checkin, and I have to undo it each time which tends to be a bit annoying.
In any case, this variants file only includes a single shader. I just referenced all of the shaders at the root of "Shaders" for now and it appears to have fixed the issue.
Not really a question. More of an FYI.