简体   繁体   中英

Unity WebGL ok in editor, pink screen in build

I am building a Polygon Tool using Unity 5.5 and WebGL, which I would like to use to crop a selection from an image. The project is using a shader file to define the points and area which make up the polygon. You can see the code for the shader below, as well as the code file.

The problem I am currently experiencing is that the project works fine in the Editor, but the WebGL build shows up pink in the browser. The polygon shader doesn't render, if I set a Fallback shader in the file it loads that one. I've looked up the issue online and I found and tried the following:

  1. Reimport all assets, as something may be missing. Check all game objects in the hierarchy for broken references.
  2. Make sure the shaders are in the 'Always Included Shaders' list in Project Graphics Settings.
  3. Potential memory leak? I increased the number of MB allocated to the project to 1024, lowered the size of the textures by compressing them and also ran the Profiler in the Editor. The Profiler recorded a max total use of ~220MB.
  4. Toggled the Quality Settings - I discovered that the Shader does not work if Anti-Aliasing is not on.
  5. Graphics card not supporting the shader? People online have reported similar problems on OS X (which I am also using), but they have not updated their queries.

I should note that there are no errors or warnings in the project. I am unsure where the problem lays and would truly appreciate any take on this issue. Please let me know if there is any further information that I can provide which could ease the process: Thank you in advance for your help :)

Polygon.cs file:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class Polygon : MonoBehaviour {
    public Material mat; //Binding materials; Polygon shader applied to it.
    Vector3[] worldPos; //Store 3D coordinates
    Vector4[] screenPos; //Store to draw the polygon vertices in screen coordinates
    int maxPointNum = 6;  //Total number of polygon vertices
    int currentpointNum = 0; //Current number of points placed
    int pointNum2Shader = 0; //Transfer number of vertices to shader
    bool InSelection = true; //Vertex gets is in the process

    void Start() {
        worldPos = new Vector3[maxPointNum];
        screenPos = new Vector4[maxPointNum];
    }

    void Update() {
        mat.SetVectorArray("Value", screenPos); //Pass the vertex position information to the screen shader.
        mat.SetInt("PointNum", pointNum2Shader); //Transfer number of vertices to shader

        //Cameras fired a ray to get to select a 3D location
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 100)) {
            Debug.DrawLine(ray.origin, hit.point);
        }

        //Use mouse clicks to obtain location information
        if (Input.GetMouseButtonDown(0) && InSelection) {
            if (currentpointNum < maxPointNum) {
                currentpointNum++;
                pointNum2Shader++;
                worldPos[currentpointNum - 1] = hit.point;
                //Vector3 v3 = Camera.main.ScreenToWorldPoint (worldPos [currentpointNum-1]);
                Vector3 v3 = Camera.main.WorldToScreenPoint(worldPos[currentpointNum - 1]);
                screenPos[currentpointNum - 1] = new Vector4(v3.x, v3.y, v3.z, 0);
            }
            else {
                InSelection = false;
            }
        }

        //Updated in real time screens of 3D point selected location
        for (int i = 0; i < maxPointNum; i++) {
            Vector3 v3 = Camera.main.WorldToScreenPoint(worldPos[i]);
            screenPos[i] = new Vector4(v3.x, v3.y, v3.z, 0);

        }

        //Detect if 3d point is behind the camera, if you stop drawing
        for (int i = 0; i < currentpointNum; i++) {
            if (Vector3.Dot(worldPos[i] - Camera.main.transform.position, Camera.main.transform.forward) <= 0) {
                pointNum2Shader = 0;
                break;
            }
            pointNum2Shader = currentpointNum;
        }
    }

    //Grab the current rendering of image processing
    void OnRenderImage(RenderTexture src, RenderTexture dest) {
        Graphics.Blit(src, dest, mat);
    }    

    void OnGUI () {
        float btnWidth = 100;
        float btnHeight = 50;
        float y = 150;
        if (GUI.Button(new Rect(100, y, btnWidth, btnHeight), "Crop")) {
            Vector2[] vertices2D = new Vector2[maxPointNum]; 
            for (int i = 0; i < currentpointNum; i++) {
                vertices2D[i].x = worldPos[i].x;
                vertices2D[i].y = worldPos[i].y;
            }

            // Use the triangulator to get indices for creating triangles
            Triangulator tr = new Triangulator(vertices2D);
            int[] indices = tr.Triangulate();

            GameObject plane = GameObject.Find("Plane");
            MeshFilter filter = plane.GetComponent<MeshFilter>();
            Vector3[] vertices = filter.mesh.vertices;

            // Vector2[] texCoords = new Vector2[currentpointNum];
            // for(int i = 0; i < currentpointNum; i++) {
            //     //There should be as many texture coordinates as vertices.
            //     //This example does not support textures, so fill with zeros
            //     texCoords[i] = new Vector2(vertices[i].x, vertices[i].y);
            // }

            // Create the mesh
            Mesh msh = new Mesh();
            msh.vertices = worldPos;
            msh.triangles = indices;
            msh.RecalculateNormals();
            msh.RecalculateBounds();
            filter.mesh = msh;
        }
    }
}

Polygon.shader file:

Shader "Unlit/polygon"
{
    Properties  
    {  
        //Define basic properties can be set from inside the editor variable  
        //_MainTex ("Texture", 2D) = "white" {}  
    }  

    CGINCLUDE
// Upgrade NOTE: excluded shader from DX11 because it uses wrong array syntax (type[size] name)
#pragma exclude_renderers d3d11
            //Incoming vertices function from the application data structure definitions 
            struct appdata  
            {  
                float4 vertex : POSITION;  
                float2 uv : TEXCOORD0;  
            };  
            //Incoming segment from a vertex function from the data structure definitions  
            struct v2f  
            {  
                float2 uv : TEXCOORD0;  
                float4 vertex : SV_POSITION;  
            };  
            //Define mapping variables  
            sampler2D _MainTex;  
            // float4 _MainTex_ST;  

            //Define variables for communicating with the script
            uniform float4 Value[6]; 
            int PointNum = 0;

            //Function that calculates the distance between two points
            float Dis(float4 v1,float4 v2)
            {
                return sqrt(pow((v1.x-v2.x),2)+pow((v1.y-v2.y),2));
            }   

            //Draw line segments
            bool DrawLineSegment(float4 p1, float4 p2, float lineWidth,v2f i)
            {
                float4 center = float4((p1.x+p2.x)/2,(p1.y+p2.y)/2,0,0);
                //Calculate distance between point and line  
                float d = abs((p2.y-p1.y)*i.vertex.x + (p1.x - p2.x)*i.vertex.y +p2.x*p1.y -p2.y*p1.x )/sqrt(pow(p2.y-p1.y,2) + pow(p1.x-p2.x,2));  
                //When less than or equal to half the line width, which belongs to the linear range, return true  
                float lineLength = sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));
                if(d<=lineWidth/2 && Dis(i.vertex,center)<lineLength/2)  
                {  
                    return true;  
                }  
                return false;
            }

            //To draw a polygon, this limits the number of vertices is not more than 6. You can change.
            bool pnpoly(int nvert, float4 vert[6], float testx, float testy)
            {

                int i, j;
                bool c=false;
                float vertx[6];
                float verty[6];

                for(int n=0;n<nvert;n++)
                {
                    vertx[n] = vert[n].x;
                    verty[n] = vert[n].y;
                }
                for (i = 0, j = nvert-1; i < nvert; j = i++) {
                if ( ((verty[i]>testy) != (verty[j]>testy)) && (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
                c = !c;
                }
                return c;
            }

            v2f vert (appdata v)  
            {  
                v2f o;  
                //Object vertices from model space to the camera cut space, or you can use the shorthand way:
                //o.vertex = UnityObjectToClipPos(v.vertex);  
                o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);  
                //2D UV coordinate transformation can also use shorthand methods
                //o.uv = TRANSFORM_TEX(v.uv, _MainTex);  
                //o.uv = v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;  
                return o;  
            }             
            fixed4 frag (v2f i) : SV_Target  
            {  

                //Draw a polygon vertex
                for(int j=0;j<PointNum;j++)
                {
                    if(Dis(i.vertex, Value[j])<3)
                    {
                        return fixed4(1,0,0,0.5);
                    }
                }
                //Draws the edges of the polygon
                for(int k=0;k<PointNum;k++)
                {
                    if(k==PointNum-1)
                    {
                        if(DrawLineSegment(Value[k],Value[0],2,i))
                        {
                            return fixed4(1,1,0,0.5);
                        }
                    }
                    else
                    {
                        if(DrawLineSegment(Value[k],Value[k+1],2,i))
                        {
                            return fixed4(1,1,0,0.5);
                        }
                    }

                }
                //Within the filled polygon
                if(pnpoly(PointNum, Value,i.vertex.x ,i.vertex.y))
                {
                    return fixed4(0,1,0,0.3);
                }
                return fixed4(0,0,0,0);
                //fixed4 col = tex2D(_MainTex, i.uv); 
                //return col;  
            }  
    ENDCG

    SubShader  
    {  
        Tags { "RenderType"="Opaque" }  
        LOD 100  
        Pass  
        {  
            //Select Alpha blend mode  
            Blend  SrcAlpha OneMinusSrcAlpha  
            //In the CGPROGRAM block of code to write your own processes
            CGPROGRAM  
            //Defined segment function entry and vertex function respectively, Vert and Frag  
            #pragma vertex vert  
            #pragma fragment frag  
            //Contains the basic files, there are some macro definitions and basic functions  
            #include "UnityCG.cginc"               

            ENDCG  
        }  
    }  
}

Pink appearance means your build has missing material assignments on the mesh renderer component or missing shader in the build.

If you are assigning materials or shaders at runtime, make sure you include the shader in the build.

You can force unity to include any shader by adding it to the list in Edit/Project Settings/Graphics

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM