Add simple partially functioning frustum culling

This commit is contained in:
James Seibel
2021-08-21 13:05:32 -05:00
parent a246dd7561
commit c5b4e20787
2 changed files with 76 additions and 7 deletions
@@ -39,6 +39,7 @@ import com.seibel.lod.handlers.ReflectionHandler;
import com.seibel.lod.objects.LevelPos;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.NearFarFogSettings;
import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodUtil;
@@ -67,7 +68,7 @@ import net.minecraft.util.math.vector.Vector3f;
* This is where LODs are draw to the world.
*
* @author James Seibel
* @version 8-20-2021
* @version 8-21-2021
*/
public class LodRenderer
{
@@ -318,14 +319,39 @@ public class LodRenderer
if (vbos != null)
{
int rendered = 0;
int skipped = 0;
Vector3d cameraDir = mc.cameraEntity.getLookAngle();
// used to determine what type of fog to render
int halfWidth = vbos.length/2;
int quarterWidth = vbos.length/4;
for (int i = 0; i < vbos.length; i++)
{
for (int j = 0; j < vbos.length; j++)
{
setupFog(fogSettings.near.distance, fogSettings.near.quality);
sendLodsToGpuAndDraw(vbos[i][j], modelViewMatrix);
RegionPos vboPos = new RegionPos(i + lodDim.getCenterX() - lodDim.getWidth()/2, j + lodDim.getCenterZ() - lodDim.getWidth()/2);
if (RenderUtil.isRegionInViewFrustum(player.blockPosition(), cameraDir, vboPos.blockPos()))
{
if ((i > halfWidth - quarterWidth && i < halfWidth + quarterWidth) && (j > halfWidth - quarterWidth && j < halfWidth + quarterWidth))
setupFog(fogSettings.near.distance, fogSettings.near.quality);
else
setupFog(fogSettings.far.distance, fogSettings.far.quality);
sendLodsToGpuAndDraw(vbos[i][j], modelViewMatrix);
rendered++;
}
else
{
skipped++;
}
}
}
ClientProxy.LOGGER.info(rendered + " - " + skipped);
}
@@ -361,9 +387,10 @@ public class LodRenderer
// end of internal LOD profiling
profiler.pop();
}
/**
/**
* This is where the actual drawing happens.
*
* @param buffers the buffers sent to the GPU to draw
@@ -22,14 +22,16 @@ import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.util.LodUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.vector.Vector3d;
/**
* This holds miscellaneous helper code
* to be used in the rendering process.
*
* @author James Seibel
* @version 8-17-2021
* @version 8-21-2021
*/
public class RenderUtil
{
@@ -105,4 +107,44 @@ public class RenderUtil
return numbLodsWide / (2 * mc.options.renderDistance);
}
/**
* Returns true if one of the regions 4 corners is in front
* of the camera.
*/
public static boolean isRegionInViewFrustum(BlockPos playerBlockPos, Vector3d cameraDir, BlockPos vboCenterPos)
{
// convert the vbo position into a direction vector
// starting from the player's position
Vector3d vboVec = new Vector3d(playerBlockPos.getX(), 0, playerBlockPos.getZ());
Vector3d playerVec = new Vector3d(vboCenterPos.getX(), vboCenterPos.getY(), vboCenterPos.getZ());
Vector3d vboCenterVec = playerVec.subtract(vboVec);
int halfRegionWidth = LodUtil.REGION_WIDTH;
Vector3d vboSeVec = new Vector3d(vboCenterVec.x + halfRegionWidth, 0, vboCenterVec.z + halfRegionWidth).normalize();
Vector3d vboSwVec = new Vector3d(vboCenterVec.x - halfRegionWidth, 0, vboCenterVec.z + halfRegionWidth).normalize();
Vector3d vboNwVec = new Vector3d(vboCenterVec.x - halfRegionWidth, 0, vboCenterVec.z - halfRegionWidth).normalize();
Vector3d vboNeVec = new Vector3d(vboCenterVec.x + halfRegionWidth, 0, vboCenterVec.z - halfRegionWidth).normalize();
return isNormalizedVectorInViewFrustum(vboSeVec, cameraDir) ||
isNormalizedVectorInViewFrustum(vboSwVec, cameraDir) ||
isNormalizedVectorInViewFrustum(vboNwVec, cameraDir) ||
isNormalizedVectorInViewFrustum(vboNeVec, cameraDir);
// return isNormalizedVectorInViewFrustum(vboCenterVec.normalize(), cameraDir);
}
/**
* Currently takes the dot product of the two vectors,
* but in the future could do more complicated frustum culling tests.
*/
private static boolean isNormalizedVectorInViewFrustum(Vector3d objectVector, Vector3d cameraDir)
{
// take the dot product
double dot = objectVector.dot(cameraDir);
return dot >= 0;
}
}