Làm thế nào để một shader HLSL thực sự kết thúc ảnh hưởng đến đầu ra kết xuất?


11

Tôi hiểu cú pháp của HLSL, ví dụ: giả sử tôi có cái này là HLSL của tôi:

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

    output.position = position;
    output.position.xy *= 0.7f;    // "shrink" the vertex on the x and y axes
    output.color = color;

    return output;
}


float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

và tôi biên dịch nó như thế này:

D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

Làm thế nào để nó ... biết thay đổi ... Tôi bối rối về chính xác đường ống giữa HLSL và các pixel / đỉnh thực tế trên màn hình là gì.

Đây có phải là những gì thực sự "áp dụng" chúng?

dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);

Hãy nhớ rằng tôi giống như một người mới bắt đầu theo nghĩa đen . Ai đó có thể giải thích những gì nó đang làm? Tôi giả sử hàm HLSL đỉnh đi qua mọi đỉnh và sau đó thay đổi chúng thành bất cứ thứ gì tôi có trong hàm và đầu ra là thứ đã được thay đổi ... và tương tự cho trình đổ bóng pixel?

Một sự nhầm lẫn khác, tôi biết pixel là gì và tôi hiểu đỉnh là gì ... nhưng chính xác thì pixel shader làm gì?


Không sao, không ai làm thế
bobobobo

Câu trả lời:


10

Nó như thế nào ...... biết thay đổi .... Tôi bối rối chính xác tại đường ống giữa HLSL và Pixels / Vertex thực tế trên màn hình.

Nó hoạt động gần giống như thế này: khi bạn thực hiện lệnh gọi rút thăm (DrawPrimologists, DrawIndexedPrimologists trong D3D, Draw in 10+, et cetera), dữ liệu hình học bạn đã liên kết với đường ống (bộ đệm đỉnh của bạn) được xử lý. Đối với mỗi đỉnh, trình tạo bóng đỉnh được thực thi để tạo ra một đỉnh đầu ra trong không gian clip.

GPU sau đó thực hiện một số chức năng cố định trên đỉnh không gian clip đó, chẳng hạn như cắt / loại bỏ và đưa đỉnh vào không gian màn hình, nơi nó bắt đầu raster các hình tam giác. Trong quá trình raster hóa từng tam giác, GPU sẽ nội suy các thuộc tính đỉnh trên bề mặt của tam giác đó, cung cấp từng thuộc tính được nội suy cho trình đổ bóng pixel để tạo ra màu bán kết cho pixel đó (pha trộn được áp dụng sau khi trình tạo bóng pixel thực hiện, do đó "bán sau cùng").

đây có phải là những gì thực sự "áp dụng" chúng:

Mã bạn đã đăng đầu tiên biên dịch các shader, sau đó liên kết chúng với đường ống nơi chúng vẫn hoạt động cho bất kỳ lệnh gọi tiếp theo nào cho đến khi thay đổi. Nó không thực sự khiến chúng bị xử tử.

Ai đó có thể giải thích những gì nó đang làm không, giả sử chức năng VertSL HLSL đi qua mọi đỉnh (như Vị trí đầu vào: VỊ TRÍ và màu sắc: MÀU SẮC) và sau đó thay đổi chúng thành bất cứ điều gì tôi có trong chức năng và đầu ra là những gì đã được thay đổi. ... (Tương tự với Pixel Shader).

Một sự nhầm lẫn khác, tôi biết pixel là gì và tôi hiểu đỉnh là gì ..... nhưng chính xác thì Pixel shader làm gì ......

Trình tạo bóng đỉnh có nhiệm vụ chuyển đổi các đỉnh từ không gian mô hình sang không gian clip.

Trình đổ bóng pixel chịu trách nhiệm tính toán màu sắc / độ sâu áp chót cho một pixel dựa trên các thuộc tính đỉnh được nội suy.


9

Tôi sẽ cố gắng giải thích cách mọi thứ hoạt động mà không sử dụng nhiều biệt ngữ.

Nếu sự đơn giản thay vì tốc độ tương tác là mối quan tâm của bạn, một bề mặt 3D trong máy tính sẽ chỉ là một đám mây điểm khổng lồ trong không gian, đủ dày đặc để chúng ta có thể chỉ hiển thị từng điểm riêng lẻ mà không có khoảng cách giữa chúng.

Bạn muốn lưu trữ một mô hình chỉ một lần trong bộ nhớ, nhưng bạn cần hiển thị nó ở nhiều kích cỡ khác nhau và từ nhiều góc độ khác nhau, vì vậy khi bạn kết xuất mô hình 3D, bạn cần "biến đổi" tất cả các điểm khi bạn đọc chúng từ bộ nhớ. Ví dụ: để hiển thị mô hình lớn hơn 50%, bạn cần chia tỷ lệ vị trí của các điểm bằng một nửa:

out.position = in.position * 0.5;
out.color = in.color;

Đây gần như là "shader đỉnh" đơn giản nhất mà người ta có thể hình dung: đi vào một vị trí đỉnh từ bộ nhớ, và đi ra một vị trí đỉnh mới, to bằng nửa. Đỉnh nửa lớn không được lưu trữ trở lại bộ nhớ - nó được sử dụng ngay lập tức để hiển thị và sau đó bị ném đi.

Mặc dù sự đơn giản hóa quá mức mà thiếu các khái niệm chính , nhưng về mặt tinh thần mô tả các khía cạnh về cách các bộ phim làm đồ họa.

Đồ họa tương tác (trò chơi) không thể đơn giản như vậy, bởi vì chúng cần kết xuất đồ họa nhanh hơn nhiều bậc so với phim.

Trong các trò chơi, chúng tôi không đủ khả năng hiển thị một điểm cho mỗi pixel trên màn hình, cộng với các tính năng bổ sung để che lấp các khoảng trống. Vì vậy, như một sự thỏa hiệp, khoảng cách giữa mỗi ba điểm gần đó được hiển thị dưới dạng một hình tam giác, vì nhiều lý do kỹ thuật khác nhau, nên có kích thước tối thiểu 10 pixel trên màn hình.

Một hình tam giác 3D có thể là chiếu lên màn hình 2D, sau đó được chia thành một chồng các dòng 1D, mỗi dòng có thể được chia thành một chồng các pixel 0D. Do đó, chúng ta có thể phân chia và chinh phục vấn đề hiển thị tam giác 3D thành vấn đề đơn giản hơn là hiển thị rất nhiều pixel 0D trong sự cô lập. Một máy tính có thể giải quyết các vấn đề đơn giản hơn trong thời gian ngắn hơn.

Một shader pixel là một chương trình nhỏ mà chúng ta chạy trên mỗi pixel để tạo ra từ việc tách rời một hình tam giác.

out.color = in.color;

Đây gần như là "pixel shader" đơn giản nhất mà người ta có thể hình dung: trong sự pha trộn màu sắc của ba đỉnh tam giác, và đi ra cùng một màu. Các đầu vào đến từ các đầu ra của "shader đỉnh" và các đầu ra được ghi vào màn hình trong bộ nhớ.

Vì vậy - "shader đỉnh" là một chương trình chạy bên trong chip GPU. Đầu vào của nó là "bộ đệm đỉnh" trong bộ nhớ GPU và đầu ra của nó được đưa trực tiếp vào "pixel shader". "Pixel shader" cũng là một chương trình chạy bên trong chip GPU. Đầu vào của nó là sự pha trộn của ba đỉnh từ trình tạo bóng đỉnh và đầu ra của nó là một pixel trên màn hình.



-2

Đừng lo lắng về một pixel shader ngay bây giờ. Nếu bạn là người mới bắt đầu, bạn chỉ nên chào thế giới GLSL / HLSL với các shader đỉnh và mảnh. Khi bạn đã quen thuộc và bạn bắt đầu hiểu chuyển động thay đổi và như vậy, sau đó mở rộng tầm nhìn của bạn.

Tôi đặc biệt khuyên dùng một cuốn sách văn bản để có được sự hài hước về cách thức hoạt động của API. Sách OpenGL cũng làm tốt công việc minh họa cách mọi thứ có thay đổi qua nhiều năm từ đường ống cố định sang đường ống lập trình động.

Đi vô địch!


1
Một shader mảnh hoàn thành chức năng tương tự như shader pixel.

1
Tôi không nghĩ chúng ta có thể nói từ câu hỏi liệu OP có phải là người mới bắt đầu trong tất cả các chương trình trò chơi hay không - anh ta chỉ nói rằng anh ta là người mới bắt đầu viết mã shader. Học để viết shaders là một công cụ rất quan trọng để có trong kho một nhà phát triển trò chơi, tôi sẽ không chỉ đơn thuần là che đậy chúng trừ khi bạn chỉ ở rất giai đoạn đầu của việc học phát triển trò chơi.
Olhovsky
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.