Răsfoiți Sursa

improve light calculation

Kolja Strohm 1 săptămână în urmă
părinte
comite
cb511203e4

+ 8 - 57
FactoryCraft/ChunkAnyHit.hlsl

@@ -1,7 +1,7 @@
 #include "Common.hlsl"
 
 [shader("anyhit")]
-void ChunkAnyHit(inout HitInfo rayPayload, ChunkHitAttributes attrib)
+void ChunkAnyHit(inout RayHits rayPayload, ChunkHitAttributes attrib)
 {
     if (rayPayload.hitCount < 0)
     { // shadow ray
@@ -17,62 +17,13 @@ void ChunkAnyHit(inout HitInfo rayPayload, ChunkHitAttributes attrib)
         IgnoreHit();
         return;
     }
-    float distance = RayTCurrent();
-    bool found = false;
-    for (int i = 0; i < rayPayload.hitCount; i++)
-    {
-        if (rayPayload.distance[i] > distance)
-        {
-            found = true;
-            float4 tmpColor = rayPayload.color[i];
-            rayPayload.color[i] = color;
-            float tmpDistance = rayPayload.distance[i];
-            rayPayload.distance[i] = distance;
-            int tmpDayLight = rayPayload.dayLight[i];
-            rayPayload.dayLight[i] = attrib.dayLight;
-            int tmpDynamicLight = rayPayload.dynamicLight[i];
-            rayPayload.dynamicLight[i] = attrib.dynamicLight;
-            if (color.w == 1.f)
-            {
-                rayPayload.hitCount = i + 1;
-            }
-            else
-            {
-                for (int j = i + 1; j < rayPayload.hitCount + 1 && j < MAX_TRANSPACENT_HITS; j++)
-                {
-                    float4 tmpColor2 = rayPayload.color[j];
-                    float tmpDistance2 = rayPayload.distance[j];
-                    int tmpDayLight2 = rayPayload.dayLight[j];
-                    int tmpDynamicLight2 = rayPayload.dynamicLight[j];
-                    rayPayload.color[j] = tmpColor;
-                    rayPayload.distance[j] = tmpDistance;
-                    rayPayload.dayLight[j] = tmpDayLight;
-                    rayPayload.dynamicLight[j] = tmpDynamicLight;
-                    tmpColor = tmpColor2;
-                    tmpDistance = tmpDistance2;
-                    tmpDayLight = tmpDayLight2;
-                    tmpDynamicLight = tmpDynamicLight2;
-                }
-            }
-            break;
-        }
-        else
-        {
-            if (rayPayload.color[i].w == 1.f)
-            {
-                found = true;
-                break;
-            }
-        }
-    }
-    if (!found && rayPayload.hitCount < MAX_TRANSPACENT_HITS)
-    {
-        rayPayload.color[rayPayload.hitCount] = color;
-        rayPayload.distance[rayPayload.hitCount] = distance;
-        rayPayload.dayLight[rayPayload.hitCount] = attrib.dayLight;
-        rayPayload.dynamicLight[rayPayload.hitCount] = attrib.dynamicLight;
-        rayPayload.hitCount++;
-    }
+    SingleHit hit;
+    hit.color = color;
+    hit.normal = attrib.normal;
+    hit.distance = RayTCurrent();
+    hit.dayLight = attrib.dayLight;
+    hit.dynamicLight = attrib.dynamicLight;
+    applyHit(rayPayload, hit);
     if (color.w < 1.f)
     {
         IgnoreHit();

+ 10 - 5
FactoryCraft/ChunkClosestHit.hlsl

@@ -1,31 +1,36 @@
 #include "Common.hlsl"
 
 [shader("closesthit")]
-void ChunkClosestHit(inout HitInfo currentPayload, ChunkHitAttributes attrib)
+void ChunkClosestHit(inout RayHits currentPayload, ChunkHitAttributes attrib)
 {
     if (currentPayload.hitCount == 0)
     {
         return; // already inside of shadow ray
     }
-    HitInfo tmpPayload;
+    RayHits tmpPayload;
     // shadow rays
     for (int i = 0; i < currentPayload.hitCount; i++)
     {
         tmpPayload.hitCount = -1; // shadow ray
         RayDesc ray;
-        ray.Origin = WorldRayOrigin() + (currentPayload.distance[i] - 0.001) * WorldRayDirection();
+        ray.Origin = WorldRayOrigin() + (currentPayload.hits[i].distance - 0.001) * WorldRayDirection();
         ray.Direction = dayLightDirection;
         ray.TMin = 0.00001;
         ray.TMax = 1000;
         TraceRay(TLAS,
             0, 0xFF, 0,
            0, 0, ray, tmpPayload);
-        float3 color = unpackLight(currentPayload.dayLight[i]) * dayLightFactor;
+        float normalFactor = saturate(dot(normalize(currentPayload.hits[i].normal), normalize(dayLightDirection)));
+        float3 color = unpackLight(currentPayload.hits[i].dayLight) * dayLightFactor;
         if (tmpPayload.hitCount == 0)
         {
             color = color / 2;
         }
-        currentPayload.dayLight[i] = packLight(color);
+        else
+        {
+            color = color * (0.5 + normalFactor / 2);
+        }
+        currentPayload.hits[i].dayLight = packLight(color);
     }
     // TODO: reflection rays
 }

+ 6 - 0
FactoryCraft/ChunkIntersection.hlsl

@@ -147,6 +147,7 @@ void ChunkIntersection()
             switch (hitSide)
             {
                 case 0: // front | NORTH
+                    intersectionAttributes.normal = float3(0, -1, 0);
                     intersectionAttributes.texCoord = float2(1 - (currentPos.x - floor(currentPos.x)), 1 - (currentPos.z - floor(currentPos.z)));
                     topLeftDayLight = getLight(lightOffset + 0);
                     topLeftDynamicLight = getLight(lightOffset + 3);
@@ -158,6 +159,7 @@ void ChunkIntersection()
                     bottomRightDynamicLight = getLight(lightOffset + 45);
                     break;
                 case 1: // back | SOUTH
+                    intersectionAttributes.normal = float3(0, 1, 0);
                     intersectionAttributes.texCoord = float2(currentPos.x - floor(currentPos.x), 1 - (currentPos.z - floor(currentPos.z)));
                     topLeftDayLight = getLight(lightOffset + 12);
                     topLeftDynamicLight = getLight(lightOffset + 15);
@@ -169,6 +171,7 @@ void ChunkIntersection()
                     bottomRightDynamicLight = getLight(lightOffset + 33);
                     break;
                 case 2: // left | EAST
+                    intersectionAttributes.normal = float3(1, 0, 0);
                     intersectionAttributes.texCoord = float2(1 - (currentPos.y - floor(currentPos.y)), 1 - (currentPos.z - floor(currentPos.z)));
                     topLeftDayLight = getLight(lightOffset + 6);
                     topLeftDynamicLight = getLight(lightOffset + 9);
@@ -180,6 +183,7 @@ void ChunkIntersection()
                     bottomRightDynamicLight = getLight(lightOffset + 27);
                     break;
                 case 3: // right | WEST
+                    intersectionAttributes.normal = float3(-1, 0, 0);
                     intersectionAttributes.texCoord = float2(currentPos.y - floor(currentPos.y), 1 - (currentPos.z - floor(currentPos.z)));
                     topLeftDayLight = getLight(lightOffset + 18);
                     topLeftDynamicLight = getLight(lightOffset + 21);
@@ -191,6 +195,7 @@ void ChunkIntersection()
                     bottomRightDynamicLight = getLight(lightOffset + 39);
                     break;
                 case 4: // top
+                    intersectionAttributes.normal = float3(0, 0, 1);
                     intersectionAttributes.texCoord = float2(1 - (currentPos.x - floor(currentPos.x)), 1 - (currentPos.y - floor(currentPos.y)));
                     topLeftDayLight = getLight(lightOffset + 6);
                     topLeftDynamicLight = getLight(lightOffset + 9);
@@ -202,6 +207,7 @@ void ChunkIntersection()
                     bottomRightDynamicLight = getLight(lightOffset + 21);
                     break;
                 case 5: // bottom
+                    intersectionAttributes.normal = float3(0, 0, -1);
                     intersectionAttributes.texCoord = float2(1 - (currentPos.x - floor(currentPos.x)), currentPos.y - floor(currentPos.y));
                     topLeftDayLight = getLight(lightOffset + 24);
                     topLeftDynamicLight = getLight(lightOffset + 27);

+ 50 - 5
FactoryCraft/Common.hlsl

@@ -7,12 +7,18 @@
 #pragma pack_matrix(row_major)
 #define MAX_TRANSPACENT_HITS 5
 
-struct [raypayload] HitInfo
+struct SingleHit
 {
-    float4 color[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit, miss);
-float distance[MAX_TRANSPACENT_HITS] : write(caller, anyhit) : read(anyhit, closesthit);
-int dayLight[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit, miss);
-int dynamicLight[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit, miss);
+    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);
 };
 
@@ -21,6 +27,7 @@ int hitCount : write(caller, anyhit, closesthit, miss) : read(caller, anyhit, cl
 struct ChunkHitAttributes
 {
     float2 texCoord;
+    float3 normal;
     int textureId;
     int dayLight;
     int dynamicLight;
@@ -53,6 +60,44 @@ float3 unpackLight(int light)
     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<float4> textures[] : register(t0, space1);
 SamplerState gSampler : register(s0, space0);

+ 6 - 6
FactoryCraft/CustomDX12API.cpp

@@ -121,10 +121,10 @@ void CustomDX12API::initializePipeline()
 
         defaultHitGroup = new DX12ShaderHitGroup("HitGroup");
         defaultHitGroup->setAttributeSize(8);
-        defaultHitGroup->setPayloadSize(28 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
+        defaultHitGroup->setPayloadSize(40 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
         defaultHitGroup->setAnyHitShaderFunction(anyHitFunction);
         defaultHitGroup->setClosestHitShaderFunction(closestHitFunction);
-        pipeline->addHitGroup(defaultHitGroup); 
+        pipeline->addHitGroup(defaultHitGroup);
 
         // Chunk ray traversal shaders
         DX12ShaderSignature* chunkHitSignature = new DX12ShaderSignature();
@@ -173,8 +173,8 @@ void CustomDX12API::initializePipeline()
         chunkHitGroup->setIntersectionShaderFunction(chunkIntersectionFunction);
         chunkHitGroup->setAnyHitShaderFunction(chunkAnyHitFunction);
         chunkHitGroup->setClosestHitShaderFunction(chunkClosestHitFunction);
-        chunkHitGroup->setAttributeSize(20);
-        chunkHitGroup->setPayloadSize(28 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
+        chunkHitGroup->setAttributeSize(32);
+        chunkHitGroup->setPayloadSize(40 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
         pipeline->addHitGroup(chunkHitGroup);
 
         // simple blocks hit shaders
@@ -226,7 +226,7 @@ void CustomDX12API::initializePipeline()
             simpleBlocksClosestHitFunction);
         simpleBlocksHitGroup->setAttributeSize(8);
         simpleBlocksHitGroup->setPayloadSize(
-            28 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
+            40 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
         pipeline->addHitGroup(simpleBlocksHitGroup);
 
         pipeline->setMaxRecursionDepth(10);
@@ -273,7 +273,7 @@ void CustomDX12API::renderWorld(Framework::World3D* zWorld,
     DX12ShaderBindingTable* zSBT,
     int& objectIndex)
 {
-     Mat4<float> identity = Mat4<float>::identity();
+    Mat4<float> identity = Mat4<float>::identity();
     for (const Model3DCollection* collection : zWorld->getCollections())
     {
         const Dimension* dim = dynamic_cast<const Dimension*>(collection);

+ 5 - 4
FactoryCraft/CustomMiss.hlsl

@@ -1,7 +1,7 @@
 #include "Common.hlsl"
 
 [shader("miss")]
-void Miss(inout HitInfo rayPayload : SV_RayPayload)
+void Miss(inout RayHits rayPayload : SV_RayPayload)
 {
     if (rayPayload.hitCount < 0)
     { // shadow ray
@@ -9,9 +9,10 @@ void Miss(inout HitInfo rayPayload : SV_RayPayload)
     }
     if (rayPayload.hitCount < MAX_TRANSPACENT_HITS)
     {
-        rayPayload.color[rayPayload.hitCount] = float4(0.2f, 0.2f, 0.2f, -1.f);
-        rayPayload.dayLight[rayPayload.hitCount] = 0xFFFFFF;
-        rayPayload.dynamicLight[rayPayload.hitCount] = 0;
+        rayPayload.hits[rayPayload.hitCount].color = float4(0.2f, 0.2f, 0.2f, -1.f);
+        rayPayload.hits[rayPayload.hitCount].dayLight = 0xFFFFFF;
+        rayPayload.hits[rayPayload.hitCount].dynamicLight = 0;
+        rayPayload.hits[rayPayload.hitCount].normal = float3(0.f, 0.f, 0.f);
         rayPayload.hitCount++;
     }
 }

+ 23 - 19
FactoryCraft/CustomRayGen.hlsl

@@ -5,18 +5,17 @@
 void RayGen()
 {
     // Initialize the ray payload
-    HitInfo rayPayload;
+    RayHits rayPayload;
     rayPayload.hitCount = 0;
-    rayPayload.color[0] = float4(0, 0, 0, 0);
-    rayPayload.color[1] = float4(0, 0, 0, 0);
-    rayPayload.color[2] = float4(0, 0, 0, 0);
-    rayPayload.color[3] = float4(0, 0, 0, 0);
-    rayPayload.color[4] = float4(0, 0, 0, 0);
+    SingleHit hitInitial;
+    hitInitial.color = float4(0, 0, 0, 0);
+    hitInitial.normal = float3(0, 0, 0);
+    hitInitial.distance = 0.f;
+    hitInitial.dayLight = 0;
+    hitInitial.dynamicLight = 0;
     for (int index = 0; index < MAX_TRANSPACENT_HITS; index++)
     {
-        rayPayload.distance[index] = 0.f;
-        rayPayload.dayLight[index] = 0;
-        rayPayload.dynamicLight[index] = 0;
+        rayPayload.hits[index] = hitInitial;
     }
     float3 color = float3(0, 0, 0);
 
@@ -38,17 +37,22 @@ void RayGen()
         ray.TMax = maxDistance;
         TraceRay(TLAS, /*RayFlags*/0, /*InstanceInclusionMask*/0xFF, /*RayContributionToHitGroupIndex*/0,
             /*MultiplierForGeometryContributionToHitGroupIndex*/0, /*MissShaderIndex*/0, ray, rayPayload);
-        float3 minLight = float3(0.1f, 0.1f, 0.1f);
-        float3 dayLight = unpackLight(rayPayload.dayLight[rayPayload.hitCount - 1]);
-        float3 dynamicLight = unpackLight(rayPayload.dynamicLight[rayPayload.hitCount - 1]);
-        float3 light = max(minLight, max(dynamicLight, dayLight));
-        color = rayPayload.color[rayPayload.hitCount - 1].rgb * light;
-        for (int i = rayPayload.hitCount - 2; i >= 0; i--)
+        if (rayPayload.hitCount > 0)
         {
-            dayLight = unpackLight(rayPayload.dayLight[i]);
-            dynamicLight = unpackLight(rayPayload.dynamicLight[i]);
-            light = max(minLight, max(dynamicLight, dayLight));
-            color = rayPayload.color[i].rgb * light * rayPayload.color[i].a + color * (1 - rayPayload.color[i].a);
+            float3 minLight = float3(0.1f, 0.1f, 0.1f);
+            SingleHit lastHit = rayPayload.hits[rayPayload.hitCount - 1];
+            float3 dayLight = unpackLight(lastHit.dayLight);
+            float3 dynamicLight = unpackLight(lastHit.dynamicLight);
+            float3 light = max(minLight, max(dynamicLight, dayLight));
+            color = lastHit.color.rgb * light;
+            for (int i = rayPayload.hitCount - 2; i >= 0; i--)
+            {
+                SingleHit currentHit = rayPayload.hits[i];
+                dayLight = unpackLight(currentHit.dayLight);
+                dynamicLight = unpackLight(currentHit.dynamicLight);
+                light = max(minLight, max(dynamicLight, dayLight));
+                color = currentHit.color.rgb * light * currentHit.color.a + color * (1 - currentHit.color.a);
+            }
         }
     }
     

+ 9 - 57
FactoryCraft/DefaultAnyHit.hlsl

@@ -6,7 +6,7 @@ StructuredBuffer<VertexData> vertexData : register(t1, space4);
 StructuredBuffer<int> polygonSizeBuffer : register(t1, space5);
 
 [shader("anyhit")]
-void AnyHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
+void AnyHit(inout RayHits rayPayload, SimpleBlocksAttributes attrib)
 {
     if (rayPayload.hitCount < 0)
     { // shadow ray
@@ -43,6 +43,7 @@ void AnyHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
     VertexData v0 = vertexData[indexBuffer[index]];
     VertexData v1 = vertexData[indexBuffer[index + 1]];
     VertexData v2 = vertexData[indexBuffer[index + 2]];
+    float3 normal = v0.normal * (1 - attrib.bary.x - attrib.bary.y) + v1.normal * attrib.bary.x + v2.normal * attrib.bary.y;
     float2 texcoord = v0.texcoord * (1 - attrib.bary.x - attrib.bary.y) + v1.texcoord * attrib.bary.x + v2.texcoord * attrib.bary.y;
     float4 color = texture.SampleLevel(gSampler, texcoord, 0);
     if (color.w == 0.f)
@@ -50,62 +51,13 @@ void AnyHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
         IgnoreHit();
         return;
     }
-    float distance = RayTCurrent();
-    bool found = false;
-    for (i = 0; i < rayPayload.hitCount; i++)
-    {
-        if (rayPayload.distance[i] > distance)
-        {
-            found = true;
-            float4 tmpColor = rayPayload.color[i];
-            rayPayload.color[i] = color;
-            float tmpDistance = rayPayload.distance[i];
-            rayPayload.distance[i] = distance;
-            int tmpDayLight = rayPayload.dayLight[i];
-            rayPayload.dayLight[i] = 0xFFFFFF;
-            int tmpDynamicLight = rayPayload.dynamicLight[i];
-            rayPayload.dynamicLight[i] = 0xFFFFFF;
-            if (color.w == 1.f)
-            {
-                rayPayload.hitCount = i + 1;
-            }
-            else
-            {
-                for (int j = i + 1; j < rayPayload.hitCount + 1 && j < MAX_TRANSPACENT_HITS; j++)
-                {
-                    float4 tmpColor2 = rayPayload.color[j];
-                    float tmpDistance2 = rayPayload.distance[j];
-                    int tmpDayLight2 = rayPayload.dayLight[j];
-                    int tmpDynamicLight2 = rayPayload.dynamicLight[j];
-                    rayPayload.color[j] = tmpColor;
-                    rayPayload.distance[j] = tmpDistance;
-                    rayPayload.dayLight[j] = tmpDayLight;
-                    rayPayload.dynamicLight[j] = tmpDynamicLight;
-                    tmpColor = tmpColor2;
-                    tmpDistance = tmpDistance2;
-                    tmpDayLight = tmpDayLight2;
-                    tmpDynamicLight = tmpDynamicLight2;
-                }
-            }
-            break;
-        }
-        else
-        {
-            if (rayPayload.color[i].w == 1.f)
-            {
-                found = true;
-                break;
-            }
-        }
-    }
-    if (!found && rayPayload.hitCount < MAX_TRANSPACENT_HITS)
-    {
-        rayPayload.color[rayPayload.hitCount] = color;
-        rayPayload.distance[rayPayload.hitCount] = distance;
-        rayPayload.dayLight[rayPayload.hitCount] = 0xFFFFFF;
-        rayPayload.dynamicLight[rayPayload.hitCount] = 0xFFFFFF;
-        rayPayload.hitCount++;
-    }
+    SingleHit hit;
+    hit.color = color;
+    hit.normal = normal;
+    hit.distance = RayTCurrent();
+    hit.dayLight = 0xFFFFFF;
+    hit.dynamicLight = 0xFFFFFF;
+    applyHit(rayPayload, hit);
     if (color.w < 1.f)
     {
         IgnoreHit();

+ 1 - 1
FactoryCraft/DefaultClosestHit.hlsl

@@ -6,7 +6,7 @@ StructuredBuffer<VertexData> vertexData : register(t1, space4);
 StructuredBuffer<int> polygonSizeBuffer : register(t1, space5);
 
 [shader("closesthit")]
-void ClosestHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
+void ClosestHit(inout RayHits rayPayload, SimpleBlocksAttributes attrib)
 {
     // TODO: reflection rays and shadow rays ...
 }

+ 9 - 57
FactoryCraft/SimpleBlocksAnyHit.hlsl

@@ -7,7 +7,7 @@ StructuredBuffer<int> indexOffsetBuffer : register(t1, space5);
 
 
 [shader("anyhit")]
-void SimpleBlocksAnyHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
+void SimpleBlocksAnyHit(inout RayHits rayPayload, SimpleBlocksAttributes attrib)
 {
     if (rayPayload.hitCount < 0)
     { // shadow ray
@@ -43,6 +43,7 @@ void SimpleBlocksAnyHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
     VertexData v0 = vertexData[indexBuffer[index]];
     VertexData v1 = vertexData[indexBuffer[index + 1]];
     VertexData v2 = vertexData[indexBuffer[index + 2]];
+    float3 normal = v0.normal * (1 - attrib.bary.x - attrib.bary.y) + v1.normal * attrib.bary.x + v2.normal * attrib.bary.y;
     float2 texcoord = v0.texcoord * (1 - attrib.bary.x - attrib.bary.y) + v1.texcoord * attrib.bary.x + v2.texcoord * attrib.bary.y;
     float4 color = texture.SampleLevel(gSampler, texcoord, 0);
     if (color.w == 0.f)
@@ -50,62 +51,13 @@ void SimpleBlocksAnyHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
         IgnoreHit();
         return;
     }
-    float distance = RayTCurrent();
-    bool found = false;
-    for (int i = 0; i < rayPayload.hitCount; i++)
-    {
-        if (rayPayload.distance[i] > distance)
-        {
-            found = true;
-            float4 tmpColor = rayPayload.color[i];
-            rayPayload.color[i] = color;
-            float tmpDistance = rayPayload.distance[i];
-            rayPayload.distance[i] = distance;
-            int tmpDayLight = rayPayload.dayLight[i];
-            rayPayload.dayLight[i] = 0xFFFFFF;
-            int tmpDynamicLight = rayPayload.dynamicLight[i];
-            rayPayload.dynamicLight[i] = 0xFFFFFF;
-            if (color.w == 1.f)
-            {
-                rayPayload.hitCount = i + 1;
-            }
-            else
-            {
-                for (int j = i + 1; j < rayPayload.hitCount + 1 && j < MAX_TRANSPACENT_HITS; j++)
-                {
-                    float4 tmpColor2 = rayPayload.color[j];
-                    float tmpDistance2 = rayPayload.distance[j];
-                    int tmpDayLight2 = rayPayload.dayLight[j];
-                    int tmpDynamicLight2 = rayPayload.dynamicLight[j];
-                    rayPayload.color[j] = tmpColor;
-                    rayPayload.distance[j] = tmpDistance;
-                    rayPayload.dayLight[j] = tmpDayLight;
-                    rayPayload.dynamicLight[j] = tmpDynamicLight;
-                    tmpColor = tmpColor2;
-                    tmpDistance = tmpDistance2;
-                    tmpDayLight = tmpDayLight2;
-                    tmpDynamicLight = tmpDynamicLight2;
-                }
-            }
-            break;
-        }
-        else
-        {
-            if (rayPayload.color[i].w == 1.f)
-            {
-                found = true;
-                break;
-            }
-        }
-    }
-    if (!found && rayPayload.hitCount < MAX_TRANSPACENT_HITS)
-    {
-        rayPayload.color[rayPayload.hitCount] = color;
-        rayPayload.distance[rayPayload.hitCount] = distance;
-        rayPayload.dayLight[rayPayload.hitCount] = 0xFFFFFF;
-        rayPayload.dynamicLight[rayPayload.hitCount] = 0xFFFFFF;
-        rayPayload.hitCount++;
-    }
+    SingleHit hit;
+    hit.color = color;
+    hit.normal = normal;
+    hit.distance = RayTCurrent();
+    hit.dayLight = 0xFFFFFF;
+    hit.dynamicLight = 0xFFFFFF;
+    applyHit(rayPayload, hit);
     if (color.w < 1.f)
     {
         IgnoreHit();

+ 1 - 1
FactoryCraft/SimpleBlocksClosestHit.hlsl

@@ -6,7 +6,7 @@ StructuredBuffer<VertexData> vertexData : register(t1, space4);
 StructuredBuffer<int> indexOffsetBuffer : register(t1, space5);
 
 [shader("closesthit")]
-void SimpleBlocksClosestHit(inout HitInfo rayPayload, SimpleBlocksAttributes attrib)
+void SimpleBlocksClosestHit(inout RayHits rayPayload, SimpleBlocksAttributes attrib)
 {
     // TODO: reflection rays and shadow rays ...
 }