|
| 1 | +#ifndef PATH_TRACER_USE_RWMC |
| 2 | +#error PATH_TRACER_USE_RWMC must be defined before including compute_render_scene_impl.hlsl |
| 3 | +#endif |
| 4 | + |
| 5 | +namespace pathtracer_render_variant |
| 6 | +{ |
| 7 | +using namespace nbl; |
| 8 | +using namespace hlsl; |
| 9 | + |
| 10 | +using ray_dir_info_t = bxdf::ray_dir_info::SBasic<float>; |
| 11 | +using iso_interaction = PTIsotropicInteraction<ray_dir_info_t, spectral_t>; |
| 12 | +using aniso_interaction = PTAnisotropicInteraction<iso_interaction>; |
| 13 | +using sample_t = bxdf::SLightSample<ray_dir_info_t>; |
| 14 | +using iso_cache = bxdf::SIsotropicMicrofacetCache<float>; |
| 15 | +using aniso_cache = bxdf::SAnisotropicMicrofacetCache<iso_cache>; |
| 16 | + |
| 17 | +using iso_config_t = PTIsoConfiguration<sample_t, iso_interaction, spectral_t>; |
| 18 | +using iso_microfacet_config_t = PTIsoMicrofacetConfiguration<sample_t, iso_interaction, iso_cache, spectral_t>; |
| 19 | + |
| 20 | +using diffuse_bxdf_type = bxdf::reflection::SOrenNayar<iso_config_t>; |
| 21 | +using conductor_bxdf_type = bxdf::reflection::SGGXIsotropic<iso_microfacet_config_t>; |
| 22 | +using dielectric_bxdf_type = bxdf::transmission::SGGXDielectricIsotropic<iso_microfacet_config_t>; |
| 23 | +using iri_conductor_bxdf_type = bxdf::reflection::SIridescent<iso_microfacet_config_t>; |
| 24 | +using iri_dielectric_bxdf_type = bxdf::transmission::SIridescent<iso_microfacet_config_t>; |
| 25 | + |
| 26 | +using payload_type = Payload<float>; |
| 27 | +using randgen_type = RandomUniformND<Xoroshiro64Star, 3>; |
| 28 | +using material_system_type = MaterialSystem<bxdfnode_type, diffuse_bxdf_type, conductor_bxdf_type, dielectric_bxdf_type, iri_conductor_bxdf_type, iri_dielectric_bxdf_type, scene_type>; |
| 29 | + |
| 30 | +#if PATH_TRACER_USE_RWMC |
| 31 | +using accumulator_type = rwmc::CascadeAccumulator<rwmc::DefaultCascades<float32_t3, CascadeCount> >; |
| 32 | +#else |
| 33 | +using accumulator_type = path_tracing::DefaultAccumulator<float32_t3>; |
| 34 | +#endif |
| 35 | + |
| 36 | +template<NEEPolygonMethod PPM> |
| 37 | +struct SVariantTypes |
| 38 | +{ |
| 39 | + using ray_type = Ray<payload_type, PPM>; |
| 40 | + using raygen_type = path_tracing::BasicRayGenerator<ray_type>; |
| 41 | + using intersector_type = Intersector<ray_type, scene_type, aniso_interaction>; |
| 42 | + using nee_type = NextEventEstimator<scene_type, light_type, ray_type, sample_t, aniso_interaction, LIGHT_TYPE, PPM>; |
| 43 | + using pathtracer_type = path_tracing::Unidirectional<randgen_type, ray_type, intersector_type, material_system_type, nee_type, accumulator_type, scene_type>; |
| 44 | +}; |
| 45 | + |
| 46 | +RenderPushConstants getRenderPushConstants() |
| 47 | +{ |
| 48 | +#if PATH_TRACER_USE_RWMC |
| 49 | + return ::pc.renderPushConstants; |
| 50 | +#else |
| 51 | + return ::pc; |
| 52 | +#endif |
| 53 | +} |
| 54 | + |
| 55 | +template<NEEPolygonMethod PPM> |
| 56 | +void tracePixel(int32_t2 coords) |
| 57 | +{ |
| 58 | + const RenderPushConstants renderPushConstants = getRenderPushConstants(); |
| 59 | + using variant_types = SVariantTypes<PPM>; |
| 60 | + |
| 61 | + uint32_t width, height, imageArraySize; |
| 62 | + ::outImage.GetDimensions(width, height, imageArraySize); |
| 63 | + if (any(coords < int32_t2(0, 0)) || any(coords >= int32_t2(width, height))) |
| 64 | + return; |
| 65 | + |
| 66 | + float32_t2 texCoord = float32_t2(coords) / float32_t2(width, height); |
| 67 | + texCoord.y = 1.0 - texCoord.y; |
| 68 | + |
| 69 | + if (((renderPushConstants.depth - 1) >> MaxDepthLog2) > 0 || ((renderPushConstants.sampleCount - 1) >> MaxSamplesLog2) > 0) |
| 70 | + { |
| 71 | + ::outImage[uint3(coords.x, coords.y, 0)] = float32_t4(1.0, 0.0, 0.0, 1.0); |
| 72 | + return; |
| 73 | + } |
| 74 | + |
| 75 | + typename variant_types::pathtracer_type pathtracer; |
| 76 | + |
| 77 | + uint2 scrambleDim; |
| 78 | + ::scramblebuf.GetDimensions(scrambleDim.x, scrambleDim.y); |
| 79 | + const float32_t2 pixOffsetParam = float32_t2(1.0, 1.0) / float32_t2(scrambleDim); |
| 80 | + |
| 81 | + float32_t4 NDC = float32_t4(texCoord * float32_t2(2.0, -2.0) + float32_t2(-1.0, 1.0), 0.0, 1.0); |
| 82 | + float32_t3 camPos; |
| 83 | + { |
| 84 | + float32_t4 tmp = mul(renderPushConstants.invMVP, NDC); |
| 85 | + camPos = tmp.xyz / tmp.w; |
| 86 | + NDC.z = 1.0; |
| 87 | + } |
| 88 | + |
| 89 | + scene_type scene; |
| 90 | + scene.updateLight(renderPushConstants.generalPurposeLightMatrix); |
| 91 | + |
| 92 | + typename variant_types::raygen_type rayGen; |
| 93 | + rayGen.pixOffsetParam = pixOffsetParam; |
| 94 | + rayGen.camPos = camPos; |
| 95 | + rayGen.NDC = NDC; |
| 96 | + rayGen.invMVP = renderPushConstants.invMVP; |
| 97 | + |
| 98 | + pathtracer.scene = scene; |
| 99 | + pathtracer.randGen = randgen_type::create(::scramblebuf[coords].rg, renderPushConstants.pSampleSequence); |
| 100 | + pathtracer.nee.lights = lights; |
| 101 | + pathtracer.materialSystem.bxdfs = bxdfs; |
| 102 | + pathtracer.bxdfPdfThreshold = 0.0001; |
| 103 | + pathtracer.lumaContributionThreshold = hlsl::dot(colorspace::scRGBtoXYZ[1], colorspace::eotf::sRGB(hlsl::promote<spectral_t>(1.0 / 255.0))); |
| 104 | + pathtracer.spectralTypeToLumaCoeffs = colorspace::scRGBtoXYZ[1]; |
| 105 | + |
| 106 | +#if PATH_TRACER_USE_RWMC |
| 107 | + accumulator_type accumulator = accumulator_type::create(::pc.splattingParameters); |
| 108 | +#else |
| 109 | + accumulator_type accumulator = accumulator_type::create(); |
| 110 | +#endif |
| 111 | + |
| 112 | + for (int i = 0; i < renderPushConstants.sampleCount; ++i) |
| 113 | + { |
| 114 | + const float32_t3 uvw = pathtracer.randGen(0u, i); |
| 115 | + typename variant_types::ray_type ray = rayGen.generate(uvw); |
| 116 | + ray.initPayload(); |
| 117 | + pathtracer.sampleMeasure(ray, i, renderPushConstants.depth, accumulator); |
| 118 | + } |
| 119 | + |
| 120 | +#if PATH_TRACER_USE_RWMC |
| 121 | + for (uint32_t i = 0; i < CascadeCount; ++i) |
| 122 | + ::cascade[uint3(coords.x, coords.y, i)] = float32_t4(accumulator.accumulation.data[i], 1.0f); |
| 123 | +#else |
| 124 | + ::outImage[uint3(coords.x, coords.y, 0)] = float32_t4(accumulator.accumulation, 1.0); |
| 125 | +#endif |
| 126 | +} |
| 127 | + |
| 128 | +#if PATH_TRACER_ENABLE_LINEAR |
| 129 | +template<NEEPolygonMethod PPM> |
| 130 | +void runLinear(uint32_t3 threadID) |
| 131 | +{ |
| 132 | + uint32_t width, height, imageArraySize; |
| 133 | + ::outImage.GetDimensions(width, height, imageArraySize); |
| 134 | + tracePixel<PPM>(int32_t2(threadID.x % width, threadID.x / width)); |
| 135 | +} |
| 136 | +#endif |
| 137 | + |
| 138 | +#if PATH_TRACER_ENABLE_PERSISTENT |
| 139 | +template<NEEPolygonMethod PPM> |
| 140 | +void runPersistent() |
| 141 | +{ |
| 142 | + uint32_t width, height, imageArraySize; |
| 143 | + ::outImage.GetDimensions(width, height, imageArraySize); |
| 144 | + const uint32_t numWorkgroupsX = width / RenderWorkgroupSizeSqrt; |
| 145 | + const uint32_t numWorkgroupsY = height / RenderWorkgroupSizeSqrt; |
| 146 | + |
| 147 | + [loop] |
| 148 | + for (uint32_t wgBase = glsl::gl_WorkGroupID().x; wgBase < numWorkgroupsX * numWorkgroupsY; wgBase += glsl::gl_NumWorkGroups().x) |
| 149 | + { |
| 150 | + const int32_t2 wgCoords = int32_t2(wgBase % numWorkgroupsX, wgBase / numWorkgroupsX); |
| 151 | + morton::code<true, 32, 2> mc; |
| 152 | + mc.value = glsl::gl_LocalInvocationIndex().x; |
| 153 | + const int32_t2 localCoords = _static_cast<int32_t2>(mc); |
| 154 | + tracePixel<PPM>(wgCoords * int32_t2(RenderWorkgroupSizeSqrt, RenderWorkgroupSizeSqrt) + localCoords); |
| 155 | + } |
| 156 | +} |
| 157 | +#endif |
| 158 | +} |
0 commit comments