有什麼區別,以及如何讓WebGL的罪與Math.sin產生相同的結果?Javascript「Math.sin」和WebGL「sin」之間的區別
編輯: 我有我的頂點着色器的一些代碼(這還不是全部的代碼),其計算圍繞球體斐波那契點應該放在頭頂上的這個新的現貨:
attribute float index;
float inc = 3.141592653589793238462643383279 * (3.0 - sqrt(5.0));
float off = 2.0/2500000;
float yy = index * off - 1.0 + (off/2.0);
float rr = sqrt(1.0 - yy * yy);
float phi = index* inc;
vec3 fibPoint = vec3(cos(phi) * rr, yy, sin(phi) * rr);
這是不行的,這讓我尷尬的頂點位置是這樣的:http://i.imgur.com/Z1crisy.png
如果我不是計算CPU在COS(PHI)和sin(PHI)與JavaScript的Math.sin和Math.cos它們扔作爲一個屬性,像這樣:
attribute float index;
attribute float sinphi;
attribute float cosphi;
float inc = 3.141592653589793238462643383279 * (3.0 - sqrt(5.0));
float off = 2.0/2500000;
float yy = index * off - 1.0 + (off/2.0);
float rr = sqrt(1.0 - yy * yy);
float phi = index* inc;
vec3 fibPoint = vec3(cosphi * rr, yy, sinphi * rr);
我得到了一個精美的分佈斐波納契像這樣:http://i.imgur.com/DeRoXkL.png
爲何,明明好像存在GLSL和Javascript之間的COS/SIN功能差一些的任何想法?披可以成爲相當大的數字,如「5476389.695241543」種大。也許這對GLSL的精度來說太大了?
編輯2:
vertexShader: [
"attribute float index;",
"attribute float cosphi;",
"attribute float sinphi;",
"attribute float displacementType;",
"uniform vec3 faceCorner;",
"uniform vec3 faceNormal;",
"uniform vec3 faceCenter;",
"varying vec2 vTexCoord;",
"void main()",
"{",
"vTexCoord = uv;",
// find fibonacci distribution of points on sphere
"float inc = 3.141592653589793238462643383279 * 0.7639320225002102;",
"float off = 0.0000008;",
"float yy = index* off - 1.0 + (off/2.0);",
"float rr = sqrt(1.0 - yy * yy);",
"float phi = index* inc;",
"vec3 fibPoint = vec3(cos(phi) * rr * -1.0, yy, sin(phi) * rr * -1.0);",
// intersecting face
"vec3 normalizedFaceNormal = normalize(faceNormal);",
"float planeConstant = - dot(faceCorner, normalizedFaceNormal);",
"float denominator = dot(normalizedFaceNormal, fibPoint);",
"float distanceToPlane = - planeConstant/denominator;",
"vec3 intersectPoint = normalize(fibPoint) * distanceToPlane;",
"intersectPoint = faceCenter;",
// displacement
"float buildingRadius = 3.0;",
"vec3 newPosition = position;",
"vec3 cornerVec = normalize(faceCorner - intersectPoint) * buildingRadius;",
// ground vertices
"if(displacementType == 0.0){",
"newPosition = intersectPoint + cornerVec;",
"} else if(displacementType == 1.0){",
"newPosition = cross(cornerVec, normalizedFaceNormal);",
"newPosition = intersectPoint + newPosition;",
"} else if(displacementType == 2.0){",
"newPosition = intersectPoint - cornerVec;",
"} else if(displacementType == 3.0){",
"newPosition = cross(normalizedFaceNormal, cornerVec);",
"newPosition = intersectPoint + newPosition;",
"} else {",
// roof vertices
"vec3 corner0 = intersectPoint + cornerVec;",
"vec3 corner1 = intersectPoint + cross(cornerVec, normalizedFaceNormal);",
"float UVdistance = length(corner0 - corner1);",
"float buildingHeight = UVdistance * 2.0;",
"vec3 roofCentroid = intersectPoint + normalizedFaceNormal * (-buildingHeight);",
"if(displacementType == 4.0){",
"newPosition = roofCentroid + cornerVec;",
"} else if(displacementType == 5.0){",
"newPosition = cross(cornerVec, normalizedFaceNormal);",
"newPosition = roofCentroid + newPosition;",
"} else if(displacementType == 6.0){",
"newPosition = roofCentroid - cornerVec;",
"} else {",
"newPosition = cross(normalizedFaceNormal, cornerVec);",
"newPosition = roofCentroid + newPosition;",
"}",
"}",
"gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition.xyz, 1.0);",
"}"
].join("\n"),
所以這一塊給錯誤的頂點位置,如果我改變 「COS(PHI)」 和 「罪(PHI)」,以COSPHI和sinphi,這是屬性,在CPU上計算,通過JavaScript的Math.sin(phi)和Math.cos(phi),然後代碼工作。建築物/立方體完好無損,因此,由於建築物/立方體放置在球體表面並具有正確的distanceToPlane,所以位移工作和相交工程。
回答玉米稈上gamedev.net:
大數量是一個問題。如果您的頂點着色器與32位浮點數一起使用,那麼它只能提供6位精度的十進制數字。 5476389.695241543至6精度的十進制數字是5476380.000000(截斷6位數字後的所有內容)。因爲sin/cos是週期性的,所以Pi只有〜3.14和 ,使用大數不會給你任何 的好處,因爲使用較小的數字(因爲大數字只是 環繞)。但是,您的號碼非常大,以致於它們幾乎環繞着 以至於它們甚至不精確映射到[-pi,pi](或[0, 2pi])範圍。基本上,周圍的包裹扔掉所有的「高」 數字,並只保留相關的低位數,但不幸的是,對於 ,你所有的低位數都是垃圾,因爲你把所有6位精度數字放在被扔掉的數字上,而現在你所有的 低(但最重要的)數字都沒有意義。
總之,是的,那些巨大的數字會殺了你。
但是,在JavaScript中,所有浮點數都是64位,其中 會爲您提供15位精度的十進制數字。這意味着在JavaScript中,您實際上可以正確代表5476389,即 。69524154,因此您的trig 計算實際上是準確的(假設您的JavaScript代碼爲 ,處理的頂點着色器的值相同)。
對於興趣,這裏的整個主題在上gamedev.net:http://www.gamedev.net/topic/645229-javascripts-%E2%80%9Cmathsinmathcos %E2%80%9D-and-webgls-%E2%80%9Csincos%E2%80%9D-give-different-results/ – Air