OpenGL có được phác thảo của nhiều đối tượng chồng chéo


10

Tôi vừa có một ý tưởng cho trò chơi đang diễn ra của mình được thực hiện bằng opengl trong c ++: Tôi muốn có một phác thảo lớn (5-6 pixel) trên nhiều đối tượng chồng chéo khi người chơi giành được thứ gì đó.

Tôi nghĩ cách tốt nhất là sử dụng bộ đệm stpson nhưng chỉ vài giờ tôi đã cố gắng thực hiện một số kết xuất ngoài màn hình của bộ đệm stpson và tôi không thể đạt được bất kỳ loại kết quả nào như vậy. Có một số kỹ thuật khác!

Đây là những gì tôi muốn nhận được:

nhập mô tả hình ảnh ở đây

Có ý kiến ​​gì không?


Sử dụng bộ lọc phát hiện cạnh, điền vào các cạnh bằng các vạch màu dày, sau đó trích xuất các hình ảnh được hiển thị của các hình dạng và lớp phủ trên lớp lớp màu?
Shotgun Ninja

ý nghĩa của bạn với bộ lọc phát hiện cạnh là gì? một shader? một bộ lọc xử lý hình ảnh? như opencv (kết xuất thành kết cấu, áp dụng bộ lọc cho kết cấu, đẩy lùi kết cấu đã sửa đổi)?
nkint

Tôi không có ý kiến; Tôi không rành về dựng hình 3d để bắt đầu.
Shotgun Ninja

Bạn có một số ví dụ về một bộ đệm stpson như thế này? Tôi nghĩ rằng sử dụng bộ đệm stpson sẽ là cách sạch hơn nhưng tôi không thể làm cho bất kỳ bộ đệm
stpson

Câu trả lời:


4
  1. Kích hoạt và xóa bộ đệm stpson.
  2. Vẽ các đối tượng, thiết lập bộ đệm stpson. Đối tượng có thể bán trong suốt, vv
  3. Bây giờ, đặt chế độ stprint thành chỉ ghi các pixel mà stprint không được đặt.
  4. Và vẽ từng đối tượng một lần nữa, tăng tỷ lệ một chút, trong màu viền mong muốn và không có họa tiết.
  5. Vô hiệu hóa bộ đệm stpson.

Đây là mã được điều chỉnh từ một số mã stGL webGL mà tôi đã làm việc:

// drawing will set stencil stencil
    gl.enable(gl.STENCIL_TEST);
    gl.stencilFunc(gl.ALWAYS,1,1);
    gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
    gl.stencilMask(1);
    gl.clearStencil(0);
    gl.clear(gl.STENCIL_BUFFER_BIT);
// draw objects
for(var object in objects)
  objects[object].draw();
// set stencil mode to only draw those not previous drawn
    gl.stencilFunc(gl.EQUAL,0,1);
    gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
    gl.stencilMask(0x00);
// draw object halo
for(var object in objects)
  objects[object].drawHalo(1.1,red); // each mesh should be individually scaled e.g. by 1.1
// done
    gl.disable(gl.STENCIL_TEST);

Tôi nghĩ rằng tôi đã sử dụng phương pháp này trong các trò chơi RTS để vẽ halos xung quanh các đơn vị được chọn, nhưng đã lâu rồi và tôi không nhớ nếu có bất kỳ vấn đề nào và tất cả các sắc thái.


Bạn có một số ví dụ về một bộ đệm stpson như thế này? Tôi nghĩ rằng sử dụng bộ đệm stpson sẽ là cách sạch hơn nhưng tôi không thể làm cho bất kỳ bộ đệm
stpson

7
Lưu ý rằng việc hiển thị các đối tượng được tăng tỷ lệ một chút sẽ không dẫn đến độ dày đường đồng nhất. Cạnh xa hơn sẽ mỏng hơn. Nếu bạn tính đến điều này khi chia tỷ lệ các đối tượng, các đối tượng dài kéo dài ra khoảng cách sẽ có độ dày không đồng đều. Có thêm một chút hiệu ứng này để có được những đường nét đẹp và đồng đều.
Sean Middleditch

2
Tốt hơn là đơn giản nhân rộng các đối tượng là viết một shader đỉnh bù cho mỗi đỉnh một khoảng cách ngắn dọc theo bình thường của nó. Điều đó hoạt động khá tốt cho các đối tượng trơn tru, nhưng nó sẽ tạo ra các vết nứt trên các cạnh cứng. Bạn có thể thử xây dựng lưới với một bộ quy tắc xen kẽ được làm mịn ở mọi nơi và xem nơi nào đưa bạn đến.
Nathan Reed

2

Bắt đầu bằng cách tìm tất cả các nhóm đối tượng, trong đó một nhóm đối tượng là một tập hợp các đối tượng trùng nhau. Phát hiện va chạm tiêu chuẩn nên làm công việc. Chỉ định cho mỗi nhóm một màu duy nhất. Bất kỳ màu nào sẽ làm.

Kết xuất tất cả các đối tượng của bạn dưới dạng màu đơn sắc, sử dụng màu nhóm, thành một kết cấu.

Tạo một kết cấu phác thảo mới với cùng kích thước với mục tiêu kết xuất. Quét qua từng texel của mục tiêu kết xuất và xác định xem đó có phải là màu khác với bất kỳ texels xung quanh nào không. Nếu có, thay đổi texel tương ứng trong kết cấu phác thảo thành màu đường bạn muốn.

Cuối cùng, lấy kết cấu phác thảo này và hiển thị nó trên đầu của hình ảnh bạn muốn vẽ trên màn hình (tất nhiên bạn có thể làm điều này cùng lúc với phát hiện cạnh trong một shader mảnh và tránh tạo kết cấu cạnh trong lần đầu tiên địa điểm).

Nếu bạn thực hiện bước này trên cpu bằng cách sử dụng vòng lặp for để đi qua các texels của mục tiêu kết xuất, thì điều này sẽ khá chậm, nhưng có lẽ đủ tốt để kiểm tra và thậm chí sử dụng trong một số trường hợp. Để sử dụng điều này trong thời gian thực, bạn sẽ tốt nhất để xử lý việc này trong một shader.

Một shader mảnh để thực hiện phát hiện cạnh này có thể trông như thế này;

precision mediump float;

uniform sampler2D s_texture;

varying vec2 v_texCoord;

void main()
{
    gl_FragColor = vec4(0.0);

    vec4 baseColor = texture2D(s_texture, v_texCoord);
    gl_FragColor += baseColor - texture2D(s_texture, top);
    gl_FragColor += baseColor - texture2D(s_texture, topRight);
    gl_FragColor += baseColor - texture2D(s_texture, right);
    gl_FragColor += baseColor - texture2D(s_texture, bottomRight);
    gl_FragColor += baseColor - texture2D(s_texture, bottom);
    gl_FragColor += baseColor - texture2D(s_texture, bottomLeft);
    gl_FragColor += baseColor - texture2D(s_texture, left);
    gl_FragColor += baseColor - texture2D(s_texture, topLeft);
}

Trong đó giá trị thứ hai trong texture2D tra cứu là tọa độ 2d so với v_texCoord. Bạn sẽ áp dụng điều này bằng cách hiển thị mục tiêu kết xuất đầu tiên dưới dạng kết cấu trên một màn hình toàn màn hình. Điều này tương tự như cách bạn sẽ áp dụng các hiệu ứng làm mờ toàn màn hình như làm mờ guassian.

Lý do để sử dụng mục tiêu kết xuất đầu tiên với màu sắc đơn giản chỉ để đảm bảo rằng không có cạnh nhận biết giữa các đối tượng khác nhau trùng nhau. Nếu bạn chỉ đơn giản thực hiện phát hiện cạnh trên hình ảnh màn hình, bạn có thể sẽ thấy rằng nó cũng phát hiện các cạnh ở các phần chồng lấp (giả sử các đối tượng có màu sắc / kết cấu / ánh sáng khác nhau).


2
xin lỗi nhưng bạn có ý nghĩa gì với "Quét qua từng texel"? một vòng lặp cho mỗi pixel? trong cpu? Vì vậy, nó là một cái gì đó như: kết xuất với một màu sắc rắn vào một kết cấu, chuyển hình ảnh vào cpu, quét, đặt chúng một lần nữa trong kết cấu? hoặc làm điều đó trong một shader?
nkint

Tốt nhất là thực hiện nó trong một shader bằng cách hiển thị một quad toàn màn hình bằng cách sử dụng mục tiêu kết xuất làm kết cấu, theo cách tương tự như thực hiện hiệu ứng làm mờ quá trình bài, nhưng bạn có thể làm cho nó hoạt động trên cpu trước bằng một vòng lặp for, chỉ để xem nếu nó hoạt động đủ tốt
OriginalDaemon
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.