public void calcShadows(int pX, int pY, RasterPoint pDestRasterPoint) { pDestRasterPoint.hasShadows = true; for (int i = 0; i < shadowZBuf.length; i++) { pDestRasterPoint.visibility[i] = 1.0; if (shadowZBuf[i] != null) { if (shadowSoften) { calcSmoothShadowIntensity( pX, pY, pDestRasterPoint, i, shadowSmoothRadius, shadowSmoothKernel); } else { calcFastShadowIntensity(pX, pY, pDestRasterPoint, i); } pDestRasterPoint.visibility[i] = GfxMathLib.clamp(pDestRasterPoint.visibility[i] + shadowIntensity[i]); } } }
public void accelerateShadows() { if (withAcceleration) { accLightProjectionZBuf = new float[lightCount][][]; for (int i = 0; i < lightCount; i++) { if (shadowZBuf[i] != null) { accLightProjectionZBuf[i] = new float[rasterWidth][rasterHeight]; for (int pX = 0; pX < rasterWidth; pX++) { for (int pY = 0; pY < rasterHeight; pY++) { accLightProjectionZBuf[i][pX][pY] = NormalsCalculator.ZBUF_ZMIN; float originX = originXBuf[pX][pY]; if (originX != NormalsCalculator.ZBUF_ZMIN) { float originY = originYBuf[pX][pY]; if (originY != NormalsCalculator.ZBUF_ZMIN) { float originZ = originZBuf[pX][pY]; if (originZ != NormalsCalculator.ZBUF_ZMIN) { int x = projectPointToLightMapX( i, lightViewCalculator.applyLightProjectionX( i, originX, originY, originZ)); int y = projectPointToLightMapY( i, lightViewCalculator.applyLightProjectionY( i, originX, originY, originZ)); if (x >= 0 && x < shadowZBuf[i].length && y >= 0 && y < shadowZBuf[i][0].length) { double lightZ = lightViewCalculator.applyLightProjectionZ(i, originX, originY, originZ); accLightProjectionZBuf[i][pX][pY] = (float) GfxMathLib.step(shadowZBuf[i][x][y] - shadowDistBias, lightZ); } } } } } } } } } }
public ShadowCalculator( int rasterWidth, int rasterHeight, float[][] originXBuf, float[][] originYBuf, float[][] originZBuf, double imgSize, Flame flame) { this.rasterWidth = rasterWidth; this.rasterHeight = rasterHeight; this.originXBuf = originXBuf; this.originYBuf = originYBuf; this.originZBuf = originZBuf; lightCount = flame.getSolidRenderSettings().getLights().size(); shadowZBuf = new float[lightCount][][]; pre_shadowIndex = new int[lightCount]; pre_shadowXBuf = new float[lightCount][]; pre_shadowYBuf = new float[lightCount][]; pre_shadowZBuf = new float[lightCount][]; shadowMapXCentre = new double[lightCount]; shadowMapYCentre = new double[lightCount]; shadowMapXScale = new double[lightCount]; shadowMapYScale = new double[lightCount]; lightX = new double[lightCount]; lightY = new double[lightCount]; shadowIntensity = new double[lightCount]; shadowMapSize = flame.getSolidRenderSettings().getShadowmapSize(); if (shadowMapSize < 64) { shadowMapSize = 64; } shadowDistBias = flame.getSolidRenderSettings().getShadowmapBias(); for (int i = 0; i < lightCount; i++) { DistantLight light = flame.getSolidRenderSettings().getLights().get(i); if (light.isCastShadows()) { shadowZBuf[i] = new float[shadowMapSize][shadowMapSize]; pre_shadowXBuf[i] = new float[PRE_SHADOWMAP_SIZE]; pre_shadowYBuf[i] = new float[PRE_SHADOWMAP_SIZE]; pre_shadowZBuf[i] = new float[PRE_SHADOWMAP_SIZE]; for (int k = 0; k < shadowZBuf[i].length; k++) { for (int l = 0; l < shadowZBuf[i][0].length; l++) { shadowZBuf[i][k][l] = NormalsCalculator.ZBUF_ZMIN; } } lightX[i] = light.getAltitude(); lightY[i] = light.getAzimuth(); shadowIntensity[i] = 1.0 - GfxMathLib.clamp(light.getShadowIntensity(), 0.0, 1.0); } else { shadowZBuf[i] = null; pre_shadowXBuf[i] = pre_shadowYBuf[i] = pre_shadowZBuf[i] = null; } } shadowSoften = ShadowType.SMOOTH.equals(flame.getSolidRenderSettings().getShadowType()); double rawSmoothRadius = flame.getSolidRenderSettings().getShadowSmoothRadius(); if (rawSmoothRadius < MathLib.EPSILON) { rawSmoothRadius = 0.0; } shadowSmoothRadius = clipSmoothRadius(Tools.FTOI(rawSmoothRadius * 6.0 * imgSize / 1000.0)); if (shadowSmoothRadius < 1.0) { shadowSoften = false; shadowSmoothKernel = null; } else { shadowSmoothKernel = getShadowSmoothKernel(shadowSmoothRadius); } }
private void calcSmoothShadowIntensity( int pX, int pY, RasterPoint pDestRasterPoint, int i, int shadowSmoothRadius, double[][] shadowSmoothKernel) { pDestRasterPoint.visibility[i] = 1.0; double totalIntensity = 0.0; if (accLightProjectionZBuf != null && accLightProjectionZBuf[i] != null) { int dl = shadowSmoothRadius / 8 + 1; for (int k = -shadowSmoothRadius; k <= shadowSmoothRadius; k += dl) { int dstX = pX + k; if (dstX >= 0 && dstX < originXBuf.length) { for (int l = -shadowSmoothRadius; l <= shadowSmoothRadius; l += dl) { int dstY = pY + l; if (dstY >= 0 && dstY < originXBuf[0].length) { if (accLightProjectionZBuf[i][dstX][dstY] > NormalsCalculator.ZBUF_ZMIN) { double intensity = shadowSmoothKernel[k + shadowSmoothRadius][l + shadowSmoothRadius]; totalIntensity += intensity; pDestRasterPoint.visibility[i] += accLightProjectionZBuf[i][dstX][dstY] * intensity; } } } } } } else { for (int k = -shadowSmoothRadius; k <= shadowSmoothRadius; k++) { int dstX = pX + k; if (dstX >= 0 && dstX < originXBuf.length) { for (int l = -shadowSmoothRadius; l <= shadowSmoothRadius; l++) { int dstY = pY + l; if (dstY >= 0 && dstY < originXBuf[0].length) { float originX = originXBuf[dstX][dstY]; if (originX != NormalsCalculator.ZBUF_ZMIN) { float originY = originYBuf[dstX][dstY]; if (originY != NormalsCalculator.ZBUF_ZMIN) { float originZ = originZBuf[dstX][dstY]; if (originZ != NormalsCalculator.ZBUF_ZMIN) { int x = projectPointToLightMapX( i, lightViewCalculator.applyLightProjectionX( i, originX, originY, originZ)); int y = projectPointToLightMapY( i, lightViewCalculator.applyLightProjectionY( i, originX, originY, originZ)); if (x >= 0 && x < shadowZBuf[i].length && y >= 0 && y < shadowZBuf[i][0].length) { double intensity = shadowSmoothKernel[k + shadowSmoothRadius][l + shadowSmoothRadius]; totalIntensity += intensity; double lightZ = lightViewCalculator.applyLightProjectionZ(i, originX, originY, originZ); pDestRasterPoint.visibility[i] += GfxMathLib.step(shadowZBuf[i][x][y] - shadowDistBias, lightZ) * intensity; } } } } } } } } } if (totalIntensity > MathLib.EPSILON) { pDestRasterPoint.visibility[i] /= totalIntensity; } }