Geometry Shader không tạo hình học cho một số Vertice


7

Tôi đang chơi với một shader hình học và tôi tự hỏi tại sao nó không tạo ra hình học cho mỗi đỉnh trong tất cả các lưới?

  • Tôi không nghĩ đây là vấn đề của Cull vì các đỉnh giống nhau tạo ra hình học khi bạn xoay quanh và thiết lập Cull Offkhông có gì thay đổi.
  • Một vấn đề khác có thể là nhân với số 0 ở đâu đó nhưng tôi đã cố gắng loại bỏ càng nhiều biến càng tốt và vẫn có vấn đề.
  • Một vấn đề không thể thứ ba có thể là giới hạn số lượng đầu ra ở đâu đó. Tôi đã không đặt bất cứ điều gì rõ ràng để cản trở điều đó.

Tôi nhận thấy vấn đề trên Cube (5/8) và Quad (2/4) nhưng dường như tạo ra tất cả các hình học tốt trên mặt phẳng, hình trụ, v.v ... Sau đây là một số kết quả từ việc sử dụng trình tạo bóng hình học xương trần.

Cube (gần nhất: Unity mặc định, quay lại: .fbxKhối xuất khẩu 4D ) :

Quad:

Nó dường như hoạt động tốt trên một mặt phẳng (cập nhật: Nó thực sự thiếu một hàng trên mỗi trục)

Mã Shader Unity GeometryShaderTest1.shader:

Lưu ý: Nếu bạn đang kiểm tra shader và không có gì hiển thị; Xoay máy ảnh của bạn xung quanh để các thông số đang quay đúng hướng để hiển thị.

Shader "Custom/GeometryShaderTest1" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _Amount ("Height Adjustment", Float) = 0.0
    }
    SubShader {
        Pass {
            Tags { "RenderType"="Opaque" }
            LOD 200

            CGPROGRAM
            #pragma target 5.0
            //#pragma addshadow
            #pragma vertex vert
            #pragma geometry GS_Main
            #pragma fragment frag
            #include "UnityCG.cginc"

            // Vert to geo
            struct v2g
            {
                float4 pos: POSITION;
            };

            // geo to frag
            struct g2f
            {
                float4 pos: POSITION;
            };


            // Vars
            fixed4 _Color;
            float _Amount;


            // Vertex modifier function
            v2g vert(appdata_base v) {

                v2g output = (v2g)0;
                output.pos = mul(_Object2World, v.vertex);
                // Just testing whether all vertices affected
                output.pos.y -= _Amount;

                return output;
            }

            // GS_Main(point v2g p[1], inout TriangleStream<g2f> triStream)
            // GS_Main(line v2g p[2], inout TriangleStream<g2f> triStream)
            // GS_Main(triangle v2g p[3], inout TriangleStream<g2f> triStream)
            [maxvertexcount(4)]
            void GS_Main(point v2g p[1], inout TriangleStream<g2f> triStream)
            {
                float4 v[4];

                float3 asdfUp = float3(0, 1, 0);
                float3 asdfRight = float3(0, 0, 1);
                v[0] = float4(p[0].pos + 0.25 * asdfRight - 0.25 * asdfUp, 1.0f);
                v[1] = float4(p[0].pos + 0.25 * asdfRight + 0.25 * asdfUp, 1.0f);
                v[2] = float4(p[0].pos - 0.25 * asdfRight - 0.25 * asdfUp, 1.0f);
                v[3] = float4(p[0].pos - 0.25 * asdfRight + 0.25 * asdfUp, 1.0f);

                float4x4 vp = mul(UNITY_MATRIX_MVP, _World2Object);
                g2f pIn;
                pIn.pos = mul(vp, v[0]);
                triStream.Append(pIn);

                pIn.pos = mul(vp, v[1]);
                triStream.Append(pIn);

                pIn.pos = mul(vp, v[2]);
                triStream.Append(pIn);

                pIn.pos = mul(vp, v[3]);
                triStream.Append(pIn);
            }

            fixed4 frag(g2f input) : COLOR {
                return float4(1.0, 0.0, 0.0, 1.0); 
            }

            ENDCG
        }


    }

    FallBack "Diffuse"
}

Tài nguyên shader hình học:

Câu trả lời:


2

Từ wiki OpenGL :

Kiểu input_primitive phải khớp với kiểu nguyên thủy được sử dụng với lệnh vẽ kết xuất với chương trình đổ bóng này.

Được, Unity có thể đang sử dụng DirectX trên Windows, nhưng điều tương tự cũng đúng. Bởi vì shader của bạn đang yêu cầu một điểm, nó chỉ lấy điểm đầu tiên từ mỗi nguyên thủy và bỏ qua phần còn lại.

Giả sử Unity vẽ bằng các hình tam giác, bạn cần thay đổi tham số đầu tiên để nhận thông số đó, đặt maxvertexcountthành 12 và tạo ba hình tứ giác thay vì một hình. Ví dụ nhanh:

[maxvertexcount(12)]
void GS_Main(triangle v2g p[3], inout TriangleStream<g2f> triStream)
{
    for(int i = 0; i < 3; i++)
    {
        // generate a quad with p[i]

        triStream.RestartStrip();
    }
}

5

Các nguyên thủy đầu vào, aka. lưới đưa vào shader, có mộtMeshTopology cài đặt có thể được điều chỉnh theo mã. Câu trả lời được chấp nhận hoạt động vì nguyên thủy đầu vào mặc định cho một lưới (bao gồm các lưới được nhập) là triangle/ MeshTopology.Triangles.

Nhưng nếu bạn sử dụng MeshTopology.Triangles , bạn sẽ tạo ra nhiều hình học hơn mức cần thiết cho trình đổ bóng. Bởi vì một đỉnh duy nhất có thể là một phần của nhiều hình tam giác, bạn sẽ có các bảng quảng cáo trên đầu các bảng quảng cáo khác. Bạn sẽ không nhận thấy nó một cách trực quan, bởi vì chúng trùng nhau hoàn hảo, nhưng nó sẽ làm bạn mất hiệu suất. Shader mảnh sẽ làm việc trên hình học trùng lặp mà không có lý do.

Thay vào đó, bạn nên sử dụng point / MeshTopology.Pointslàm nguyên thủy đầu vào của mình, như trình đổ bóng ban đầu của bạn đã làm, sau đó báo cho Unity vẽ bằng các điểm thay vì hình tam giác.

Bạn có thể sử dụng Mesh.SetIndicesđể điều chỉnh cấu trúc liên kết của lưới và sau đó trình đổ bóng ban đầu của bạn sẽ hoạt động tốt.

using UnityEngine;

public class UsePointTopologyMeshMode : MonoBehaviour {

    [ContextMenu("ConvertToPointTopology")]
    void ConvertToPointTopology() {
        Mesh mesh = GetComponent<MeshFilter>().mesh;
        int[] indices = new int[mesh.vertices.Length];
        for (int i = 0; i < indices.Length; i++) {
            indices[i] = i;
        }
        mesh.SetIndices(indices, MeshTopology.Points, 0);
    }

    // Use this for initialization
    void Start () {
        ConvertToPointTopology();
    }
}

1
Câu hỏi là về các shader Geometry, không xây dựng các mắt lưới.
MLM

Câu trả lời của tôi là về việc thay đổi lệnh vẽ ảnh hưởng đến shader hình học, không xây dựng các mắt lưới.
Croolsby

Tôi xin lỗi, tôi đã hiểu nhầm câu trả lời của bạn. Đây là một chi tiết tuyệt vời về cách thay đổi nguyên thủy đầu vào và cách mối quan hệ này hoạt động. Tôi đã chỉnh sửa câu trả lời để xóa ngôn ngữ cho tôi và tôi hy vọng người xem trong tương lai.
MLM

Đừng lo lắng. Tôi đã không nhận ra nó không đủ rõ ràng ban đầu. Cảm ơn đã chỉnh sửa.
Croolsby
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.