2012-10-29 23 views
5

Tôi tìm thấy nếu tôi xác định khoảng cách mặt phẳng xa cho ma trận phối cảnh là 1,000,000,000, thì tất cả đối tượng bên trong phạm vi đó sẽ bị cắt bớt. Phạm vi của 100,000,000 hoạt động tốt. Bất cứ ai cũng có thể giải thích điều này? Ý tôi là, nó vẫn không xấp xỉ số lượng phạm vi Max. Hay tôi sai về điều này? Đối với tính toán quan điểm tôi sử dụng thư viện GLM. Không có đường ống cố định cứng.OpenGL Far Plane cho các giá trị rất lớn clip mọi thứ

CẬP NHẬT: (JAVA) Perspective ma trận tính:

public static Mat4 perspective(float fovy, float aspect, float zNear, float zFar) { 
    float range = (float) (Math.tan(Math.toRadians(fovy/2.0f)) * zNear); 
    float left = -range * aspect; 
    float right = range * aspect; 
    float bottom = -range; 
    float top = range; 

    Mat4 res = new Mat4(0.0f); 

    res.matrix[0] = (2.0f * zNear)/(right - left); 
    res.matrix[5] = (2.0f * zNear)/(top - bottom); 
    res.matrix[10] = -(zFar + zNear)/(zFar - zNear); 
    res.matrix[11] = -1.0f; 
    res.matrix[14] = -(2.0f * zFar * zNear)/(zFar - zNear); 

    return res; 
    } 
+2

Không chắc tôi hiểu câu hỏi, nhưng một độ chính xác phao duy nhất có thể đại diện cho một ít hơn 7 chữ số thập phân. Số của bạn có 10 chữ số, vì vậy bất kỳ tọa độ nào chỉ khác nhau trong 3 chữ số cuối cùng là "giống nhau". Vì vậy, 999,999,950 có thể bị cắt bớt. Đó có phải là điều bạn thắc mắc không? – Damon

+1

Âm thanh như một vấn đề làm tròn hoặc thứ gì đó tương tự. Tất nhiên nó không vượt qua phạm vi float (nó thậm chí không vượt qua phạm vi int 32-bit). Nhưng chia cho số lượng lớn như vậy có thể biến mọi thứ thành 0. Tương tự như vậy khi thêm một số rất nhỏ vào số lượng lớn này (như trong 'gần + xa' hoặc' gần-xa' được thực hiện trong quá trình tính toán ma trận), con số nhiều khả năng nhất giữ nguyên. Nó cần phải được phân tích như thế nào ảnh hưởng đến tính toán của ma trận nói riêng. –

+0

Cảm ơn câu trả lời.Nhưng một anh chàng ở trên bạn nói ngược lại. –

Trả lời

8

gì bạn đang nhìn thấy là một vấn đề làm tròn do độ chính xác rất hữu hạn các số dấu chấm động.

Mặc dù số dấu phẩy động có rất lớn (đối với hầu hết các ứng dụng thực tế "vô hạn"), chúng có độ chính xác giới hạn thấp hơn số nguyên của cùng một kích thước. Độ chính xác duy nhất (32 bit) float có thể biểu thị ít hơn 7 chữ số thập phân. Bạn có thể có số lượng cực nhỏ hoặc lớn (nhỏ hơn và lớn hơn bạn có thể tưởng tượng), nhưng chúng vẫn chỉ có 7.22 chữ số thập phân hợp lệ.

Các con số chỉ biểu diễn bằng độ chính xác đơn float giữa 999.999.900 và 1000000100 là: 999.999.872, 999.999.936, 1000000000 và 1000000064. Bạn có thể dễ dàng xác minh điều này bằng cách đếm một biến số nguyên trong một vòng lặp for, đúc cho một biến float, và in nó.

Điều đó có nghĩa là ví dụ 999.999.950 và 999.999.951 và 999.999.999 là chính xác cùng một số, vì vậy 999.999.950 có thể bị cắt bớt mặc dù nó "rõ ràng" ở phía trước mặt cắt.

EDIT:

ít chương trình demo với sản lượng:

#include <stdio.h> 

int main() 
{ 
    float f = 0.0f; 
    for(int i = 999999900; i < 1000000100; ++i) 
    { 
     f = i; 
     printf("%d\t%f\n", i, f); 
    } 
    return 0; 
} 

999999900  999999872.000000 
999999901  999999872.000000 
999999902  999999872.000000 
999999903  999999872.000000 
999999904  999999872.000000 
999999905  999999936.000000 
999999906  999999936.000000 
999999907  999999936.000000 
... 
[some lines omitted] 
... 
999999967  999999936.000000 
999999968  1000000000.000000 
999999969  1000000000.000000 
999999970  1000000000.000000 
999999971  1000000000.000000 
999999972  1000000000.000000 
... 
[some lines omitted] 
... 
1000000028  1000000000.000000 
1000000029  1000000000.000000 
1000000030  1000000000.000000 
1000000031  1000000000.000000 
1000000032  1000000000.000000 
1000000033  1000000064.000000 
1000000034  1000000064.000000 
1000000035  1000000064.000000 
1000000036  1000000064.000000 
1000000037  1000000064.000000 
1000000038  1000000064.000000 
1000000039  1000000064.000000 
1000000040  1000000064.000000 
1000000041  1000000064.000000 
1000000042  1000000064.000000 
1000000043  1000000064.000000