// Hit information, aka ray payload // This sample only carries a shading color and hit distance. // Note that the rayPayload should be kept as small as possible, // and that its size must be declared in the corresponding // D3D12_RAYTRACING_SHADER_CONFIG pipeline subobjet. #pragma pack_matrix(row_major) #define MAX_TRANSPACENT_HITS 5 struct SingleHit { float4 color; float3 normal; float distance; int dayLight; int dynamicLight; }; struct [raypayload] RayHits { SingleHit hits[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit, miss); int hitCount : write(caller, anyhit, closesthit, miss) : read(caller, anyhit, closesthit, miss); }; // Attributes output by the raytracing when hitting a surface, // here the barycentric coordinates struct ChunkHitAttributes { float2 texCoord; float3 normal; int textureId; int dayLight; int dynamicLight; }; struct SimpleBlocksAttributes { float2 bary; }; struct VertexData { float2 texcoord; float3 normal; }; int packLight(float3 light) { uint r = (uint) (light.r * 255.0) & 0xFF; uint g = (uint) (light.g * 255.0) & 0xFF; uint b = (uint) (light.b * 255.0) & 0xFF; return (int) ((r << 16) | (g << 8) | b); } float3 unpackLight(int light) { float r = ((light >> 16) & 0xFF) / 255.0f; float g = ((light >> 8) & 0xFF) / 255.0f; float b = (light & 0xFF) / 255.0f; return float3(r, g, b); } void applyHit(inout RayHits rayPayload, in SingleHit hit) { for (int i = 0; i < rayPayload.hitCount; i++) { if (rayPayload.hits[i].distance > hit.distance) { SingleHit tmpHit = rayPayload.hits[i]; rayPayload.hits[i] = hit; if (hit.color.w == 1.f) { rayPayload.hitCount = i + 1; } else { for (int j = i + 1; j < rayPayload.hitCount + 1 && j < MAX_TRANSPACENT_HITS; j++) { SingleHit tmpHit2 = rayPayload.hits[j]; rayPayload.hits[j] = tmpHit; tmpHit = tmpHit2; } } return; } else { if (rayPayload.hits[i].color.w == 1.f) { return; } } } if (rayPayload.hitCount < MAX_TRANSPACENT_HITS) { rayPayload.hits[rayPayload.hitCount] = hit; rayPayload.hitCount++; } } // Global resources Texture2D textures[] : register(t0, space1); SamplerState gSampler : register(s0, space0); cbuffer DX12ShaderLightInfo : register(b0, space1) { float3 dayLightFactor; uint padding; float3 dayLightDirection; }; // Raytracing acceleration structure, accessed as a SRV RaytracingAccelerationStructure TLAS : register(t0, space0); RWTexture2D gOutput : register(u0); RWTexture2D guiTexture : register(u1); cbuffer RayGenerationSettings : register(b0, space0) { int renderGui; int useRays; float minDistance; float maxDistance; float4x4 inverseView; float4x4 inverseProjection; }; float3 getLight(ByteAddressBuffer lightBuffer, int index) { uint raw = lightBuffer.Load((index / 4) * 4); uint shift = (index % 4) * 8; float r = ((raw >> shift) & 0xFF) / 255.0; shift += 8; if (shift == 32) { raw = lightBuffer.Load((index / 4) * 4 + 4); shift = 0; } float g = ((raw >> shift) & 0xFF) / 255.0; shift += 8; if (shift == 32) { raw = lightBuffer.Load((index / 4) * 4 + 4); shift = 0; } float b = ((raw >> shift) & 0xFF) / 255.0; return float3(r, g, b); }