Explorar o código

fix problems with lightning

Kolja Strohm hai 1 semana
pai
achega
df91bea944

+ 1 - 1
FactoryCraft/ChunkAnyHit.hlsl

@@ -4,7 +4,7 @@ Texture2D<float4> textures[] : register(t0, space1);
 SamplerState gSampler : register(s0, space0);
 
 [shader("anyhit")]
-void ChunkAnyHit(inout HitInfo payload, Attributes attrib)
+void ChunkAnyHit(inout HitInfo payload, ChunkHitAttributes attrib)
 {
     Texture2D<float4> texture = textures[attrib.textureId];
     float4 color = texture.SampleLevel(gSampler, attrib.texCoord, 0);

+ 1 - 1
FactoryCraft/ChunkClosestHit.hlsl

@@ -4,7 +4,7 @@ Texture2D<float4> textures[] : register(t0, space1);
 SamplerState gSampler : register(s0, space0);
 
 [shader("closesthit")]
-void ChunkClosestHit(inout HitInfo payload, Attributes attrib)
+void ChunkClosestHit(inout HitInfo payload, ChunkHitAttributes attrib)
 {
     // TODO: reflection rays and shadow rays ...
 }

+ 4 - 4
FactoryCraft/ChunkIntersection.hlsl

@@ -21,20 +21,20 @@ ByteAddressBuffer lightBuffer : register(t1, space4);
 
 float3 getLight(int index)
 {
-    uint raw = lightBuffer.Load(index / 4);
+    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);
+        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);
+        raw = lightBuffer.Load((index / 4) * 4 + 4);
         shift = 0;
     }
     float b = ((raw >> shift) & 0xFF) / 255.0;
@@ -50,7 +50,7 @@ float3 interpolateLight(float3 topLeft, float3 topRight, float3 bottomLeft, floa
 void ChunkIntersection()
 {
     float THit = RayTCurrent();
-    Attributes intersectionAttributes;
+    ChunkHitAttributes intersectionAttributes;
     intersectionAttributes.texCoord = float2(0.5, 0.5);
     intersectionAttributes.textureId = 2;
     float3 origin = WorldRayOrigin();

+ 3 - 3
FactoryCraft/Common.hlsl

@@ -11,14 +11,14 @@ struct [raypayload] HitInfo
 {
     float4 color[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit, miss);
 float distance[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit) : read(caller, anyhit, closesthit);
-int dayLight[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit) : read(caller, anyhit, closesthit);
-int dynamicLight[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit) : read(caller, anyhit, closesthit);
+int dayLight[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit);
+int dynamicLight[MAX_TRANSPACENT_HITS] : write(caller, closesthit, anyhit, miss) : read(caller, anyhit, closesthit);
 uint 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 Attributes
+struct ChunkHitAttributes
 {
     float2 texCoord;
     int textureId;

+ 5 - 5
FactoryCraft/CustomDX12API.cpp

@@ -21,7 +21,7 @@ using namespace Framework;
 
 CustomDX12API::CustomDX12API()
     : DirectX12()
-{}
+{} 
 
 CustomDX12API::~CustomDX12API() {}
 
@@ -115,12 +115,12 @@ void CustomDX12API::initializePipeline()
         sbtChunkIndexBufferOffset
             = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
                 DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
-        sbtChunkDataBufferOffset
-            = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
-                DX12_SHADER_REGISTER_B_CONST_BUFFER, 0, 2);
         sbtChunkLightBufferOffset
             = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
                 DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 4);
+        sbtChunkDataBufferOffset
+            = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
+                DX12_SHADER_REGISTER_B_CONST_BUFFER, 0, 2);
 
         DX12Shader* chunkIntersectionShader
             = new DX12Shader(CustomChunkIntersectionShader,
@@ -159,7 +159,7 @@ void CustomDX12API::initializePipeline()
         pipeline->addHitGroup(chunkHitGroup);
 
         // simple blocks hit shaders
-        DX12ShaderSignature* simpleBlocksHitSignature
+         DX12ShaderSignature* simpleBlocksHitSignature
             = new DX12ShaderSignature();
         simpleBlocksHitSignature->addRegisterUsageLinkedToDescriptorHeap(
             0, DX12_SHADER_REGISTER_S_SAMPLER, 0, 0, SAMPLER_DESCRIPTOR_HEAP);

+ 2 - 0
FactoryCraft/CustomMiss.hlsl

@@ -6,6 +6,8 @@ void Miss(inout HitInfo payload : SV_RayPayload)
     if (payload.hitCount < MAX_TRANSPACENT_HITS)
     {
         payload.color[payload.hitCount] = float4(0.2f, 0.2f, 0.2f, -1.f);
+        payload.dayLight[payload.hitCount] = 0xFFFFFF;
+        payload.dynamicLight[payload.hitCount] = 0;
         payload.hitCount++;
     }
 }

+ 69 - 44
FactoryCraft/DX12ChunkData.cpp

@@ -301,34 +301,40 @@ void DX12ChunkData::updateLightning(Chunk* zChunk)
             dxLightBuffer->setLength(neededSize);
         }
     }
-    Directions vertexDirections[] = {TOP | NORTH | EAST,
-        TOP | SOUTH | EAST,
-        TOP | SOUTH | WEST,
-        TOP | NORTH | WEST,
-        BOTTOM | NORTH | EAST,
-        BOTTOM | SOUTH | EAST,
-        BOTTOM | SOUTH | WEST,
-        BOTTOM | NORTH | WEST};
+    Directions vertexDirections[8][3] = {
+        {TOP,    NORTH, EAST},
+        {TOP,    SOUTH, EAST},
+        {TOP,    SOUTH, WEST},
+        {TOP,    NORTH, WEST},
+        {BOTTOM, NORTH, EAST},
+        {BOTTOM, SOUTH, EAST},
+        {BOTTOM, SOUTH, WEST},
+        {BOTTOM, NORTH, WEST}
+    };
+    const unsigned char noLightData[6] = {0, 0, 0, 0, 0, 0};
     for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; ++i)
     {
         if (blockIndices[i] >= 0)
         {
             Vec3<int> blockLocation = Chunk::chunkCoordinates(i);
             Block* zBlock = zChunk->zBlockAt(blockLocation);
-            int offset = blockIndices[i] * 8;
-            for (int j = 0; j < 8; ++j)
+            union
             {
-                Directions dir = vertexDirections[j];
-                int lightData[6];
-                memset(lightData, 0, sizeof(int) * 6);
-                int count = 0;
-                for (int d = 0; d < 6; d++)
+                const unsigned char* neighborLightMap[3][3][3];
+                const unsigned char* neighborLightMapEntries[3 * 3 * 3];
+            };
+            for (int j = 0; j < 3 * 3 * 3; j++)
+            {
+                neighborLightMapEntries[j] = noLightData;
+            }
+            for (int x = -1; x <= 1; ++x)
+            {
+                for (int y = -1; y <= 1; ++y)
                 {
-                    Direction direction = getDirectionFromIndex(d);
-                    if ((dir | direction) == dir)
+                    for (int z = -1; z <= 1; ++z)
                     {
                         Vec3<int> neighborLocation
-                            = blockLocation + getDirection(direction);
+                            = blockLocation + Vec3<int>(x, y, z);
                         if (neighborLocation.z >= 0
                             && neighborLocation.z < WORLD_HEIGHT)
                         {
@@ -337,40 +343,59 @@ void DX12ChunkData::updateLightning(Chunk* zChunk)
                                 && neighborLocation.y >= 0
                                 && neighborLocation.y < CHUNK_SIZE)
                             {
-                                int index = Chunk::index(neighborLocation);
-                                if (blockIndices[index] < 0)
-                                {
-                                    for (int k = 0; k < 6; ++k)
-                                    {
-                                        lightData[k]
-                                            += (int)zBlock->getLightData(
-                                                direction)[k];
-                                    }
-                                    ++count;
-                                }
-                            }
-                            else
-                            {
-                                if (!World::INSTANCE->zBlockAt(
-                                        neighborLocation
-                                        + Vec3<int>(zChunk->getCenter().x
-                                                        - CHUNK_SIZE / 2,
-                                            zChunk->getCenter().y
-                                                - CHUNK_SIZE / 2,
-                                            0)))
+                                Block* zNeighborBlock
+                                    = zChunk->zBlockAt(neighborLocation);
+                                if (zNeighborBlock)
                                 {
-                                    for (int k = 0; k < 6; ++k)
+                                    for (int d = 0; d < 6; d++)
                                     {
-                                        lightData[k]
-                                            += (int)zBlock->getLightData(
-                                                direction)[k];
+                                        Vec3<int> lmi
+                                            = getDirection(
+                                                  getDirectionFromIndex(d))
+                                            + Vec3<int>(x, y, z);
+                                        if (lmi.x >= -1 && lmi.x <= 1
+                                            && lmi.y >= -1 && lmi.y <= 1
+                                            && lmi.z >= -1 && lmi.z <= 1)
+                                        {
+                                            neighborLightMap[lmi.x + 1]
+                                                            [lmi.y + 1]
+                                                            [lmi.z + 1]
+                                                = zNeighborBlock->getLightData(
+                                                    getDirectionFromIndex(d));
+                                        }
                                     }
-                                    ++count;
                                 }
                             }
                         }
                     }
                 }
+            }
+            int offset = blockIndices[i] * 8;
+            for (int j = 0; j < 8; ++j)
+            {
+                int lightData[6];
+                memset(lightData, 0, sizeof(int) * 6);
+                int count = 0;
+                for (int d = 1; d < 8; d++)
+                {
+                    Directions direction = vertexDirections[j][0] * ((d & 0x1) != 0)
+                                         + vertexDirections[j][1] * ((d & 0x2) != 0)
+                                         + vertexDirections[j][2] * ((d & 0x4) != 0);
+                    Vec3<int> index = getDirection(direction);
+                    bool notZero = 0;
+                    const unsigned char* currentLight
+                        = neighborLightMap[index.x + 1][index.y + 1]
+                                          [index.z + 1];
+                    for (int k = 0; k < 6; ++k)
+                    {
+                        lightData[k] += (int)currentLight[k];
+                        notZero |= currentLight[k] > 0;
+                    }
+                    if (notZero)
+                    {
+                        ++count;
+                    }
+                }
                 for (int k = 0; k < 6; ++k)
                 {
                     lightBuffer[offset + j * 6 + k]