/* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */ public void applyLighting( HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor) { int[] shadowscale = null; if (smooth) { shadowscale = ss.getLightingTable(); if (shadowscale == null) { shadowscale = defLightingTable; } applySmoothLighting(ps, ss, incolor, outcolor, shadowscale); return; } LightLevels ll = null; int lightlevel = 15, lightlevel_day = 15; /* If processing for shadows, use sky light level as base lighting */ if (defLightingTable != null) { shadowscale = ss.getLightingTable(); if (shadowscale == null) { shadowscale = defLightingTable; } ll = ps.getCachedLightLevels(0); ps.getLightLevels(ll); lightlevel = lightlevel_day = ll.sky; } /* If ambient light, adjust base lighting for it */ lightlevel = lightscale[lightlevel]; /* If we're below max, see if emitted light helps */ if ((lightlevel < 15) || (lightlevel_day < 15)) { int emitted = ll.emitted; lightlevel = Math.max(emitted, lightlevel); lightlevel_day = Math.max(emitted, lightlevel_day); } /* Figure out our color, with lighting if needed */ outcolor[0].setColor(incolor); if (lightlevel < 15) { shadowColor(outcolor[0], lightlevel, shadowscale); } if (outcolor.length > 1) { if (lightlevel_day == lightlevel) { outcolor[1].setColor(outcolor[0]); } else { outcolor[1].setColor(incolor); if (lightlevel_day < 15) { shadowColor(outcolor[1], lightlevel_day, shadowscale); } } } }
private void applySmoothLighting( HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor, int[] shadowscale) { int[] xyz = ps.getSubblockCoord(); int scale = (int) ps.getScale(); int mid = scale / 2; BlockStep s1, s2; int w1, w2; /* Figure out which directions to look */ switch (ps.getLastBlockStep()) { case X_MINUS: case X_PLUS: if (xyz[1] < mid) { s1 = BlockStep.Y_MINUS; w1 = mid - xyz[1]; } else { s1 = BlockStep.Y_PLUS; w1 = xyz[1] - mid; } if (xyz[2] < mid) { s2 = BlockStep.Z_MINUS; w2 = mid - xyz[2]; } else { s2 = BlockStep.Z_PLUS; w2 = xyz[2] - mid; } break; case Z_MINUS: case Z_PLUS: if (xyz[0] < mid) { s1 = BlockStep.X_MINUS; w1 = mid - xyz[0]; } else { s1 = BlockStep.X_PLUS; w1 = xyz[0] - mid; } if (xyz[1] < mid) { s2 = BlockStep.Y_MINUS; w2 = mid - xyz[1]; } else { s2 = BlockStep.Y_PLUS; w2 = xyz[1] - mid; } break; default: if (xyz[0] < mid) { s1 = BlockStep.X_MINUS; w1 = mid - xyz[0]; } else { s1 = BlockStep.X_PLUS; w1 = xyz[0] - mid; } if (xyz[2] < mid) { s2 = BlockStep.Z_MINUS; w2 = mid - xyz[2]; } else { s2 = BlockStep.Z_PLUS; w2 = xyz[2] - mid; } break; } /* Now get the 3 needed light levels */ LightLevels skyemit0 = ps.getCachedLightLevels(0); ps.getLightLevels(skyemit0); LightLevels skyemit1 = ps.getCachedLightLevels(1); ps.getLightLevelsAtStep(s1, skyemit1); LightLevels skyemit2 = ps.getCachedLightLevels(2); ps.getLightLevelsAtStep(s2, skyemit2); /* Get light levels */ int ll0 = getLightLevel(skyemit0, true); int ll1 = getLightLevel(skyemit1, true); int weight = 0; if (ll1 < ll0) weight -= w1; else if (ll1 > ll0) weight += w1; int ll2 = getLightLevel(skyemit2, true); if (ll2 < ll0) weight -= w2; else if (ll2 > ll0) weight += w2; outcolor[0].setColor(incolor); int cscale = 256; if (weight == 0) { cscale = shadowscale[ll0]; } else if (weight < 0) { /* If negative, interpolate down */ weight = -weight; if (ll0 > 0) { cscale = (shadowscale[ll0] * (scale - weight) + shadowscale[ll0 - 1] * weight) / scale; } else { cscale = shadowscale[ll0]; } } else { if (ll0 < 15) { cscale = (shadowscale[ll0] * (scale - weight) + shadowscale[ll0 + 1] * weight) / scale; } else { cscale = shadowscale[ll0]; } } if (cscale < 256) { Color c = outcolor[0]; c.setRGBA( (c.getRed() * cscale) >> 8, (c.getGreen() * cscale) >> 8, (c.getBlue() * cscale) >> 8, c.getAlpha()); } if (outcolor.length > 1) { ll0 = getLightLevel(skyemit0, false); ll1 = getLightLevel(skyemit1, false); weight = 0; if (ll1 < ll0) weight -= w1; else if (ll1 > ll0) weight += w1; ll2 = getLightLevel(skyemit2, false); if (ll2 < ll0) weight -= w2; else if (ll2 > ll0) weight += w2; outcolor[1].setColor(incolor); cscale = 256; if (weight == 0) { cscale = shadowscale[ll0]; } else if (weight < 0) { /* If negative, interpolate down */ weight = -weight; if (ll0 > 0) { cscale = (shadowscale[ll0] * (scale - weight) + shadowscale[ll0 - 1] * weight) / scale; } else { cscale = shadowscale[ll0]; } } else { if (ll0 < 15) { cscale = (shadowscale[ll0] * (scale - weight) + shadowscale[ll0 + 1] * weight) / scale; } else { cscale = shadowscale[ll0]; } } if (cscale < 256) { Color c = outcolor[1]; c.setRGBA( (c.getRed() * cscale) >> 8, (c.getGreen() * cscale) >> 8, (c.getBlue() * cscale) >> 8, c.getAlpha()); } } }