[c#] 텍스처를 평평한 3D 오브젝트로 그려서 깊이를 모방 할 때 검은 선이 무작위로 나타납니다.


1 Answers

문제는 HLSL의 숫자 유형과 관련이 있습니다.

먼저, 그 쉐이더를 정리하자. 이것이 우리가 실제 문제를 발견 한 방법이기 때문에 그렇게 할 것입니다. 다음은 taperfix가 삽입되기 전의 SplattedTileShader.fx에 대한 통합 diff입니다.

@@ -37,76 +37,31 @@
    data.Position = mul(worldPosition, viewProjection);

-   
     return data;
 }

-float4 PixelLayer1(VertexShaderOutput input, uniform float alpha) : COLOR0
+float4 PixelLayer(VertexShaderOutput input, uniform uint layer, uniform float alpha) : COLOR0
 {
-   if(input.TextureInfo[0] < 1)
+   if(input.TextureInfo[0] < layer)
        discard;

-    float4 color;
+   float4 color;
+   float2 coord;
+   if(layer == 1)
+       coord = input.TexCoord1;
+   else if(layer == 2)
+       coord = input.TexCoord2;
+   else if(layer == 3)
+       coord = input.TexCoord3;

-   switch (input.TextureInfo[1])
+   switch (input.TextureInfo[layer])
    {
        case 0:
-           color = tex2D(staticTilesSampler, input.TexCoord1);
+           color = tex2D(staticTilesSampler, coord);
            break;
        case 1:
-           color = tex2D(autoTilesSampler, input.TexCoord1);
+           color = tex2D(autoTilesSampler, coord);
            break;
        case 2:
-           color = tex2D(autoTilesSampler, input.TexCoord1 + float2(frame, 0) * animOffset) * (1 - frameBlend) + tex2D(autoTilesSampler, input.TexCoord1 + float2(nextframe, 0) * animOffset) * frameBlend;
-           break;
-   }
-
-   clip(color.a - alpha);
-
-   return color;
-}
-
-float4 PixelLayer2(VertexShaderOutput input, uniform float alpha) : COLOR0
-{
-   if(input.TextureInfo[0] < 2)
-       discard;
-
-    float4 color;
-
-   switch (input.TextureInfo[2])
-   {
-       case 0:
-           color = tex2D(staticTilesSampler, input.TexCoord2);
-           break;
-       case 1:
-           color = tex2D(autoTilesSampler, input.TexCoord2);
-           break;
-       case 2: 
-           color = tex2D(autoTilesSampler, input.TexCoord2 + float2(frame, 0) * animOffset) * (1 - frameBlend) + tex2D(autoTilesSampler, input.TexCoord2 + float2(nextframe, 0) * animOffset) * frameBlend;
-           break;
-   }
-
-   clip(color.a - alpha);
-
-   return color;
-}
-
-float4 PixelLayer3(VertexShaderOutput input, uniform float alpha) : COLOR0
-{
-   if(input.TextureInfo[0] < 3)
-       discard;
-
-    float4 color;
-
-   switch (input.TextureInfo[3])
-   {
-       case 0:
-           color = tex2D(staticTilesSampler, input.TexCoord3);
-           break;
-       case 1:
-           color = tex2D(autoTilesSampler, input.TexCoord3);
-           //color = float4(0,1,0,1);
-           break;
-       case 2:
-           color = tex2D(autoTilesSampler, input.TexCoord3 + float2(frame, 0) * animOffset) * (1 - frameBlend) + tex2D(autoTilesSampler, input.TexCoord3 + float2(nextframe, 0) * animOffset) * frameBlend;
+           color = tex2D(autoTilesSampler, coord + float2(frame, 0) * animOffset) * (1 - frameBlend) + tex2D(autoTilesSampler, coord + float2(nextframe, 0) * animOffset) * frameBlend;
            break;
    }
@@ -125,5 +80,5 @@
        DestBlend = Zero;
         VertexShader = compile vs_3_0 VertexShaderFunction();
-        PixelShader = compile ps_3_0 PixelLayer1(1);
+        PixelShader = compile ps_3_0 PixelLayer(1,1);
     }

@@ -134,5 +89,5 @@
        DestBlend = InvSrcAlpha;
        VertexShader = compile vs_3_0 VertexShaderFunction();
-        PixelShader = compile ps_3_0 PixelLayer2(0.00001);
+        PixelShader = compile ps_3_0 PixelLayer(2,0.00001);
    }

@@ -143,5 +98,5 @@
        DestBlend = InvSrcAlpha;
        VertexShader = compile vs_3_0 VertexShaderFunction();
-        PixelShader = compile ps_3_0 PixelLayer3(0.00001);
+        PixelShader = compile ps_3_0 PixelLayer(3,0.00001);
    }
 }
@@ -155,5 +110,5 @@
        DestBlend = InvSrcAlpha;
         VertexShader = compile vs_3_0 VertexShaderFunction();
-        PixelShader = compile ps_3_0 PixelLayer1(0.000001);
+        PixelShader = compile ps_3_0 PixelLayer(1,0.000001);
     }

@@ -164,5 +119,5 @@
        DestBlend = InvSrcAlpha;
        VertexShader = compile vs_3_0 VertexShaderFunction();
-        PixelShader = compile ps_3_0 PixelLayer2(0.000001);
+        PixelShader = compile ps_3_0 PixelLayer(2,0.000001);
    }

@@ -173,5 +128,5 @@
        DestBlend = InvSrcAlpha;
        VertexShader = compile vs_3_0 VertexShaderFunction();
-        PixelShader = compile ps_3_0 PixelLayer3(0.00001);
+        PixelShader = compile ps_3_0 PixelLayer(3,0.00001);
    }
 }

`

보시다시피 layer (type = uint)라는 새로운 입력 변수가 있습니다. 그리고 이제 3 대신 PixelLayer 함수 하나가 있습니다.

다음은 SplattedTileVertex.cs에 대한 통합 된 diff입니다.

@@ -11,5 +11,5 @@
     {
         internal Vector3 vertexPosition;
-        internal byte textures;
+        internal float textures;
         /// <summary>
         /// Texture 0 is static tiles
@@ -17,7 +17,7 @@
         /// Texture 2 is animated autotiles
         /// </summary>
-        internal byte texture1;
-        internal byte texture2;
-        internal byte texture3;
+        internal float texture1;
+        internal float texture2;
+        internal float texture3;
         internal Vector2 texturePos1;
         internal Vector2 texturePos2;
@@ -27,8 +27,8 @@
         (
             new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
-            new VertexElement(12, VertexElementFormat.Byte4, VertexElementUsage.PointSize, 0),
-            new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
-            new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 1),
-            new VertexElement(32, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 2)
+            new VertexElement(12, VertexElementFormat.Vector4, VertexElementUsage.PointSize, 0),
+            new VertexElement(28, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
+            new VertexElement(36, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 1),
+            new VertexElement(44, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 2)
         );

예, 유형을 변경했습니다.

그리고 이제 문제가 드러납니다. 입력이 처리되는 방식 때문에 부동 소수점은 절대 정수 값과 완전히 같지 않을 것입니다. 이것의 뒤에있는 추론은이 쓰레드를 넘어서지만, 어쩌면 나는 그것에 커뮤니티 위키를 만들어야 할 것이다.

그래서, 무슨 일이 일어 났습니까?

Ok. 그래서 우리는 레이어에없는 값을 (if input.TextureInfo[0] < layer -> discard) . 내부 input.TextInfo [layer]에는 플로트가 있습니다. 이제 우리는 float을 우리의 uint 레이어 값과 비교합니다. 그리고 여기서 마술이 일어납니다. 일부 픽셀은 정확히 일치 (또는 해당 레이어 값 바로 위에있을 수 있습니다.) 유형이 (u) int 인 경우에는 코드별로 좋지만 그렇지는 않습니다.

어떻게 해결할 수 있을까요? 그곳에는 아마도 규칙이있을 것입니다. 움직이는 코드는 타일이 반쯤있는 경우 타일에 픽셀을 렌더링합니다. 우리는 레이어와 동일한 작업을 수행합니다.

다음은 SplattedTileShader.fx의 수정 사항 (통합 된 diff)입니다.

@@ -42,28 +42,24 @@
 float4 PixelLayer(VertexShaderOutput input, uniform uint layer, uniform float alpha) : COLOR0
 {
-   if(input.TextureInfo[0] < layer)
+   if(input.TextureInfo[0] < (float)layer - 0.5)
        discard;

    float4 color;
    float2 coord;
-   if(layer == 1)
+   if(layer < 1.5)
        coord = input.TexCoord1;
-   else if(layer == 2)
+   else if(layer < 2.5)
        coord = input.TexCoord2;
-   else if(layer == 3)
+   else
        coord = input.TexCoord3;

-   switch (input.TextureInfo[layer])
-   {
-       case 0:
-           color = tex2D(staticTilesSampler, coord);
-           break;
-       case 1:
-           color = tex2D(autoTilesSampler, coord);
-           break;
-       case 2:
-           color = tex2D(autoTilesSampler, coord + float2(frame, 0) * animOffset) * (1 - frameBlend) + tex2D(autoTilesSampler, coord + float2(nextframe, 0) * animOffset) * frameBlend;
-           break;
-   }
+   float type = input.TextureInfo[layer];
+
+   if (type < 0.5)
+       color = tex2D(staticTilesSampler, coord);
+   else if (type < 1.5)
+       color = tex2D(autoTilesSampler, coord);
+   else
+       color = tex2D(autoTilesSampler, coord + float2(frame, 0) * animOffset) * (1 - frameBlend) + tex2D(autoTilesSampler, coord + float2(nextframe, 0) * animOffset) * frameBlend;

    clip(color.a - alpha);

이제 모든 유형이 정확합니다. 코드가 정상적으로 작동하고 문제가 해결되었습니다. 그것은 처음에 내가 지적한 discard(...) 코드로 할 일이 없었습니다.

이 문제를 해결하는 데 참여해 주신 모든 분들께 감사드립니다.

Question

우리는 XNA를 사용하여 하향식 RPG를 개발 중입니다. 최근 우리지도를 표시하는 코드를 작성할 때 우리는 좌절에 부 닥쳤다. 지도를 그릴 때, 정상적인 변환 행렬을 가진 하향식 뷰는 모든 것이 잘된 것처럼 보입니다. 위 또는 아래를 흉내 내기 위해 비평 행 변환 행렬을 사용할 때 카메라가 위치를 바꿀 때 주위를 움직이는 검은 색 선 (위쪽 또는 아래쪽 열, 왼쪽 또는 오른쪽 열이 압착 될 때)이 나타납니다. 이동 및 배치는 무작위로 나타납니다. (이미지가 더 아래로 제공됩니다.)

배경 정보

맵은 타일로 구성됩니다. 원래 텍스처에는 32x32 픽셀로 구성된 타일이 있습니다. 이 삼각형에 2 개의 삼각형을 만들고 원래 텍스처의 일부를 표시하여 타일을 그립니다. 셰이더가 우리를 위해이 작업을 수행합니다. 삼각형의 세 가지 레이어가 있습니다. 먼저 모든 불투명 한 타일과 모든 반투명 및 부분 투명 타일의 모든 불투명 한 픽셀을 그리고 나서 모든 반투명 및 부분 투명 타일과 픽셀을 그립니다. 이것은 잘 동작합니다 (그러나 부동 소수점 인수로 확대 / 축소 할 때 색상 조합 된 선이 타일 행 및 / 또는 열 사이에 있음).

Renderstates

모든 타일에 동일한 래스터 라이저 상태를 사용하고 솔리드 또는 반투명 타일을 드로잉 할 때 두 개를 전환합니다.

_rasterizerState = new RasterizerState();
_rasterizerState.CullMode = CullMode.CullCounterClockwiseFace;

_solidDepthState = new DepthStencilState();
_solidDepthState.DepthBufferEnable = true;
_solidDepthState.DepthBufferWriteEnable = true;

_alphaDepthState = new DepthStencilState();
_alphaDepthState.DepthBufferEnable = true;
_alphaDepthState.DepthBufferWriteEnable = false;

그늘에서 다음과 같이 SpriteBlendMode를 설정합니다.

제 1의 고체 층 (1)은

AlphaBlendEnable = False; 
SrcBlend = One; 
DestBlend = Zero; 

다른 모든 단색 및 투명 레이어 (나중에 그려야 함)는

AlphaBlendEnable = True; 
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha; 

다른 쉐이더도 이것을 사용합니다. 사용 된 SpriteFontsSpriteBatch 는 기본 설정을 사용합니다.

생성 된 텍스처

일부 타일은 즉석에서 생성되어 파일로 저장됩니다. 지도가로드되면 파일이로드됩니다. 이것은 다음과 같이 생성 된 RenderTarget 사용하여 수행됩니다 :

RenderTarget2D rt = new RenderTarget2D(sb.GraphicsDevice, 768, 1792, false, 
    SurfaceFormat.Color, DepthFormat.None);
    sb.GraphicsDevice.SetRenderTarget(rt);

파일이 생성되면 파일이 저장되고로드됩니다. 따라서 RenderTarget 에 더 이상 존재하지 않으므로 장치가 재설정 될 때 파일이 손실되지 않습니다. 밉 매핑을 사용하여 시도했지만 스프라이트 시트입니다. 타일 ​​배치 장소에 대한 정보가 없기 때문에 밉 매핑은 쓸모가 없으며 문제를 해결하지 못했습니다.

정점들

우리는 모든 위치를 순환합니다. 부동 소수점은 아직 없지만 위치는 Vector3 (Float3)입니다.

for (UInt16 x = 0; x < _width;  x++)
{
    for (UInt16 y = 0; y < _heigth; y++)
    {
        [...]
        position.z = priority; // this is a byte 0-5

타일을 배치하려면 다음 코드가 사용됩니다.

tilePosition.X = position.X;
tilePosition.Y = position.Y + position.Z;
tilePosition.Z = position.Z;

알다시피, 부동 소수점은 32 비트이고 정밀도는 24 비트입니다. z의 최대 비트 값은 8 비트 (5 = 00000101)입니다. X와 Y의 최대 값은 16 비트입니다. 24 비트. 나는 부동 소수점의 관점에서 잘못 될 수 없다고 생각했다.

this.Position = tilePosition;

정점이 설정되면 다음과 같이 정점이 설정됩니다 (모든 정점이 동일한 타일 위치를 공유 함)

Vector3[] offsets  = new Vector3[] { Vector3.Zero, Vector3.Right, 
    Vector3.Right + (this.IsVertical ? Vector3.Forward : Vector3.Up), 
    (this.IsVertical ? Vector3.Forward : Vector3.Up) };
Vector2[] texOffset = new Vector2[] { Vector2.Zero, Vector2.UnitX, 
    Vector2.One, Vector2.UnitY };

for (int i = 0; i < 4; i++)
{
    SetVertex(out arr[start + i]);
    arr[start + i].vertexPosition = Position + offsets[i];

    if (this.Tiles[0] != null)
        arr[start + i].texturePos1 += texOffset[i] * this.Tiles[0].TextureWidth;
    if (this.Tiles[1] != null)
        arr[start + i].texturePos2 += texOffset[i] * this.Tiles[1].TextureWidth;
    if (this.Tiles[2] != null)
        arr[start + i].texturePos3 += texOffset[i] * this.Tiles[2].TextureWidth;
}

쉐이더

셰이더는 애니메이션 타일과 정적 타일을 그릴 수 있습니다. 둘 다 다음 샘플러 상태를 사용합니다.

sampler2D staticTilesSampler = sampler_state { 
    texture = <staticTiles> ; magfilter = POINT; minfilter = POINT; 
    mipfilter = POINT; AddressU = clamp; AddressV = clamp;};

셰이더는 다른 샘플러 상태를 설정하지 않으며 코드에도 포함되지 않습니다.

매 회마다 다음 줄을 사용하여 알파 값으로 클립합니다 (검정 픽셀을 얻지 못합니다).

clip(color.a - alpha)

알파는 솔리드 레이어 1에서는 1이고 다른 레이어에서는 거의 0입니다. 즉, 알파의 일부가있는 경우 맨 아래의 레이어가 아니라면 그 레이어가 그려지는 것을 의미합니다 (우리는 그 레이어로 무엇을해야할지 모르기 때문입니다).

카메라

우리는 카메라를 사용하여 타일에서 위에서 아래로 룩업을 모방하여 z 값을 사용하여 외부 레이어 데이터 (3 개의 레이어가 항상 올바른 순서가 아님)로 레이어를 정렬하여 평면으로 표시합니다. 이것은 또한 잘 작동합니다. 카메라가 변환 행렬을 업데이트합니다. 왜 이것이 이상한 구조를 가지고 있는지 궁금해하신 다면요 .AddChange - 코드는 Double Buffered입니다 (이것도 가능합니다). 변환 행렬은 다음과 같이 형성됩니다.

// First get the position we will be looking at. Zoom is normally 32
Single x = (Single)Math.Round((newPosition.X + newShakeOffset.X) * 
    this.Zoom) / this.Zoom;
Single y = (Single)Math.Round((newPosition.Y + newShakeOffset.Y) * 
    this.Zoom) / this.Zoom;

// Translation
Matrix translation = Matrix.CreateTranslation(-x, -y, 0);

// Projection
Matrix obliqueProjection = new Matrix(1, 0, 0, 0,
                                      0, 1, 1, 0,
                                      0, -1, 0, 0,
                                      0, 0, 0, 1);

Matrix taper = Matrix.Identity; 

// Base it of center screen
Matrix orthographic = Matrix.CreateOrthographicOffCenter(
    -_resolution.X / this.Zoom / 2, 
     _resolution.X / this.Zoom / 2, 
     _resolution.Y / this.Zoom / 2, 
    -_resolution.Y / this.Zoom / 2, 
    -10000, 10000);

// Shake rotation. This works fine       
Matrix shakeRotation = Matrix.CreateRotationZ(
    newShakeOffset.Z > 0.01 ? newShakeOffset.Z / 20 : 0);

// Projection is used in Draw/Render
this.AddChange(() => { 
    this.Projection = translation * obliqueProjection * 
    orthographic * taper * shakeRotation; }); 

추론 및 흐름

타일 ​​데이터는 3 개의 레이어로 구성됩니다. 각 타일은 IsSemiTransparent 의해 정의됩니다. 타일이 IsSemiTransparent 인 경우 IsSemiTransparentIsSemiTransparent 타일 ​​뒤에 IsSemiTransparent 합니다. 타일 ​​데이터는 SplattedTile 인스턴스에로드 될 때 스택됩니다. 따라서 타일 데이터의 레이어 1이 비어 SplattedTile 의 레이어 1에는 첫 번째 레이어에 타일 데이터가 있습니다 (적어도 하나의 레이어에는 타일 데이터가 있음). 그 이유는 Z-buffer 가 그 뒤에 솔리드 픽셀이 없기 때문에 순서대로 그려지면 블렌딩 대상을 알지 못하기 때문입니다.

레이어에는 az 값이 없으며 개별 타일 데이터에 있습니다. 지상 타일 인 경우 Priority = 0 입니다. 따라서 Priority 가 동일한 타일을 레이어 (그리기 순서)와 불투명 (반투명, 불투명) 순서로 정렬합니다. 우선 순위가 다른 타일은 우선 순위에 따라 그려집니다.

첫 번째 단색 레이어에는 대상 픽셀이 없으므로 DestinationBlend.Zero 설정합니다. 또한 AlphaBlending 필요 없기 때문에 AlphaBlending 필요하지 않습니다. 이미 색 데이터가 있고 그에 따라 혼합해야하는 경우 다른 레이어 (5, 2 솔리드, 3 투명)가 그려 질 수 있습니다.

6 패스를 반복하기 전에, projection matrix 이 설정됩니다. 테이퍼를 사용하지 않으면이 기능이 작동합니다. 테이퍼를 사용할 때 그렇지 않습니다.

문제

우리는 테이퍼를 적용하여 약간의 행렬을 사용하여 좀 더 깊이를 모방하고 싶습니다. 몇 가지 값을 시도했지만 예제가 있습니다.

new Matrix(1, 0, 0, 0,
           0, 1, 0, 0.1f,
           0, 0, 1, 0,
           0, 0, 0, 1);

화면 (높이 값 0의 모든 항목, 모든 평면 항목)이 압착됩니다. y가 낮을수록 (화면에서 높을수록) 압착이 심합니다. 이것은 실제로 작동하지만 지금은 거의 모든 곳에서 임의의 검은 선이 나타납니다. 몇 개의 타일을 제외하는 것처럼 보이지만 상관 관계가 무엇인지 알지 못합니다. 보간이나 밉맵과 관련이 있다고 생각합니다.

그리고 내가 말하는 것에 대해 보여주는 이미지가 있습니다. .

영향을받지 않는 타일은 맨 아래 레이어에 정적 타일이 아닌 것처럼 보입니다. 그러나 그 위에있는 투명 타일은 다른 그래픽 인공물을 나타냅니다. 그들은 행을 놓치기 때문에 행이 삭제됩니다. 나는 그것이 일어나는 것에 대한 힌트라고 생각하기 때문에이 텍스트를 표시했다. mip mag and minfilterLinear 놓으면 수직선 이 나타납니다.

다음은 레이어 2 또는 3의 타일에 아티팩트가 표시되어 확대 된 이미지입니다 (게임 줌에서).

우리는 이미 시도했다.

  • Point 또는 Linear mipfilter
  • 원래 텍스처에 GenerateMipMaps 설정하기
  • GenerateMipMaps 된 텍스처에 GenerateMipMaps 설정 ( RenderTarget true 플래그 생성자)
  • 밉 매핑을 켜기 (필자가 스프라이트 시트를 밉맵으로 사용 하기 때문에 줌아웃 할 때 아티팩트가 더 많이 생겼다 .
  • 레이어 2와 레이어 3을 그리지 않음 (실제로 모든 타일에 검정색 선이 있음)
  • DepthBufferEnable = false
  • 모든 단색 레이어를 SrcBlend = One; DestBlend = Zero;
  • 모든 단색 레이어를 ScrBlend = SrcAlpha; 로 설정합니다 ScrBlend = SrcAlpha; DestBlend = InvSrcAlpha;
  • 투명 레이어를 그리지 않습니다 (선은 여전히 ​​있음).
  • shader 에서 clip(opacity) 제거 이 명령은 일부 줄만 제거합니다. 우리는 이것을 더 조사하고 있습니다.
  • msdn, 및 google (행운과 함께)을 사용하여 동일한 문제를 검색합니다.

누구든지이 문제를 인식합니까? 마지막으로, 우리는 타일을 그린 후에 SpriteBatch 호출하고, 아바타에 다른 Shader 를 사용합니다 (높이> 0이기 때문에 별다른 문제가 없음). sampler state 취소합니까? 또는...?




당신이 우리에게 준 것과 함께, 나는 당신의 코드 레이어링에 대해 매우 의심스러워 할 것입니다. 이것은 실제로 맨 아래 레이어가 부동 소수점 반올림에 따라 맨 위에 있고 숨겨져있는 레이어를 뚫고 지나가는 것처럼 보입니다. 보기 각도에 수직 인 줄무늬는 정확히 동일 평면 상에 있어야하는 두 개의 삼각형을 가지고 있지만 어떤 이유로 든 정확히 동일한 꼭지점 좌표가없는 경우 (예 : 다른 하나가 더 큼) 매우 일반적인 효과입니다. 서로 다른 층을 매우 작게 그린다면 어떻게 될까요? 마찬가지로 아래쪽 솔리드 레이어는 -0.00002에 그리고 그 다음은 -0.00001에 그리고 위쪽 레이어는 0에 그려야합니다 (3 개가 모두 0으로 그려진다는 가정하에).

특히 XNA에 대해서는 잘 모르겠지만 레이어링 문제는 항상 부동 소수점을 사용하여 기하학을 표현하는 근본적인 문제이며 XNA가 "마법처럼"당신을 피할 경우 놀라실 것입니다. 왜 일부 타일들은 괜찮지 만 대부분은 망가 졌는지 확실하지 않습니다. 아마도 그 타일들은 단지 운이 좋았을 것입니다. 부동 소수점 오류로 인한 문제는 종종 이와 같이 매우 이상하게 작용합니다.

레이어를 약간 분리해도 도움이되지 않는다면 표준 주석 기반 디버깅으로 축소 될 것입니다. 투명 레이어가없는 애니메이션 타일이없는 스프라이트없이 시도해보십시오. & c. 그것이 일어날 때 멈추었을 때, 당신이 방금 논평 한 것은 무엇이든 그것을 깨뜨리는 것입니다 : P



Related