- 476
- 9
- 39
Есть ли тема где можно тот или иной туториал попросить сделать?
Или может кто-то здесь ответит, тоже невероятно хорошо было бы.
Мучаюсь с Ambient Occlusion и гайдов на русском или почти нет, или уходят в свою реализацию, а мне бы понять, что в самом майне относительно кода происходит :\
А проблема в том, что все блоки чёрные, если я у всех делаю свою волнистую модельку.
В целом я понимаю со стороны логики как это работает, но как через кучу математических формул это происходит в коде AO хз
Или может кто-то здесь ответит, тоже невероятно хорошо было бы.
Мучаюсь с Ambient Occlusion и гайдов на русском или почти нет, или уходят в свою реализацию, а мне бы понять, что в самом майне относительно кода происходит :\
А проблема в том, что все блоки чёрные, если я у всех делаю свою волнистую модельку.
В целом я понимаю со стороны логики как это работает, но как через кучу математических формул это происходит в коде AO хз
Java:
public void fillQuadBounds(IBlockState stateIn, int[] vertexData, EnumFacing face, @Nullable float[] faceShape, BitSet shapeState)
{
float west = 32.0F;
float down = 32.0F;
float north = 32.0F;
float east = -32.0F;
float up = -32.0F;
float south = -32.0F;
int count = vertexData.length / 4;
for (int i = 0; i < vertexData.length / count; i++)
{
float posX = Float.intBitsToFloat(vertexData[i * 7]);
float posY = Float.intBitsToFloat(vertexData[i * 7 + 1]);
float posZ = Float.intBitsToFloat(vertexData[i * 7 + 2]);
west = Math.min(west, posX);
down = Math.min(down, posY);
north = Math.min(north, posZ);
east = Math.max(east, posX);
up = Math.max(up, posY);
south = Math.max(south, posZ);
}
if (faceShape != null)
{
faceShape[WEST.getIndex()] = west;
faceShape[EAST.getIndex()] = east;
faceShape[EnumFacing.DOWN.getIndex()] = down;
faceShape[EnumFacing.UP.getIndex()] = up;
faceShape[NORTH.getIndex()] = north;
faceShape[SOUTH.getIndex()] = south;
int countFace = EnumFacing.values().length;
faceShape[WEST.getIndex() + countFace] = 1.0F - west;
faceShape[EAST.getIndex() + countFace] = 1.0F - east;
faceShape[EnumFacing.DOWN.getIndex() + countFace] = 1.0F - down;
faceShape[EnumFacing.UP.getIndex() + countFace] = 1.0F - up;
faceShape[NORTH.getIndex() + countFace] = 1.0F - north;
faceShape[SOUTH.getIndex() + countFace] = 1.0F - south;
}
switch (face)
{
case DOWN:
shapeState.set(1, west >= 1.0E-4F || north >= 1.0E-4F || east <= 0.9999F || south <= 0.9999F);
shapeState.set(0, (down < 1.0E-4F || stateIn.isFullCube()) && down == up);
break;
case UP:
shapeState.set(1, west >= 1.0E-4F || north >= 1.0E-4F || east <= 0.9999F || south <= 0.9999F);
shapeState.set(0, (up > 0.9999F || stateIn.isFullCube()) && down == up);
break;
case NORTH:
shapeState.set(1, west >= 1.0E-4F || down >= 1.0E-4F || east <= 0.9999F || up <= 0.9999F);
shapeState.set(0, (north < 1.0E-4F || stateIn.isFullCube()) && north == south);
break;
case SOUTH:
shapeState.set(1, west >= 1.0E-4F || down >= 1.0E-4F || east <= 0.9999F || up <= 0.9999F);
shapeState.set(0, (south > 0.9999F || stateIn.isFullCube()) && north == south);
break;
case WEST:
shapeState.set(1, down >= 1.0E-4F || north >= 1.0E-4F || up <= 0.9999F || south <= 0.9999F);
shapeState.set(0, (west < 1.0E-4F || stateIn.isFullCube()) && west == east);
break;
case EAST:
shapeState.set(1, down >= 1.0E-4F || north >= 1.0E-4F || up <= 0.9999F || south <= 0.9999F);
shapeState.set(0, (east > 0.9999F || stateIn.isFullCube()) && west == east);
}
}
Java:
public class AmbientOcclusionFace
{
public final float[] vertexColorMultiplier = new float[4];
public final int[] vertexBrightness = new int[4];
public void updateVertexBrightness(IBlockAccess worldIn, IBlockState state, BlockPos centerPos, EnumFacing direction, float[] faceShape, BitSet shapeState)
{
BlockPos posIn = shapeState.get(0) ? centerPos.offset(direction) : centerPos;
BlockPos.PooledMutableBlockPos mutablePos = BlockPos.PooledMutableBlockPos.retain();
BlockModelRenderer.EnumNeighborInfo neighborInfo = BlockModelRenderer.EnumNeighborInfo.getNeighbourInfo(direction);
BlockPos.PooledMutableBlockPos mutablePos1 = BlockPos.PooledMutableBlockPos.retain(posIn).move(neighborInfo.corners[0]);
BlockPos.PooledMutableBlockPos mutablePos2 = BlockPos.PooledMutableBlockPos.retain(posIn).move(neighborInfo.corners[1]);
BlockPos.PooledMutableBlockPos mutablePos3 = BlockPos.PooledMutableBlockPos.retain(posIn).move(neighborInfo.corners[2]);
BlockPos.PooledMutableBlockPos mutablePos4 = BlockPos.PooledMutableBlockPos.retain(posIn).move(neighborInfo.corners[3]);
int light = state.getPackedLightmapCoords(worldIn, mutablePos1);
int light1 = state.getPackedLightmapCoords(worldIn, mutablePos2);
int light2 = state.getPackedLightmapCoords(worldIn, mutablePos3);
int light3 = state.getPackedLightmapCoords(worldIn, mutablePos4);
//if cube is normal 0.2f else 1.0f
float occlusionValue = worldIn.getBlockState(mutablePos1).getAmbientOcclusionLightValue();
float occlusionValue1 = worldIn.getBlockState(mutablePos2).getAmbientOcclusionLightValue();
float occlusionValue2 = worldIn.getBlockState(mutablePos3).getAmbientOcclusionLightValue();
float occlusionValue3 = worldIn.getBlockState(mutablePos4).getAmbientOcclusionLightValue();
boolean isTranslucent = worldIn.getBlockState(mutablePos.setPos(mutablePos1).move(direction)).isTranslucent();
boolean isTranslucent1 = worldIn.getBlockState(mutablePos.setPos(mutablePos2).move(direction)).isTranslucent();
boolean isTranslucent2 = worldIn.getBlockState(mutablePos.setPos(mutablePos3).move(direction)).isTranslucent();
boolean isTranslucent3 = worldIn.getBlockState(mutablePos.setPos(mutablePos4).move(direction)).isTranslucent();
float occlusion;
int lightVal;
if (!isTranslucent2 && !isTranslucent)
{
occlusion = occlusionValue;
lightVal = light;
} else
{
BlockPos pos = mutablePos.setPos(mutablePos1).move(neighborInfo.corners[2]);
occlusion = worldIn.getBlockState(pos).getAmbientOcclusionLightValue();
lightVal = state.getPackedLightmapCoords(worldIn, pos);
}
float occlusion1;
int lightVal1;
if (!isTranslucent3 && !isTranslucent)
{
occlusion1 = occlusionValue;
lightVal1 = light;
} else
{
BlockPos pos2 = mutablePos.setPos(mutablePos1).move(neighborInfo.corners[3]);
occlusion1 = worldIn.getBlockState(pos2).getAmbientOcclusionLightValue();
lightVal1 = state.getPackedLightmapCoords(worldIn, pos2);
}
float occlusion2;
int lightVal2;
if (!isTranslucent2 && !isTranslucent1)
{
occlusion2 = occlusionValue1;
lightVal2 = light1;
} else
{
BlockPos pos3 = mutablePos.setPos(mutablePos2).move(neighborInfo.corners[2]);
occlusion2 = worldIn.getBlockState(pos3).getAmbientOcclusionLightValue();
lightVal2 = state.getPackedLightmapCoords(worldIn, pos3);
}
float occlusion3;
int lightVal3;
if (!isTranslucent3 && !isTranslucent1)
{
occlusion3 = occlusionValue1;
lightVal3 = light1;
} else
{
BlockPos pos4 = mutablePos.setPos(mutablePos2).move(neighborInfo.corners[3]);
occlusion3 = worldIn.getBlockState(pos4).getAmbientOcclusionLightValue();
lightVal3 = state.getPackedLightmapCoords(worldIn, pos4);
}
int cubeLight = state.getPackedLightmapCoords(worldIn, centerPos);
if (shapeState.get(0) || !worldIn.getBlockState(centerPos.offset(direction)).isOpaqueCube())
{
cubeLight = state.getPackedLightmapCoords(worldIn, centerPos.offset(direction));
}
float shapeOcclusion = shapeState.get(0) ? worldIn.getBlockState(posIn).getAmbientOcclusionLightValue() : worldIn.getBlockState(centerPos).getAmbientOcclusionLightValue();
BlockModelRenderer.VertexTranslations vertexTranslations = BlockModelRenderer.VertexTranslations.getVertexTranslations(direction);
mutablePos.release();
mutablePos1.release();
mutablePos2.release();
mutablePos3.release();
mutablePos4.release();
if (shapeState.get(1) && neighborInfo.doNonCubicWeight)
{
float colorMultip = (occlusionValue3 + occlusionValue + occlusion1 + shapeOcclusion) * 0.25F;
float colorMultip1 = (occlusionValue2 + occlusionValue + occlusion + shapeOcclusion) * 0.25F;
float colorMultip2 = (occlusionValue2 + occlusionValue1 + occlusion2 + shapeOcclusion) * 0.25F;
float colorMultip3 = (occlusionValue3 + occlusionValue1 + occlusion3 + shapeOcclusion) * 0.25F;
//У блока 16 точек, и походу это что-то типа них
float shape = faceShape[neighborInfo.vert0Weights[0].shape] * faceShape[neighborInfo.vert0Weights[1].shape];
float shape1 = faceShape[neighborInfo.vert0Weights[2].shape] * faceShape[neighborInfo.vert0Weights[3].shape];
float shape2 = faceShape[neighborInfo.vert0Weights[4].shape] * faceShape[neighborInfo.vert0Weights[5].shape];
float shape3 = faceShape[neighborInfo.vert0Weights[6].shape] * faceShape[neighborInfo.vert0Weights[7].shape];
float shape4 = faceShape[neighborInfo.vert1Weights[0].shape] * faceShape[neighborInfo.vert1Weights[1].shape];
float shape5 = faceShape[neighborInfo.vert1Weights[2].shape] * faceShape[neighborInfo.vert1Weights[3].shape];
float shape6 = faceShape[neighborInfo.vert1Weights[4].shape] * faceShape[neighborInfo.vert1Weights[5].shape];
float shape7 = faceShape[neighborInfo.vert1Weights[6].shape] * faceShape[neighborInfo.vert1Weights[7].shape];
float shape8 = faceShape[neighborInfo.vert2Weights[0].shape] * faceShape[neighborInfo.vert2Weights[1].shape];
float shape9 = faceShape[neighborInfo.vert2Weights[2].shape] * faceShape[neighborInfo.vert2Weights[3].shape];
float shape10 = faceShape[neighborInfo.vert2Weights[4].shape] * faceShape[neighborInfo.vert2Weights[5].shape];
float shape11 = faceShape[neighborInfo.vert2Weights[6].shape] * faceShape[neighborInfo.vert2Weights[7].shape];
float shape12 = faceShape[neighborInfo.vert3Weights[0].shape] * faceShape[neighborInfo.vert3Weights[1].shape];
float shape13 = faceShape[neighborInfo.vert3Weights[2].shape] * faceShape[neighborInfo.vert3Weights[3].shape];
float shape14 = faceShape[neighborInfo.vert3Weights[4].shape] * faceShape[neighborInfo.vert3Weights[5].shape];
float shape15 = faceShape[neighborInfo.vert3Weights[6].shape] * faceShape[neighborInfo.vert3Weights[7].shape];
//Цвет
this.vertexColorMultiplier[vertexTranslations.vert0] = colorMultip * shape + colorMultip1 * shape1 + colorMultip2 * shape2 + colorMultip3 * shape3;
this.vertexColorMultiplier[vertexTranslations.vert1] = colorMultip * shape4 + colorMultip1 * shape5 + colorMultip2 * shape6 + colorMultip3 * shape7;
this.vertexColorMultiplier[vertexTranslations.vert2] = colorMultip * shape8 + colorMultip1 * shape9 + colorMultip2 * shape10 + colorMultip3 * shape11;
this.vertexColorMultiplier[vertexTranslations.vert3] = colorMultip * shape12 + colorMultip1 * shape13 + colorMultip2 * shape14 + colorMultip3 * shape15;
//Яркость
int aoBrightness = this.getAoBrightness(light3, light, lightVal1, cubeLight);
int aoBrightness1 = this.getAoBrightness(light2, light, lightVal, cubeLight);
int aoBrightness2 = this.getAoBrightness(light2, light1, lightVal2, cubeLight);
int aoBrightness3 = this.getAoBrightness(light3, light1, lightVal3, cubeLight);
//Точка яркости? Точки яркости? Как обычные текстуры только с натягиванием света на область из 4 точек?
this.vertexBrightness[vertexTranslations.vert0] = this.getVertexBrightness(aoBrightness, aoBrightness1, aoBrightness2, aoBrightness3, shape, shape1, shape2, shape3);
this.vertexBrightness[vertexTranslations.vert1] = this.getVertexBrightness(aoBrightness, aoBrightness1, aoBrightness2, aoBrightness3, shape4, shape5, shape6, shape7);
this.vertexBrightness[vertexTranslations.vert2] = this.getVertexBrightness(aoBrightness, aoBrightness1, aoBrightness2, aoBrightness3, shape8, shape9, shape10, shape11);
this.vertexBrightness[vertexTranslations.vert3] = this.getVertexBrightness(aoBrightness, aoBrightness1, aoBrightness2, aoBrightness3, shape12, shape13, shape14, shape15);
} else
{
float colorMultip = (occlusionValue3 + occlusionValue + occlusion1 + shapeOcclusion) * 0.25F;
float colorMultip1 = (occlusionValue2 + occlusionValue + occlusion + shapeOcclusion) * 0.25F;
float colorMultip2 = (occlusionValue2 + occlusionValue1 + occlusion2 + shapeOcclusion) * 0.25F;
float colorMultip3 = (occlusionValue3 + occlusionValue1 + occlusion3 + shapeOcclusion) * 0.25F;
//Точка яркости? Точки яркости? Как обычные текстуры только с натягиванием света на область из 4 точек?
this.vertexBrightness[vertexTranslations.vert0] = this.getAoBrightness(light3, light, lightVal1, cubeLight);
this.vertexBrightness[vertexTranslations.vert1] = this.getAoBrightness(light2, light, lightVal, cubeLight);
this.vertexBrightness[vertexTranslations.vert2] = this.getAoBrightness(light2, light1, lightVal2, cubeLight);
this.vertexBrightness[vertexTranslations.vert3] = this.getAoBrightness(light3, light1, lightVal3, cubeLight);
//Цвет
this.vertexColorMultiplier[vertexTranslations.vert0] = colorMultip;
this.vertexColorMultiplier[vertexTranslations.vert1] = colorMultip1;
this.vertexColorMultiplier[vertexTranslations.vert2] = colorMultip2;
this.vertexColorMultiplier[vertexTranslations.vert3] = colorMultip3;
}
}
/**
* Get ambient occlusion brightness
*/
private int getAoBrightness(int light, int light1, int lightval, int cubeLight)
{
if (light == 0)
{
light = cubeLight;
}
if (light1 == 0)
{
light1 = cubeLight;
}
if (lightval == 0)
{
lightval = cubeLight;
}
return light + light1 + lightval + cubeLight >> 2 & 16711935;
}
private int getVertexBrightness(int aoBrightness, int aoBrightness1, int aoBrightness2, int aoBrightness3, float shape, float shape1, float shape2, float shape3)
{
int i = (int) ((float) (aoBrightness >> 16 & 255) * shape +
(float) (aoBrightness1 >> 16 & 255) * shape1 +
(float) (aoBrightness2 >> 16 & 255) * shape2 +
(float) (aoBrightness3 >> 16 & 255) * shape3) & 255;
int j = (int) ((float) (aoBrightness & 255) * shape +
(float) (aoBrightness1 & 255) * shape1 +
(float) (aoBrightness2 & 255) * shape2 +
(float) (aoBrightness3 & 255) * shape3) & 255;
return i << 16 | j;
}
}
Последнее редактирование: