1
$\begingroup$

I am using RT shader (DXR) to generate g-buffers with code below. There was no problems with smaller scene (pink room from cwyman tutorial - http://cwyman.org/code/dxrTutors/tutors/Tutor5/tutorial05.md.html ). However, when I moved to bigger scene (Sun Temple by Epic Games - https://developer.nvidia.com/ue4-sun-temple ), I've started noticing problems with texture sampling. Please compare textures at the end of this post. The greater the distance to world origin (0, 0, 0), the more jaggy artifacts appear and quality becomes worse.

At the beginning, I was suspecting acceleration structures. But skybox quality is becoming worse, so it's probably unrelated to AS.

inline void GenerateCameraRay(uint2 index, uint2 dimensions, float4x4 projectionToWorld, inout  float3 origin, out float3 direction)
{
    float2 xy = index + float2(0.5f, 0.5f); // center in the middle of the pixel.
    float2 screenPos = (xy / (float2) dimensions) * 2.0 - 1.0;

    // Invert Y for DirectX-style coordinates.
    screenPos.y = -screenPos.y;

    // Unproject the pixel coordinate into a ray.
    float4 world = mul(float4(screenPos, 0, 1), projectionToWorld);

    world.xyz /= world.w;
    direction = normalize(world.xyz - origin);
}

[shader("raygeneration")]
void RayGen()
{
    float3 rayDir;
    float3 origin = g_sceneCB.cameraPosition.xyz;
    
    // Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid.
    GenerateCameraRay(DispatchRaysIndex().xy, DispatchRaysDimensions().xy, g_sceneCB.projectionToWorld, origin, rayDir);

    RayDesc ray = { origin, 1e-4f, rayDir, 1e+38f };
    RayPayload payload = { 0 };
    TraceRay(SceneBVH, RAY_FLAG_NONE, 0xFF, 0, 1, 0, ray, payload);
}
    
[shader("miss")]
void Miss(inout RayPayload payload)
{
    float3 rayDir = WorldRayDirection();
    rayDir.z = -rayDir.z;

    RTOutputAlbedo[DispatchRaysIndex().xy] = float4(skyboxTexture.SampleLevel(g_sampler, rayDir, 0).rgb, 0);
    RTOutputNormal[DispatchRaysIndex().xy] = float4(0, 0, 0, 0);
    RTOutputSpecRoughness[DispatchRaysIndex().xy] = float4(0, 0, 0, 0);
}

enter image description here enter image description here

$\endgroup$
1
$\begingroup$

Problem was that perspective matrix had very short Z_NEAR and Z_FAR values (0.01f and 200.0f). By changing it to much higher range (10.0f, 20000.0f), problem with jaggies and artifacts disappears.

| improve this answer | |
$\endgroup$
  • $\begingroup$ You could generate rays without using a near/far plane so you avoid introducing precision loss $\endgroup$ – PaulHK Sep 18 at 6:46
  • $\begingroup$ @PaulHK I'm using inverse viewProj matrix to transform ray from ndc to world space. What is other way of generating ray direction? $\endgroup$ – DirectX_Programmer Sep 18 at 7:20
  • 2
    $\begingroup$ You could interpolate between the 4 far corner positions of your view frustum in screen space (keep the distance near 1, we only care about direction and not length) and generate per-pixel ray directions from that. The ray starts at the eye position. $\endgroup$ – PaulHK Sep 18 at 7:37
  • 2
    $\begingroup$ Your current solution of modifying near/far to be close in magnitude is also valid, ray generation shouldn't need to concern itself with far/near planes $\endgroup$ – PaulHK Sep 18 at 7:41
  • $\begingroup$ Yeah, it worked for me and for now I don't need to change it and I've seen that invViewProj matrix is used in many code samples. I don't know how it looks in industry standard AAA engines, but I'm grateful for an insight of other method of casting rays. $\endgroup$ – DirectX_Programmer Sep 18 at 11:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.