Search Unity

Spheres show as lavender circles on devices

Discussion in 'General Graphics' started by dmarques42, Jul 2, 2015.

  1. dmarques42

    dmarques42

    Joined:
    Jul 2, 2015
    Posts:
    3
    I am new to Unity.

    I have built a simple app, everything is working fine. I have run it on Android tablets, Android phone, iOS, and WebGL. But I have a problem I cannot figure out. I use tiny (0.1, 0.1, 0.1) spheres at the bottom to show page navigation for swipe. These show up fine in the editor/simulator, but on every device and on WebGL, they show up as small lavender circles.

    Here is my code for these dots:

    varcurwin : GameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    curwin.transform.localScale = Vector3(0.1,0.1,0.1);
    curwin.transform.position = Vector3(0.1,-4.5,0);
    curwin.GetComponent.<Renderer>().material.color = Color(1,1,1,1);

    varotherwin : GameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    otherwin.transform.localScale = Vector3(0.1,0.1,0.1);
    otherwin.transform.position = Vector3(-0.1,-4.5,0);
    otherwin.GetComponent.<Renderer>().material.color = Color(0.3,0.3,0.3,0.3);

    And attached are as viewed in Unity3D
    Screen Shot 2015-07-02 at 12.52.18 PM.png

    And as viewed on any device or WebGL
    Screen Shot 2015-07-02 at 12.51.39 PM.png


    I have played with the Color parameters, size parameters, but nothing makes any difference.
    What am I missing?
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Solid magenta is unity's way of telling you that your material either has an error in it's shader, or it's shader is not compatible with your platform or hardware.

    Try using a different shader on your material, and if you're making your own shaders, make sure they have fallback shaders.
     
    theANMATOR2b likes this.
  3. dmarques42

    dmarques42

    Joined:
    Jul 2, 2015
    Posts:
    3
    Hmm, I never invoked Shader anywhere in my code, never created a shader, I assumed it would just pick up the default Shader and that would be compatible in general. I guess those are incorrect assumptions, I'll look into shaders, thanks for the pointer.
     
  4. dmarques42

    dmarques42

    Joined:
    Jul 2, 2015
    Posts:
    3
    I am still not getting it, perhaps not understanding how shaders work. I added these lines (in the appropriate places):

    varshader1 : Shader;
    shader1 = Shader.Find("Standard");
    curwin.GetComponent.<Renderer>().material.shader = shader1;

    It all compiles and works perfectly fine no errors in Unity3d.

    The result on devices is the same, magenta circles. Is it a problem that I am using CreatePrimitive(PrimitiveType.Sphere) instead of using spheres created in the hierarchy? (I am doing everything in script to control the way they all scale together.) Or is Standard not useful on devices?
     
    Last edited: Jul 2, 2015
  5. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    You don't need to do anything with shaders in code. On your game object in the editor, you have a mesh renderer with a material attached.

    If you change the material or texture, unity will create the new material inside a new material folder. You can select the material to change the shader it uses in the inspector.

    If you don't change the material or the texture, you're using the default material, which uses the standard shader.



    I haven't done much work with models in unity (usually done by a team member), but perhaps the vertex information you're creating for the new mesh is not compatible with the shader you're using? (example: using verts with no texcoords on a textured shader)
     
  6. smd863

    smd863

    Joined:
    Jan 26, 2014
    Posts:
    292
    All materials use a shader, and when you create primitive geometry, it should come in using the "Default-Material" material which uses the Unity 5 "Standard" shader.

    The vertex information should be fine since he's just using the Unity built-in primitive sphere unless it was changed. You can mess with it using "Meshfilter.sharedMesh" if you're not careful, but that shouldn't happen very often.

    For what it's worth I copied and pasted that code into a new Unity project and it deployed without a problem to both WebGL and Android. The standard shader should be working fine for what you're doing. I would create a new test project with just that code in it, and see if it works. If it does, slowly re-introduce aspects of your project into the test project until you find when the problem pops up.

    I suppose it's possible that the "Standard" shader in your Unity install got changed or corrupted somehow so that it fails to be compatible with the ES2 feature-level. You could try re-installing Unity and see if that fixes it.

    As an aside, though, the standard shader is pretty heavy (doing all that physically-based shading) so I would suggest using a simpler shader if you are just using the spheres as page navigation icons. Take a look at the Free MatCap Shaders. They don't do correct or dynamic lighting at all--they just fake some nice-looking lighting using a texture--but they are pretty and very fast.
     
    theANMATOR2b likes this.
  7. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    Offhand it seems like you are not referencing any materials or shaders, so Unity is not adding them to your build.

    In order for Unity to include assets like materials or shaders in the build they have to be directly referenced somewhere, or included in a Resources' folder. If you are only programmatically creating models, then its unlikely you have any material/shader references in your scene and so Unity cannot know to include them.

    Usually a Unity project would have some models in the scene hierarchy, so in that case you'd have a mesh and a mesh renderer, where the renderer would have a reference to a material and that material would reference a shader ( e.g. normally the default Standard shader). This would mean even if you just had a single model in your scene, the default material/shader that would be needed by your code would be included into the build.

    However since it would appear that your scene is empty, or at least devoid of any models/meshes that use the default material and thus the default Standard shader ( which was the only way I could recreate your problem) then the standard shader is not included in your build, hence why your spheres come out pink.

    Thankfully the fix is straight forward.

    1. Go to Edit > Project Settings > Graphics
    2. In the Inspector that now shows the Graphics tab you'll see an option 'Always Include Shaders' that should be an array containing 6 elemensts ( first is Legacy Shaders/Diffuse'.
    3. Change the Array from a size of 6 to 7
    4. Now click on the selector for the new last shader in the list ( element 6, should be a duplicate of 'UI/Default Font') and change it to the 'standard' shader.
    5. Save the project and Scene.
    6. Rebuild

    In my tests with webGL this now correctly renders the spheres and no more pink materials, since you've explicitly told Unity to include the 'standard' shader which is referenced by the default material which is automatically assigned to your spheres when you created them.

    The key point here is that Unity will only include assets in a build that have a reference in the scene. In the case of a shader this means including either a direct reference ( e.g. add a public Shader field to a script that you assign via the inspector), or indirectly e.g. via including a gameObject with a mesh Renderer, that uses the default material, which itself references the 'standard' shader. Alternatively its also possible to use a special 'Resource' folder, or in the case of shaders, to explicitly include them via the 'Project Settings > Graphics' Inspector Tab.


    Hope this helps.

    Edit: While its good to learn and understand why this happens, as others have mentioned the standard shader is maybe not the best shader for mobile development, so unless you need its specific features ( Physically Based Rendering ), you may be better off with the legacy shaders.
     
    theANMATOR2b likes this.