2011-11-20 30 views
9

Tôi có một trò chơi chạy khá tốt (55-60fps) trên màn hình võng mạc. Tôi muốn thêm lớp phủ toàn màn hình kết hợp với cảnh hiện có. Tuy nhiên, ngay cả khi sử dụng một kết cấu nhỏ, hiệu suất hit là rất lớn. Có tối ưu hóa tôi có thể thực hiện để làm cho điều này có thể sử dụng được không?Hiệu suất trúng từ pha trộn quad lớn

Nếu tôi sử dụng kết cấu 80x120 (kết cấu được hiển thị khi đang di chuyển, đó là lý do tại sao nó không vuông), tôi nhận được 25-30FPS. Nếu tôi làm cho kết cấu nhỏ hơn, hiệu suất tăng lên, nhưng chất lượng không được chấp nhận. Nói chung, mặc dù, chất lượng của lớp phủ không phải là rất quan trọng (nó chỉ là ánh sáng).

Sử dụng trình kết xuất ở mức 99%.

Thậm chí nếu tôi sử dụng kết cấu hình vuông từ tệp (.png), hiệu suất kém.

Đây là cách tôi có thể tạo các kết cấu:

[EAGLContext setCurrentContext:context]; 

    // Create default framebuffer object. 
    glGenFramebuffers(1, &lightFramebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, lightFramebuffer); 

    // Create color render buffer and allocate backing store. 
    glGenRenderbuffers(1, &lightRenderbuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, lightRenderbuffer); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, LIGHT_WIDTH, LIGHT_HEIGHT); 

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, lightRenderbuffer); 

    glGenTextures(1, &lightImage); 
    glBindTexture(GL_TEXTURE_2D, lightImage); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, LIGHT_WIDTH, LIGHT_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightImage, 0); 

Và đây là vẽ ...

/* Draw scene... */ 

glBlendFunc(GL_ONE, GL_ONE); 


//Switch to offscreen texture buffer 
glBindFramebuffer(GL_FRAMEBUFFER, lightFramebuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, lightRenderbuffer); 
glViewport(0, 0, LIGHT_WIDTH, LIGHT_HEIGHT); 

glClearColor(ambientLight, ambientLight, ambientLight, ambientLight); 
glClear(GL_COLOR_BUFFER_BIT); 

/* Draw lights to texture... */ 

//Switch back to main frame buffer 
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 
glViewport(0, 0, framebufferWidth, framebufferHeight); 

glBlendFunc(GL_DST_COLOR, GL_ZERO); 

glBindTexture(GL_TEXTURE_2D, glview.lightImage);  

/* Set up drawing... */ 

glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, 0); 

Dưới đây là một số tiêu chuẩn tôi mất khi cố gắng thu hẹp vấn đề. 'Không pha trộn' có nghĩa là tôi glDisable (GL_BLEND) trước khi tôi vẽ quad. 'Không chuyển đổi bộ đệm' nghĩa là tôi không chuyển đổi qua lại từ bộ đệm ngoài màn hình trước khi vẽ.

(Tests using a static 256x256 .png) 
No blend, No buffer switching: 52FPS 
Yes blend, No buffer switching: 29FPS //disabled the glClear, which would artificially speed up the rendering 
No blend, Yes buffer switching: 29FPS 
Yes blend, Yes buffer switching: 27FPS 

Yes buffer switching, No drawing: 46FPS 

Mọi trợ giúp đều được đánh giá cao. Cảm ơn!

CẬP NHẬT

Thay vì pha trộn toàn bộ lightmap sau đó, tôi đã kết thúc viết một Shader để làm việc một cách nhanh chóng. Mỗi mẫu mảnh và hỗn hợp từ lightmap (loại giống như multitexturing). Lúc đầu, hiệu suất đạt được là tối thiểu, nhưng sau đó tôi sử dụng một sampler2d lowp cho bản đồ ánh sáng, và sau đó tôi nhận được khoảng 45FPS.

Đây là shader đoạn:

lowp vec4 texColor = texture2D(tex, texCoordsVarying); 
lowp vec4 lightColor = texture2D(lightMap, worldPosVarying); 
lightColor.rgb *= lightColor.a; 
lightColor.a = 1.0; 

gl_FragColor = texColor * color * lightColor; 
+0

Tôi nghi ngờ 'glView' đệm công tắc có thể là thủ phạm ở đây. Điều gì đang xảy ra trong những phương pháp đó? Tại sao không sử dụng 'glBindRenderBuffer'? – Justicle

+0

Tôi sẽ nội tuyến các phương pháp để làm rõ. – whooops

+0

Ok để debuf vấn đề perf, hãy thử trước khi rendering lớp phủ (chỉ cần để nó tĩnh cho bây giờ), và sau đó sao chép vào bộ đệm chính mỗi khung. Điều đó sẽ ít nhất cho bạn biết nếu các bộ đệm chuyển mạch chậm (tức là làm hai cuộc gọi đến glBindFrame, glBindRender, glViewport mỗi khung). – Justicle

Trả lời

3

Ok Tôi nghĩ rằng bạn đã chạy lên chống lại những hạn chế của phần cứng. Việc pha trộn một quad có kích thước màn hình trên toàn bộ khung cảnh có lẽ là một trường hợp đặc biệt xấu đối với phần cứng dựa trên nền. PowerVR SGX (trên iPhone) được tối ưu hóa để loại bỏ bề mặt ẩn, để tránh vẽ những thứ khi không cần thiết. Nó có băng thông bộ nhớ thấp vì nó được tối ưu hóa cho thiết bị công suất thấp.

Vì vậy, màn hình quad có kích thước màn hình được đọc rồi viết mọi đoạn trên màn hình. Ouch!

Tốc độ tăng tốc glClear có liên quan - bởi vì bạn đang nói GL, bạn không quan tâm đến nội dung của bộ đệm sau trước khi hiển thị, giúp lưu nội dung trước đó vào bộ nhớ.

Có một cái nhìn tổng quan rất tốt về phần cứng iOS ở đây: http://www.imgtec.com/factsheets/SDK/POWERVR%20SGX.OpenGL%20ES%202.0%20Application%20Development%20Recommendations.1.1f.External.pdf

Đối với một giải pháp thực tế - Tôi sẽ cố gắng trực tiếp render lớp phủ của bạn trên sân khấu trò chơi.

Ví dụ, bạn làm cho vòng lặp sẽ giống như thế:

[EAGLContext setCurrentContext:context]; 

// Set up game view port and render the game 
InitGameViewPort(); 
GameRender(); 

// Change camera to 2d/orthographic, turn off depth write and compare 
InitOverlayViewPort() 

// Render overlay into same buffer 
OverlayRender() 
+0

Cảm ơn. Yea, tôi đến cùng một kết luận. Thật không may, tôi không thể sử dụng giải pháp của bạn-- lớp phủ tôi vẽ thực sự nhiều hơn một bản đồ ánh sáng, do đó, nó ảnh hưởng đến pixel môi trường trò chơi thực tế. Tôi đã kết thúc viết một shader để làm công việc tương tự, với thành công khá tốt. Tôi sẽ đăng các chi tiết về điều đó trong câu hỏi của tôi. Cảm ơn tất cả sự trợ giúp của bạn về điều tra này! – whooops

+0

Tuyệt vời - Tôi rất muốn xem những gì bạn đã làm. – Justicle

+0

Tôi đang sử dụng quad có kích thước màn hình được pha trộn trên toàn bộ cảnh trong trò chơi của mình và không giảm tốc độ khung hình (30 khung hình/giây trong 3G, 60 giây ở võng mạc). Sự chậm lại có thể là trong việc tạo ra các kết cấu? bạn đang làm nó mỗi khung hình? – led42

1

Nếu bạn trả cho một mục tiêu hiển thị trên một chip PowerVR, chuyển sang làm cho mục tiêu và đưa ra, sau đó chuyển trở lại bất kỳ làm cho mục tiêu trước bạn sẽ bị ảnh hưởng lớn. Kiểu truy cập này được gắn nhãn là "Bộ đệm tải logic" bởi Máy phân tích OpenGL ES được tích hợp vào các Thiết bị mới nhất.

Nếu bạn chuyển đổi thứ tự hiển thị của mình để bạn vẽ mục tiêu hiển thị ánh sáng trước, sau đó hiển thị khung cảnh của bạn thành bộ đệm khung chính, sau đó thực hiện kết hợp toàn màn hình của bạn.

0

Tôi có thể xác nhận, trên iPad 1 sử dụng iOS 4.2, bật/tắt GL_BLEND cho một quad toàn màn hình được bật giữa 18 và 31 khung hình/giây. Trong cả hai lần chạy, việc sử dụng trình kết xuất đồ họa là 90-100%.

0

Thậm chí trước khi nghịch với kết cấu, hãy đảm bảo rằng trình đổ bóng của bạn được tối ưu hóa. Khi lấp đầy màn hình 960x640 (614400 pixel), bất kỳ thao tác nào trong trình đổ bóng phân đoạn đều có tác động rất lớn.

Một điều tốt để tạo phiên bản cụ thể của trình đổ bóng đoạn của bạn cho trường hợp này. Nó phải là một cái gì đó như thế này:

varying mediump vec2 vertexTexCoord; 
uniform sampler2D texture; 

void main() { 
    gl_FragColor = texture2D(texture, vertexTexCoord); 
} 

Tạo một chương trình khác với đoạn đổ bóng này và sử dụng nó trước khi vẽ quad lớn, sau đó khôi phục chương trình bình thường. IPhone 4 có khả năng render khoảng 7 màn hình full, 1: 1 cho mỗi khung hình với sự pha trộn, nhưng nó nhanh chóng giảm xuống còn khoảng 1 với một shader phức tạp hơn.

(Ngoài ra trong trường hợp của bạn, hãy cố gắng làm cho kết cấu lớp phủ của bạn trước, sau đó các yếu tố bình thường, sau đó kết cấu so với phần còn lại. Nó sẽ cải thiện hiệu suất bằng lãi đáng kể.)

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