|
|
@@ -12,22 +12,38 @@ cbuffer ChunkShaderInfo : register(b0, space2)
|
|
|
|
|
|
StructuredBuffer<int> textureIdBuffer : register(t1, space2);
|
|
|
StructuredBuffer<int> indexBuffer : register(t1, space3);
|
|
|
+ByteAddressBuffer lightBuffer : register(t1, space4);
|
|
|
|
|
|
#define minPos(x, y) min(x>0?x:y,y>0?y:x)
|
|
|
#define minPosV(v1, v2) float3(minPos(v1.x, v2.x), minPos(v1.y, v2.y), minPos(v1.z, v2.z))
|
|
|
|
|
|
#define between(v1, vmin, vmax) (v1.x >= vmin.x && v1.x <= vmax.x && v1.y >= vmin.y && v1.y <= vmax.y && v1.z >= vmin.z && v1.z <= vmax.z)
|
|
|
|
|
|
-float GetEntry(float3 minp, float3 maxp, float3 invDir, float3 origin)
|
|
|
+float3 getLight(int index)
|
|
|
{
|
|
|
- if (between(origin, minp, maxp))
|
|
|
+ uint raw = lightBuffer.Load(index / 4);
|
|
|
+ uint shift = (index % 4) * 8;
|
|
|
+ float r = ((raw >> shift) & 0xFF) / 255.0;
|
|
|
+ shift += 8;
|
|
|
+ if (shift == 32)
|
|
|
{
|
|
|
- return 0;
|
|
|
+ raw = lightBuffer.Load(index / 4 + 4);
|
|
|
+ shift = 0;
|
|
|
}
|
|
|
- float3 t1 = (minp - origin) * invDir;
|
|
|
- float3 t2 = (maxp - origin) * invDir;
|
|
|
- float3 tmin = min(t1, t2);
|
|
|
- return max(max(tmin.x, tmin.y), tmin.z);
|
|
|
+ float g = ((raw >> shift) & 0xFF) / 255.0;
|
|
|
+ shift += 8;
|
|
|
+ if (shift == 32)
|
|
|
+ {
|
|
|
+ raw = lightBuffer.Load(index / 4 + 4);
|
|
|
+ shift = 0;
|
|
|
+ }
|
|
|
+ float b = ((raw >> shift) & 0xFF) / 255.0;
|
|
|
+ return float3(r, g, b);
|
|
|
+}
|
|
|
+
|
|
|
+float3 interpolateLight(float3 topLeft, float3 topRight, float3 bottomLeft, float3 bottomRight, float2 coords)
|
|
|
+{
|
|
|
+ return (topLeft * (1 - coords.x) + topRight * coords.x) * (1 - coords.y) + (bottomLeft * (1 - coords.x) + bottomRight * coords.x) * coords.y;
|
|
|
}
|
|
|
|
|
|
[shader("intersection")]
|
|
|
@@ -78,19 +94,19 @@ void ChunkIntersection()
|
|
|
int3 blockMax = int3(CHUNK_SIZE - 1, CHUNK_SIZE - 1, WORLD_HEIGHT - 1);
|
|
|
switch (hitSide)
|
|
|
{
|
|
|
- case 0: // front
|
|
|
+ case 0: // front | NORTH
|
|
|
block.y = blockMin.y;
|
|
|
nextBorder.y = blockMin.y + 1 + chunkMin.y;
|
|
|
break;
|
|
|
- case 1: // back
|
|
|
+ case 1: // back | SOUTH
|
|
|
block.y = blockMax.y;
|
|
|
nextBorder.y = blockMax.y + chunkMin.y;
|
|
|
break;
|
|
|
- case 2: // left
|
|
|
+ case 2: // left | EAST
|
|
|
block.x = blockMax.x;
|
|
|
nextBorder.x = blockMax.x + chunkMin.x;
|
|
|
break;
|
|
|
- case 3: // right
|
|
|
+ case 3: // right | WEST
|
|
|
block.x = blockMin.x;
|
|
|
nextBorder.x = blockMin.x + 1 + chunkMin.x;
|
|
|
break;
|
|
|
@@ -108,27 +124,97 @@ void ChunkIntersection()
|
|
|
int index = (block.x * CHUNK_SIZE + block.y) * WORLD_HEIGHT + block.z;
|
|
|
if (indexBuffer[index] >= 0 && distance > minDistance && hitSide >= 0)
|
|
|
{
|
|
|
+ int lightOffset = indexBuffer[index] * 8;
|
|
|
+ float3 topLeftDayLight;
|
|
|
+ float3 topRightDayLight;
|
|
|
+ float3 bottomLeftDayLight;
|
|
|
+ float3 bottomRightDayLight;
|
|
|
+ float3 topLeftDynamicLight;
|
|
|
+ float3 topRightDynamicLight;
|
|
|
+ float3 bottomLeftDynamicLight;
|
|
|
+ float3 bottomRightDynamicLight;
|
|
|
+ /**
|
|
|
+ Light indices are stored in the following order:
|
|
|
+ lightOffset = TOP | NORTH | EAST
|
|
|
+ lightOffset + 6 = TOP | SOUTH | EAST
|
|
|
+ lightOffset + 12 = TOP | SOUTH | WEST
|
|
|
+ lightOffset + 18 = TOP | NORTH | WEST
|
|
|
+ lightOffset + 24 = BOTTOM | NORTH | EAST
|
|
|
+ lightOffset + 30 = BOTTOM | SOUTH | EAST
|
|
|
+ lightOffset + 36 = BOTTOM | SOUTH | WEST
|
|
|
+ lightOffset + 42 = BOTTOM | NORTH | WEST
|
|
|
+ **/
|
|
|
switch (hitSide)
|
|
|
{
|
|
|
- case 0: // front
|
|
|
+ case 0: // front | NORTH
|
|
|
intersectionAttributes.texCoord = float2(1 - (currentPos.x - floor(currentPos.x)), 1 - (currentPos.z - floor(currentPos.z)));
|
|
|
+ topLeftDayLight = getLight(lightOffset + 0);
|
|
|
+ topLeftDynamicLight = getLight(lightOffset + 3);
|
|
|
+ topRightDayLight = getLight(lightOffset + 18);
|
|
|
+ topRightDynamicLight = getLight(lightOffset + 21);
|
|
|
+ bottomLeftDayLight = getLight(lightOffset + 24);
|
|
|
+ bottomLeftDynamicLight = getLight(lightOffset + 27);
|
|
|
+ bottomRightDayLight = getLight(lightOffset + 42);
|
|
|
+ bottomRightDynamicLight = getLight(lightOffset + 45);
|
|
|
break;
|
|
|
- case 1: // back
|
|
|
+ case 1: // back | SOUTH
|
|
|
intersectionAttributes.texCoord = float2(currentPos.x - floor(currentPos.x), 1 - (currentPos.z - floor(currentPos.z)));
|
|
|
+ topLeftDayLight = getLight(lightOffset + 12);
|
|
|
+ topLeftDynamicLight = getLight(lightOffset + 15);
|
|
|
+ topRightDayLight = getLight(lightOffset + 6);
|
|
|
+ topRightDynamicLight = getLight(lightOffset + 9);
|
|
|
+ bottomLeftDayLight = getLight(lightOffset + 36);
|
|
|
+ bottomLeftDynamicLight = getLight(lightOffset + 39);
|
|
|
+ bottomRightDayLight = getLight(lightOffset + 30);
|
|
|
+ bottomRightDynamicLight = getLight(lightOffset + 33);
|
|
|
break;
|
|
|
- case 2: // left
|
|
|
+ case 2: // left | EAST
|
|
|
intersectionAttributes.texCoord = float2(1 - (currentPos.y - floor(currentPos.y)), 1 - (currentPos.z - floor(currentPos.z)));
|
|
|
+ topLeftDayLight = getLight(lightOffset + 6);
|
|
|
+ topLeftDynamicLight = getLight(lightOffset + 9);
|
|
|
+ topRightDayLight = getLight(lightOffset + 0);
|
|
|
+ topRightDynamicLight = getLight(lightOffset + 3);
|
|
|
+ bottomLeftDayLight = getLight(lightOffset + 30);
|
|
|
+ bottomLeftDynamicLight = getLight(lightOffset + 33);
|
|
|
+ bottomRightDayLight = getLight(lightOffset + 24);
|
|
|
+ bottomRightDynamicLight = getLight(lightOffset + 27);
|
|
|
break;
|
|
|
- case 3: // right
|
|
|
+ case 3: // right | WEST
|
|
|
intersectionAttributes.texCoord = float2(currentPos.y - floor(currentPos.y), 1 - (currentPos.z - floor(currentPos.z)));
|
|
|
+ topLeftDayLight = getLight(lightOffset + 18);
|
|
|
+ topLeftDynamicLight = getLight(lightOffset + 21);
|
|
|
+ topRightDayLight = getLight(lightOffset + 12);
|
|
|
+ topRightDynamicLight = getLight(lightOffset + 15);
|
|
|
+ bottomLeftDayLight = getLight(lightOffset + 42);
|
|
|
+ bottomLeftDynamicLight = getLight(lightOffset + 45);
|
|
|
+ bottomRightDayLight = getLight(lightOffset + 36);
|
|
|
+ bottomRightDynamicLight = getLight(lightOffset + 39);
|
|
|
break;
|
|
|
case 4: // top
|
|
|
intersectionAttributes.texCoord = float2(1 - (currentPos.x - floor(currentPos.x)), 1 - (currentPos.y - floor(currentPos.y)));
|
|
|
+ topLeftDayLight = getLight(lightOffset + 6);
|
|
|
+ topLeftDynamicLight = getLight(lightOffset + 9);
|
|
|
+ topRightDayLight = getLight(lightOffset + 12);
|
|
|
+ topRightDynamicLight = getLight(lightOffset + 15);
|
|
|
+ bottomLeftDayLight = getLight(lightOffset + 0);
|
|
|
+ bottomLeftDynamicLight = getLight(lightOffset + 3);
|
|
|
+ bottomRightDayLight = getLight(lightOffset + 18);
|
|
|
+ bottomRightDynamicLight = getLight(lightOffset + 21);
|
|
|
break;
|
|
|
case 5: // bottom
|
|
|
intersectionAttributes.texCoord = float2(1 - (currentPos.x - floor(currentPos.x)), currentPos.y - floor(currentPos.y));
|
|
|
+ topLeftDayLight = getLight(lightOffset + 24);
|
|
|
+ topLeftDynamicLight = getLight(lightOffset + 27);
|
|
|
+ topRightDayLight = getLight(lightOffset + 42);
|
|
|
+ topRightDynamicLight = getLight(lightOffset + 45);
|
|
|
+ bottomLeftDayLight = getLight(lightOffset + 30);
|
|
|
+ bottomLeftDynamicLight = getLight(lightOffset + 33);
|
|
|
+ bottomRightDayLight = getLight(lightOffset + 36);
|
|
|
+ bottomRightDynamicLight = getLight(lightOffset + 39);
|
|
|
break;
|
|
|
}
|
|
|
+ intersectionAttributes.dayLight = packLight(interpolateLight(topLeftDayLight, topRightDayLight, bottomLeftDayLight, bottomRightDayLight, intersectionAttributes.texCoord));
|
|
|
+ intersectionAttributes.dynamicLight = packLight(interpolateLight(topLeftDynamicLight, topRightDynamicLight, bottomLeftDynamicLight, bottomRightDynamicLight, intersectionAttributes.texCoord));
|
|
|
intersectionAttributes.textureId = textureIdBuffer[indexBuffer[index] + hitSide];
|
|
|
ReportHit(distance, hitSide, intersectionAttributes);
|
|
|
if (RayTCurrent() < THit)
|