GPU: Floating point screen coordinates to eliminate vertex snapping
This commit is contained in:
@@ -74,9 +74,9 @@ bool face_visible(ivec4 vA, ivec4 vB, ivec4 vC, ivec4 position, int cameraYaw, i
|
|||||||
vB += position - cameraPos;
|
vB += position - cameraPos;
|
||||||
vC += position - cameraPos;
|
vC += position - cameraPos;
|
||||||
|
|
||||||
ivec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
vec3 sA = toScreen(vA.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||||
ivec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
vec3 sB = toScreen(vB.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||||
ivec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
vec3 sC = toScreen(vC.xyz, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||||
|
|
||||||
return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0;
|
return (sA.x - sB.x) * (sC.y - sB.y) - (sC.x - sB.x) * (sA.y - sB.y) > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ out float fogAmount;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ivec3 cameraPos = ivec3(cameraX, cameraY, cameraZ);
|
ivec3 cameraPos = ivec3(cameraX, cameraY, cameraZ);
|
||||||
ivec3 screenA = toScreen(vPosition[0] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
vec3 screenA = toScreen(vPosition[0] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||||
ivec3 screenB = toScreen(vPosition[1] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
vec3 screenB = toScreen(vPosition[1] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||||
ivec3 screenC = toScreen(vPosition[2] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
vec3 screenC = toScreen(vPosition[2] - cameraPos, cameraYaw, cameraPitch, centerX, centerY, zoom);
|
||||||
|
|
||||||
if (-screenA.z < 50 || -screenB.z < 50 || -screenC.z < 50) {
|
if (-screenA.z < 50 || -screenB.z < 50 || -screenC.z < 50) {
|
||||||
// the client does not draw a triangle if any vertex distance is <50
|
// the client does not draw a triangle if any vertex distance is <50
|
||||||
|
|||||||
@@ -26,22 +26,22 @@
|
|||||||
/*
|
/*
|
||||||
* Convert a vertex to screen space
|
* Convert a vertex to screen space
|
||||||
*/
|
*/
|
||||||
ivec3 toScreen(ivec3 vertex, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) {
|
vec3 toScreen(ivec3 vertex, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) {
|
||||||
int yawSin = int(65536.0f * sin(cameraYaw * UNIT));
|
float yawSin = sin(cameraYaw * UNIT);
|
||||||
int yawCos = int(65536.0f * cos(cameraYaw * UNIT));
|
float yawCos = cos(cameraYaw * UNIT);
|
||||||
|
|
||||||
int pitchSin = int(65536.0f * sin(cameraPitch * UNIT));
|
float pitchSin = sin(cameraPitch * UNIT);
|
||||||
int pitchCos = int(65536.0f * cos(cameraPitch * UNIT));
|
float pitchCos = cos(cameraPitch * UNIT);
|
||||||
|
|
||||||
int rotatedX = ((vertex.z * yawSin) + (vertex.x * yawCos)) >> 16;
|
float rotatedX = (vertex.z * yawSin) + (vertex.x * yawCos);
|
||||||
int rotatedZ = ((vertex.z * yawCos) - (vertex.x * yawSin)) >> 16;
|
float rotatedZ = (vertex.z * yawCos) - (vertex.x * yawSin);
|
||||||
|
|
||||||
int var13 = ((vertex.y * pitchCos) - (rotatedZ * pitchSin)) >> 16;
|
float var13 = (vertex.y * pitchCos) - (rotatedZ * pitchSin);
|
||||||
int var12 = ((vertex.y * pitchSin) + (rotatedZ * pitchCos)) >> 16;
|
float var12 = (vertex.y * pitchSin) + (rotatedZ * pitchCos);
|
||||||
|
|
||||||
int x = rotatedX * zoom / var12 + centerX;
|
float x = rotatedX * zoom / var12 + centerX;
|
||||||
int y = var13 * zoom / var12 + centerY;
|
float y = var13 * zoom / var12 + centerY;
|
||||||
int z = -var12; // in OpenGL depth is negative
|
float z = -var12; // in OpenGL depth is negative
|
||||||
|
|
||||||
return ivec3(x, y, z);
|
return vec3(x, y, z);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user