Algorithm 在雷击机上看到的平滑闪电
我将要为我的游戏创建一个灯光系统,实际上我已经设置好了,但是如图所示,这是一个“块状”闪电。我想平滑的脸,使两个不同的瓷砖不显着 我环顾了一下这个主题,我发现唯一真正的答案是平均所有4个周围邻居的光线,并从中创建一个渐变。答案是,但是没有特别的规则可以遵循,因为这是我需要了解的 每个平铺的灯光强度在100-255之间是一个固定的数字,其中100是最暗的,255是最亮的(不透明度),每个顶点都获得该值 我是否必须找出哪些邻居使用每个瓷砖顶点并从那里继续?我真的不知道 “我的灯光”的当前版本如下所示:编辑:现在它如下所示。它有一些缺陷。 我试图收集所有相邻顶点并取它们的平均值(见下图)。通过使用此方法,我将在每个顶点上接收不同的强度值 这是算法的开始。此功能旨在为灯光中的每个瓷砖运行。从我当前的算法状态来看,我需要找到同一点上的顶点。我被困在这里了!:'-(我已经更新了算法,但它仍然有一些视觉缺陷。请注意,左上和右下两侧是“块状”的,而其他的则不是。另外,如果你仔细观察中心,会发现有一个六边形,大约3宽3高Algorithm 在雷击机上看到的平滑闪电,algorithm,interpolation,light,Algorithm,Interpolation,Light,我将要为我的游戏创建一个灯光系统,实际上我已经设置好了,但是如图所示,这是一个“块状”闪电。我想平滑的脸,使两个不同的瓷砖不显着 我环顾了一下这个主题,我发现唯一真正的答案是平均所有4个周围邻居的光线,并从中创建一个渐变。答案是,但是没有特别的规则可以遵循,因为这是我需要了解的 每个平铺的灯光强度在100-255之间是一个固定的数字,其中100是最暗的,255是最亮的(不透明度),每个顶点都获得该值 我是否必须找出哪些邻居使用每个瓷砖顶点并从那里继续?我真的不知道 “我的灯光”的当前版本如下所示
void Torch::smoothLight(int pX, int pY)
{
if (pX == 0 || pX == (mWidth - 1) || pY == 0 || pY == (mHeight - 1)) return;
// Tile we are smoothing
Tile *c = mTilesInRange[pY * mWidth + pX];
if (c == nullptr) return;
int x_min_1 = pX - 1;
int x_plus_1 = pX + 1;
int y_min_1 = pY - 1;
int y_plus_1 = pY + 1;
// Get all nearby tiles in all 8 weather directions
Tile *NW = mTilesInRange[y_min_1 * mWidth + x_min_1];
Tile *N = mTilesInRange[y_min_1 * mWidth + pX];
Tile *NE = mTilesInRange[y_min_1 * mWidth + x_plus_1];
Tile *E = mTilesInRange[pY * mWidth + x_plus_1];
Tile *SW = mTilesInRange[y_plus_1 * mWidth + x_min_1];
Tile *S = mTilesInRange[y_plus_1 * mWidth + pX];
Tile *SE = mTilesInRange[y_plus_1 * mWidth + x_plus_1];
Tile *W = mTilesInRange[pY * mWidth + x_min_1];
/*
- Loop trough all 4 vertices on the tile in the following order
0 1
2 3
- For each vertex, find the 3 other vertices that lies on the same point, example vertex 1:
0 1 <--
2 3
0 1 0 1
2 3 2 3
Original quad -> 0 1 0 1
-> 2 3 2 3
Result: 3 2
1 0
*/
for (int i = 0; i < 4; i++)
{
int intensitySum = 0;
// This is really ugly but I can't come up with a better algorithm
if (i == 0) // upper left
{
intensitySum += c->getQuad()[0].color.a; // me
intensitySum += N->getQuad()[3].color.a;
intensitySum += NW->getQuad()[2].color.a;
intensitySum += W->getQuad()[1].color.a;
int alpha = intensitySum / 4;
c->getQuad()[0].color.a = alpha;
}
else if (i == 1) // upper right
{
intensitySum += c->getQuad()[1].color.a; // me
intensitySum += N->getQuad()[2].color.a;
intensitySum += NE->getQuad()[3].color.a;
intensitySum += E->getQuad()[0].color.a;
int alpha = intensitySum / 4;
c->getQuad()[1].color.a = alpha;
}
else if (i == 2) // lower left
{
intensitySum += c->getQuad()[2].color.a; // me
intensitySum += E->getQuad()[3].color.a;
intensitySum += SE->getQuad()[0].color.a;
intensitySum += S->getQuad()[1].color.a;
int alpha = intensitySum / 4;
c->getQuad()[2].color.a = alpha;
}
else if (i == 3) // lower right
{
intensitySum += c->getQuad()[3].color.a; // me
intensitySum += S->getQuad()[0].color.a;
intensitySum += SW->getQuad()[1].color.a;
intensitySum += W->getQuad()[2].color.a;
int alpha = intensitySum / 4;
c->getQuad()[3].color.a = alpha;
}
}
}
void Torch::smoothLight(int-pX,int-pY)
{
如果(pX==0 | | pX==(mWidth-1)| | pY==0 | | pY==(mHeight-1))返回;
//我们正在平滑
瓷砖*c=mTilesInRange[pY*mWidth+pX];
如果(c==nullptr)返回;
int x_min_1=pX-1;
整数x加1=pX+1;
int y_min_1=pY-1;
int y_加上_1=pY+1;
//在所有8个天气方向获取附近的所有瓷砖
瓦片*NW=mTilesInRange[y_min_1*mWidth+x_min_1];
瓷砖*N=mTilesInRange[y_min_1*mWidth+pX];
瓷砖*NE=mTilesInRange[y_min_1*mWidth+x_+u 1];
瓦片*E=mTilesInRange[pY*mWidth+x_+u 1];
瓦片*SW=mTilesInRange[y加上1*M宽度+x最小值1];
瓦片*S=mTilesInRange[y_加上1*mWidth+pX];
瓷砖*SE=mTilesInRange[y_+u 1*mWidth+x_+u 1];
瓷砖*W=mTilesInRange[pY*mWidth+x_min_1];
/*
-按以下顺序循环穿过平铺上的所有4个顶点
0 1
2 3
-对于每个顶点,查找位于同一点上的其他3个顶点,例如顶点1:
0 1 0 1 0 1
-> 2 3 2 3
结果:3 2
1 0
*/
对于(int i=0;i<4;i++)
{
int-intensitySum=0;
//这真的很难看,但我想不出更好的算法
if(i==0)//左上角
{
intensitySum+=c->getQuad()[0]。color.a;//me
intensitySum+=N->getQuad()[3].color.a;
intensitySum+=NW->getQuad()[2].color.a;
intensitySum+=W->getQuad()[1]。颜色。a;
int alpha=强度总和/4;
c->getQuad()[0].color.a=alpha;
}
else如果(i==1)//右上角
{
intensitySum+=c->getQuad()[1]。color.a;//me
intensitySum+=N->getQuad()[2].color.a;
intensitySum+=NE->getQuad()[3]。颜色。a;
intensitySum+=E->getQuad()[0]。颜色。a;
int alpha=强度总和/4;
c->getQuad()[1].color.a=alpha;
}
else如果(i==2)//左下角
{
intensitySum+=c->getQuad()[2]。color.a;//me
intensitySum+=E->getQuad()[3].color.a;
intensitySum+=SE->getQuad()[0]。颜色。a;
intensitySum+=S->getQuad()[1].color.a;
int alpha=强度总和/4;
c->getQuad()[2].color.a=alpha;
}
else如果(i==3)//右下角
{
intensitySum+=c->getQuad()[3]。color.a;//me
intensitySum+=S->getQuad()[0].color.a;
intensitySum+=SW->getQuad()[1]。颜色。a;
intensitySum+=W->getQuad()[2]。颜色。a;
int alpha=强度总和/4;
c->getQuad()[3].color.a=alpha;
}
}
}
Umm minecraft在设置为奇特的照明设置时不使用opengl像素着色器和Phong着色?我认为它们不使用着色器。minecraft Wiki中有一个非常简短的解释,不幸的是没有任何技术解释。看起来你是对的,但我建议阅读2D环境光遮挡,类似于这里:AO只是他们的lightning引擎中的一个功能。他们表示“在块面上插值照明”是与AO一起制作平滑闪电的另一个功能。因此,在瓷砖上插值是我想要实现的,但从那里我就迷失了。如何“获得位于同一点上的顶点”?这个问题是语言/库特定的,不是吗。你应该把它们标记进去。我以为你在算法方面问得更多。所以,我删除了建议你看高斯模糊的答案。