简体   繁体   中英

Why does my Unity shading work strangely on a Mesh?

So for context, I create a mesh based on vertex and triangleindice data. Within the function I create a Polygon object, which basically holds an array of vertices who each have their individual colors attached along with its positioning (Although I use the same color for each vertex in this specific situation). It also has an array with triangleindice points alongside the vertices.

Edit : I also added calculation of normals and UV. UV should be irrelevant here seeing as I do not want to make use of textures but just proper lighting for the vertexcolors.

The Function:

   private void createPolyMesh()
    {
        bool multiplePolygons = false;
        
        for(int h = 0; h < protoData.Polygons.Count; h++) 
        {
            PolygonData.Data.Types.Polygon polygon = protoData.Polygons[h];

            Vector3[] polyVertices = new Vector3[polygon.Vertex.Count];
            int[] triangles = new int[(polygon.TriangleIndices.Count * 3)];
            Color[] colors = new Color[polygon.Vertex.Count];
            Vector2[] uvs = new Vector2[polygon.Vertex.Count];
            Vector3[] normals = new Vector3[polygon.Vertex.Count];

            GameObject polyObject = new GameObject("Polygon " + h);
            Mesh polyMesh = new Mesh();
            polyObject.AddComponent<MeshFilter>().mesh = polyMesh;
            polyObject.AddComponent<MeshRenderer>();
            
            for(int i = 0; i < polygon.Vertex.Count; i++) {
                polyVertices[i] = new Vector3(polygon.Vertex[i].Point.X, polygon.Vertex[i].Point.Y, polygon.Vertex[i].Point.Z);
                uvs[i] = new Vector2(polyVertices[i][0], polyVertices[i][2]);
                colors[i] = new Color(polygon.Vertex[i].Color.R, polygon.Vertex[i].Color.G, polygon.Vertex[i].Color.B, polygon.Vertex[i].Color.A);
            }

            for(int j = 0; j < polygon.TriangleIndices.Count; j++) {
                int k = (j + (j * 2));
                triangles[k] = (int)polygon.TriangleIndices[j].A;
                triangles[k + 1] = (int)polygon.TriangleIndices[j].B;
                triangles[k + 2] = (int)polygon.TriangleIndices[j].C;
            }

            for(int l = 0; l < polygon.Vertex.Count - 2; l++) {
                int m = (l + (l * 2));
                Vector3 p0 = polyVertices[l];
                Vector3 p1 = polyVertices[l+1];
                Vector3 p2 = polyVertices[l+2];

                normals[l] = (Vector3.Cross(p1-p0, p2-p0)).normalized;

            }

            polyMesh.vertices = polyVertices;
            polyMesh.uv = uvs;
            polyMesh.triangles = triangles;
            polyMesh.colors = colors;
            polyMesh.normals = normals;
            polyObject.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Custom/VertexColor"));

            TopologySetter topologySetter = new TopologySetter();
            topologySetter.addPolyMesh(polyObject.GetComponent<MeshFilter>().mesh);

            if(protoData.Polygons.Count > 1 && h == 0) 
            {
                GameObject model = new GameObject("Model");
                multiplePolygons = true;
            } 
            
            if(multiplePolygons) 
            {
                polyObject.transform.SetParent(GameObject.Find("Model").transform);
            }
        }
    }

Whenever I attach shaders the behaviour on the object seems very strange though. The.shader file for the abomination I used here looks as follows.

The Shader:

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Edit : This shader is a default template by unity

In the following two pictures you can see the difference between how the shader example should look and how it looks within the program.

The example:

着色器的外观

How it looks in game:

它看起来像什么

Edit: The normals seem to not wrap around the entire mesh properly for some reason?

*It is a 3d sphere, the background color for the camera has been set to black

The eventual answer to this appeared to be, me having to recalculate the normals after applying them through using the recalculateNormals() function on the mesh.

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