모델 주위의 이상한 흰색 윤곽선


19

XNA 4에서 게임을하고 있는데 최근 이 안내서에 따라 지연된 음영 구현으로 전환했습니다 . 내 모델에 이상한 흰색 윤곽선이 나타나고 있는데이 원인이 무엇인지 잘 모르겠습니다. 일반 렌더 타겟 또는 뎁스 렌더 타겟의 정밀도가 떨어졌을 수도 있지만 32 (컬러) 대신 64 비트 (Rgba64)로 늘리면 도움이되지 않습니다. 또한 스페 큘러 계산에 문제가 있다고 생각하여 스페 큘러를 0으로 설정하려고 시도했지만 도움이되지 않았습니다. PIX에서 픽셀을 디버깅하면 확산 값이 해당 픽셀에 대해 거의 흰색으로 계산됩니다. 어떤 아이디어? 아래에 문제의 그림이 포함되어있어 전체 크기로보기가 더 쉽습니다.

픽셀 쉐이더 :

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    input.ScreenPosition.xy /= input.ScreenPosition.w;

    float2 texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1) - halfPixel;

    float4 normalData = tex2D(normalSampler, texCoord);

    //Transform normal back into [-1, 1] range
    float3 normal = normalize(2.0f * normalData.xyz - 1.0f);

    float specularPower = normalData.a;
    float specularHardness = tex2D(colorSampler, texCoord).a * 255;
    float depthVal = tex2D(depthSampler, texCoord).r;

    //Compute screen-space position
    float4 position = float4(input.ScreenPosition.xy, depthVal, 1.0f);

    //Transform to world space
    position = mul(position, InvertViewProjection);
    position /= position.w;

    //Surface-to-light vector
    float3 lightVector = lightPosition - position;

    float3 projectedTexCoords = position - lightPosition;
    projectedTexCoords = mul(projectedTexCoords, float3x3(
                            float3(-1, 0, 0),
                            float3(0, 1, 0),
                            float3(0, 0, 1)));

    float distanceToLight = length(lightVector) / lightRadius;
    float shadow = ShadowContribution(projectedTexCoords, distanceToLight);

    float attenuation = saturate(1.0f - distanceToLight);

    lightVector = normalize(lightVector);

    //Compute diffuse light
    float normalDotLight = max(0, dot(normal, lightVector));
    float3 diffuseLight = normalDotLight * Color.rgb;

    float3 reflectionVector = normalize(reflect(-lightVector, normal));
    float3 directionToCamera = normalize(cameraPosition - position);
    float specularLight = specularPower * pow(saturate(dot(reflectionVector, directionToCamera)), specularHardness);

    return shadow * attenuation * lightIntensity * float4(diffuseLight.rgb, specularLight);
}

편집 : JPG에 대해 죄송합니다. stackexchange의 업 로더가 자체적으로 수행했습니다. Roy T : XNA3에서 변경된 부분에 대한 튜토리얼의 XNA4 변환을 실제로 참조했습니다. 코드를 크게 변경하지 않았기 때문에이 버그는 원래 존재했지만 너무 많은 조명이 모두 움직이는 것으로 볼 수는 없다고 생각했기 때문에 하나의 조명을 제외한 모든 조명을 제거하고 버그가 다시 나타났습니다 (보기 도마뱀 팔꿈치 근처)

내 장면의 GBuffer 내용은 다음과 같습니다.

컬러 버퍼 : 깊이 버퍼 : 일반 버퍼 : 최종 렌더링 :

편집 2 :

컬러 맵을 샘플링 할 때 문제가 CombineFinal.fx라고 의심되기 시작합니다. 이것은 흰색 픽셀 바로 옆에 올바르게 채색 된 픽셀에 대한 계산입니다.

diffuseColor        : (0.435, 0.447, 0.412)
diffuseLight        : (1.000, 1.000, 0.902)
light               : (1.000, 1.000, 0.902, 0.000)
PixelShaderFunction : (0.435, 0.447, 0.371, 1.000)
specularLight       : 0.000

그리고 이것은 바로 옆에 부적절한 색상의 흰색 픽셀의 출력입니다.

diffuseColor        : (0.824, 0.792, 0.741)
diffuseLight        : (1.000, 1.000, 0.902)
light               : (1.000, 1.000, 0.902, 0.000)
PixelShaderFunction : (0.824, 0.792, 0.669, 1.000)
specularLight       : 0.000

spreadColor는 유일한 차이점이며이 색상은 색상 맵에서 직접 가져옵니다. 샘플링 할 텍스처 좌표 계산에 약간의 오류가 있습니까?

조명 패스 :


4
미묘한 그래픽 결함을 보여주는 스크린 샷을 jpeg로 압축하지 마십시오. 사람들은 완벽한 생식으로 문제를보고 싶어 할 것입니다.
aaaaaaaaaaaa

jpeg 압축은 실제로 하나의 픽셀 만 특정 부분이 재결합 될 때 (Z 깊이의 큰 차이와 모든 픽셀의 조명이 매우 높음) 글리치가 꽤 훌륭하다고 생각합니다. 행운을 빕니다, 지연 렌더링은 상당히 기술적 인 것입니다.
Valmond

2
그것이 도움이되는지 확실하지 않지만 매우 오래된 버전의 코드 / 튜토리얼을 사용하고 있다면 Catalin Zima의 실제 코드 / 튜토리얼은 현재 catalinzima.com/tutorials/deferred-rendering-in-xna 및 승인 된 XNA4.0에 있습니다. 버전은 여기에 있습니다 : roy-t.nl/index.php/2010/12/28/…
Roy T.

또한 지연된 렌더링 디버깅과 마찬가지로 모든 버퍼에서 스크린 샷을 게시 할 수 있습니까? 아마도 조명 버퍼에 있지만 다른 것일 수 있습니다.
Roy T.

내 본능은 알고리즘의 일부가 정확히 90도 각도를 처리하는 방식에 문제가 있다는 것입니다.하지만 더 자세히 살펴 보려면 작업 후에 ode를 가지고 놀아야합니다.
Jordaan Mylonas

답변:


4

지연된 렌더러를 시작할 때 모델 주위에이 흰색 윤곽선이나 "후광"도있었습니다. 문제는 렌더링 대상 오버레이에 대한 텍스처 오프셋 값이 올바르게 설정되지 않았다는 것입니다. 일부 텍스처는 -0.5 픽셀 대신 오프셋에 +0.5 픽셀로 설정해야했습니다.

윤곽선이 사라진 일부 텍스처 오프셋의 값을 조정 한 후에 만 ​​가능했습니다. 조명 쉐이더 중 하나 일 가능성이 높습니다.

편집 : 나는 또한 당신의 예에서 나온 Catalin Zima의 튜토리얼에서 배웠으므로 작동해야합니다.


그렇습니다. 라이트 쉐이더의 모든 좌표 샘플링을 위해 + halfPixel로 변경했으며 후광이 사라졌습니다.
Telanor

0

정확히 무슨 일이 일어나고 있는지 확실하지 않지만 몇 가지 확인해야 할 사항이 있습니다.

  1. G- 버퍼를 샘플링 할 때 이중 선형 또는 이방성 또는 다른 물체가없는 텍스처 필터링이 해제되어 있는지 확인하십시오.

  2. 텍스처 좌표에 반 픽셀 오프셋을 추가하는 것을 보았습니다. 맞는지 다시 확인하십시오. 올바른 오프셋이 무엇인지 알기 위해 XNA에 익숙하지는 않지만 G 버퍼 중 하나를 샘플링하고 샘플을 출력하는 셰이더를 작성하여 확인할 수 있습니다. 그런 다음이 버튼을 앞뒤로 넘기고 G- 버퍼를 화면에 직접 표시하십시오. 올바른 오프셋이 있으면 단일 픽셀이 아닌 차이가 없어야합니다.


나는 가서 GBuffer와 관련된 모든 것을 POINT (필터링을 비활성화한다고 가정 함)와 여전히 동일하게 변경했습니다. 두 번째 포인트에 관해서는 GBuffer를 직접 출력하는 것이 똑같지 않습니다. 데이터를 출력하는 셰이더를 만드시겠습니까? 좀 더 자세히 설명해 주시겠습니까?
Telanor

글쎄, 위의 G- 버퍼 스크린 샷은 어떻게 생성 했습니까? 픽셀을 G 버퍼에서 화면 (백 버퍼)으로 일대일로 복사하기 위해 일종의 내장 API 함수를 호출한다고 가정합니까? (나는 XNA를 알지 못하므로 그것이 무엇인지 알 수 없습니다.) 내장 일대일 복사 기능의 출력을 수행하도록 작성된 픽셀 쉐이더의 출력과 비교하십시오. 일대일 복사 ... 그러면 텍스처 좌표가 정확히 정확하고 실제로 일대일 샘플링을 받고 있는지 확인할 수 있습니다 .
Nathan Reed
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.