2012-01-25 33 views
6

Tôi đang làm việc trên trò chơi 2D iOS sử dụng OpenGL 2.0 và tôi tự hỏi liệu có thể viết bóng đổ để phác thảo hình ảnh với ánh sáng. Tất cả các hình ảnh là 2D sprites. Các ví dụ shader tôi đã thấy cho phác thảo là cho các đối tượng 3D, vì vậy tôi không chắc chắn nếu nó có thể cho hình ảnh 2D.OpenGL ES Shader để phác thảo hình ảnh 2D

+0

để ánh sáng bạn muốn thêm giống như bóng đổ? –

+0

Thêm nét vẽ xung quanh hình ảnh có các cạnh mềm. –

Trả lời

7

Bạn có chấp nhận bộ lọc phát hiện cạnh (chẳng hạn như Sobel), tạo ra hình ảnh như được hiển thị trong the Wikipedia article, tiếp theo là một hiệu ứng Gaussian blur trên đó để làm mềm các cạnh và cho nó nhiều ánh sáng hơn, sau đó tổng hợp hình ảnh đó vào cảnh của bạn? Trong thực tế, bạn có thể chỉ cần tái sử dụng các họa tiết 3d phác thảo mà bạn đã thấy - mặc dù bạn có thể lý thuyết kiểm tra đại lượng sâu (với một số nỗ lực mở rộng trong ES), mỗi cái tôi từng thấy chỉ là hiệu ứng 2d hình ảnh được hiển thị.

EDIT: khi xem xét kỹ hơn, Laplacian có thể dễ áp ​​dụng hơn Sobel vì nó có thể được thực hiện như một shader đổ bóng đơn giản (như được mô tả ở các địa điểm like this). Mặc dù an toàn trên thiết bị di động, bạn có thể muốn dính vào hạt nhân 3x3 nhiều nhất và viết một bóng đổ khác nhau cho từng hiệu ứng thay vì thực hiện với dữ liệu. Vì vậy, ví dụ: độ nhòe Gaussian mờ, được viết ra theo chiều dài:

void main() 
{ 
    mediump vec4 total = vec4(0.0); 
    mediump vec4 grabPixel; 

    total +=  texture2D(tex2D, texCoordVarying + vec2(-1.0/width, -1.0/height)); 
    total +=  texture2D(tex2D, texCoordVarying + vec2(1.0/width, -1.0/height)); 
    total +=  texture2D(tex2D, texCoordVarying + vec2(1.0/width, 1.0/height)); 
    total +=  texture2D(tex2D, texCoordVarying + vec2(-1.0/width, 1.0/height)); 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(0.0, -1.0/height)); 
    total += grabPixel * 2.0; 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(0.0, 1.0/height)); 
    total += grabPixel * 2.0; 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(-1.0/width, 0.0)); 
    total += grabPixel * 2.0; 

    grabPixel =  texture2D(tex2D, texCoordVarying + vec2(1.0/width, 0.0)); 
    total += grabPixel * 2.0; 

    grabPixel = texture2D(tex2D, texCoordVarying); 
    total += grabPixel * 4.0; 

    total *= 1.0/16.0; 

    gl_FragColor = total; 
} 

Và phát hiện cạnh Laplacian kết thúc trông giống nhau nhưng với các hằng số khác nhau. Để tối ưu hóa, bạn nên tìm ra các điểm lấy mẫu tương đối của bạn trong bóng đổ hơn là trong shader fragment càng nhiều càng tốt cho giới hạn về các thay đổi, vì làm như vậy sẽ tránh đọc kết cấu phụ thuộc.

+0

Có lẽ tôi không nhìn vào những cái 3D đúng, nhưng những cái tôi đã thấy dường như hoạt động trên nguồn ánh sáng ở một mức độ nào đó, mà tôi không cho nó là 2D. Tôi đã rất mới để shaders, vì vậy tôi có lẽ nhìn ra rõ ràng ở đây. –

+0

Rất nhiều trình đổ bóng tế bào Radio sau khi cài đặt máy bay phản lực sử dụng vị trí của máy ảnh để phát hiện các cạnh bằng cách xác định một cạnh là sự nối giữa cạnh về phía trước và cạnh quay ngược. Bạn rõ ràng sẽ không thể sử dụng một trong số đó. Nhưng các cách tiếp cận như Sobel và Laplacian tìm kiếm sự gián đoạn về màu sắc trong một hình ảnh 2d để phát hiện các cạnh, vì vậy hoàn toàn phù hợp. Nó có lẽ là thông minh để đọc lên trên các bộ lọc convolution, nếu bạn chưa có, sau đó điều tra các Laplacian và Gaussian blur. Tôi đã thêm một số mẫu mã được lắp ráp vội vàng cho sau này. – Tommy

Các vấn đề liên quan