Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix VR compilation #41

Merged
merged 12 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build Release.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

RMDIR dist /S /Q

cmake -S . --preset=FLATRIM --check-stamp-file "build\CMakeFiles\generate.stamp"
cmake -S . --preset=ALL --check-stamp-file "build\CMakeFiles\generate.stamp"
if %ERRORLEVEL% NEQ 0 exit 1
cmake --build build --config Release
if %ERRORLEVEL% NEQ 0 exit 1
Expand Down
39 changes: 19 additions & 20 deletions features/Grass Lighting/Shaders/RunGrass.hlsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "Common/Color.hlsl"
#include "Common/FrameBuffer.hlsl"
#include "Common/MotionBlur.hlsl"
#include "Common/Color.hlsl"

struct VS_INPUT
{
Expand Down Expand Up @@ -130,7 +130,7 @@ cbuffer cb13 : register(b13)
{
float4 cb13[3];
}
# endif // VR
# endif // VR

# define M_PI 3.1415925 // PI
# define M_2PI 6.283185 // PI * 2
Expand Down Expand Up @@ -442,9 +442,9 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
// Swaps direction of the backfaces otherwise they seem to get lit from the wrong direction.
if (!frontFace)
worldNormal.xyz = -worldNormal.xyz;

worldNormal.xyz = normalize(lerp(worldNormal.xyz, normalize(input.FlatNormal.xyz), saturate(input.FlatNormal.w)));

if (complex) {
float3 normalColor = float4(TransformNormal(specColor.xyz), 1);
// Inverting x as well as y seems to look more correct.
Expand Down Expand Up @@ -481,7 +481,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
float3 dirDiffuseColor = dirLightColor * saturate(dirLightAngle);

lightsDiffuseColor += dirDiffuseColor;

// Generated texture to simulate light transport.
// Numerous attempts were made to use a more interesting algorithm however they were mostly fruitless.
float3 subsurfaceColor = normalize(baseColor.xyz);
Expand All @@ -501,44 +501,43 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
float3 viewPosition = mul(CameraView[eyeIndex], float4(input.WorldPosition.xyz, 1)).xyz;

float clampedDepth = clamp(viewPosition.z, GetNearPlane(), GetFarPlane());
uint clusterZ = uint(max((log2(clampedDepth) - log2(GetNearPlane())) * 24.0 / log2(GetFarPlane() / GetNearPlane()), 0.0));

uint clusterZ = uint(max((log2(clampedDepth) - log2(GetNearPlane())) * 24.0 / log2(GetFarPlane() / GetNearPlane()), 0.0));
uint2 clusterDim = ceil(perPassLLF[0].BufferDim / float2(16, 8));
uint3 cluster = uint3(uint2(input.HPosition.xy / clusterDim), clusterZ);
uint clusterIndex = cluster.x + (16 * cluster.y) + (16 * 8 * cluster.z);
uint clusterIndex = cluster.x + (16 * cluster.y) + (16 * 8 * cluster.z);

uint lightCount = lightGrid[clusterIndex].lightCount;

if (lightCount > 0){
if (lightCount > 0) {
uint lightOffset = lightGrid[clusterIndex].offset;

float2 screenUV = ViewToUV(viewPosition);
float2 screenUV = ViewToUV(viewPosition, true, eyeIndex);
float screenNoise = InterleavedGradientNoise(screenUV * perPassLLF[0].BufferDim);

[loop]
for (uint i = 0; i < lightCount; i++)
{

[loop] for (uint i = 0; i < lightCount; i++)
{
uint light_index = lightList[lightOffset + i];
StructuredLight light = lights[light_index];

float3 lightDirection = light.positionWS.xyz - input.WorldPosition.xyz;
float3 lightDirection = light.positionWS[eyeIndex].xyz - input.WorldPosition.xyz;
float lightDist = length(lightDirection);
float intensityFactor = saturate(lightDist / light.radius);
if (intensityFactor == 1)
continue;

float intensityMultiplier = 1 - intensityFactor * intensityFactor;
float intensityMultiplier = 1 - intensityFactor * intensityFactor;
float3 lightColor = light.color.xyz;
float3 nsLightColor = lightColor;
float3 normalizedLightDirection = normalize(lightDirection);

float lightAngle = dot(worldNormal.xyz, normalizedLightDirection.xyz);

float3 normalizedLightDirectionVS = WorldToView(normalizedLightDirection);
float3 normalizedLightDirectionVS = WorldToView(normalizedLightDirection, true, eyeIndex);
if (light.shadowMode == 2)
lightColor *= ContactShadows(viewPosition, screenUV, screenNoise, normalizedLightDirectionVS);
lightColor *= ContactShadows(viewPosition, screenUV, screenNoise, normalizedLightDirectionVS, eyeIndex);
else if (light.shadowMode == 1)
lightColor *= ContactShadowsLong(viewPosition, screenUV, screenNoise, normalizedLightDirectionVS, light.radius);
lightColor *= ContactShadowsLong(viewPosition, screenUV, screenNoise, normalizedLightDirectionVS, light.radius, eyeIndex);

float3 lightDiffuseColor = lightColor * saturate(lightAngle.xxx);

Expand Down
141 changes: 69 additions & 72 deletions features/Light Limit Fix/Shaders/LightLimitFix/ClusterCullingCS.hlsl
Original file line number Diff line number Diff line change
@@ -1,88 +1,85 @@
#include "Common.hlsli"

//references
//references
//https://github.com/pezcode/Cluster

StructuredBuffer<ClusterAABB> clusters : register(t0);
StructuredBuffer<StructuredLight> lights : register(t1);
StructuredBuffer<ClusterAABB> clusters : register(t0);
StructuredBuffer<StructuredLight> lights : register(t1);

RWStructuredBuffer<uint> lightIndexCounter : register(u0); //1
RWStructuredBuffer<uint> lightIndexList : register(u1); //MAX_CLUSTER_LIGHTS * 16^3
RWStructuredBuffer<LightGrid> lightGrid : register(u2); //16^3
RWStructuredBuffer<uint> lightIndexCounter : register(u0); //1
RWStructuredBuffer<uint> lightIndexList : register(u1); //MAX_CLUSTER_LIGHTS * 16^3
RWStructuredBuffer<LightGrid> lightGrid : register(u2); //16^3

groupshared StructuredLight sharedLights[GROUP_SIZE];

bool LightIntersectsCluster(StructuredLight light, ClusterAABB cluster)
{
float3 closest = max(cluster.minPoint, min(light.positionVS.xyz, cluster.maxPoint)).xyz;
// For now, only use left eye position
float3 closest = max(cluster.minPoint, min(light.positionVS[0].xyz, cluster.maxPoint)).xyz;

float3 dist = closest - light.positionVS.xyz;
return dot(dist, dist) <= (light.radius * light.radius);
float3 dist = closest - light.positionVS[0].xyz;
return dot(dist, dist) <= (light.radius * light.radius);
}

[numthreads(16, 8, 8)]
void main(uint3 groupId : SV_GroupID,
uint3 dispatchThreadId : SV_DispatchThreadID,
uint3 groupThreadId : SV_GroupThreadID,
uint groupIndex : SV_GroupIndex)
{
if (all(dispatchThreadId == 0))
{
lightIndexCounter[0] = 0;
}

uint visibleLightCount = 0;
uint visibleLightIndices[MAX_CLUSTER_LIGHTS];

uint clusterIndex = groupIndex + GROUP_SIZE * groupId.z;

ClusterAABB cluster = clusters[clusterIndex];

uint lightOffset = 0;
uint lightCount, dummy;
lights.GetDimensions(lightCount, dummy);

while (lightOffset < lightCount)
{
uint batchSize = min(GROUP_SIZE, lightCount - lightOffset);

if(groupIndex < batchSize)
{
uint lightIndex = lightOffset + groupIndex;

StructuredLight light = lights[lightIndex];

sharedLights[groupIndex] = light;
}

GroupMemoryBarrierWithGroupSync();

for (uint i = 0; i < batchSize; i++)
{
StructuredLight light = lights[i];

if (visibleLightCount < MAX_CLUSTER_LIGHTS && LightIntersectsCluster(light, cluster))
{
visibleLightIndices[visibleLightCount] = lightOffset + i;
visibleLightCount++;
}
}

lightOffset += batchSize;
}

GroupMemoryBarrierWithGroupSync();

uint offset = 0;
InterlockedAdd(lightIndexCounter[0], visibleLightCount, offset);

for (uint i = 0; i < visibleLightCount; i++)
{
lightIndexList[offset + i] = visibleLightIndices[i];
}

lightGrid[clusterIndex].offset = offset;
lightGrid[clusterIndex].lightCount = visibleLightCount;
[numthreads(16, 8, 8)] void main(uint3 groupId
: SV_GroupID,
uint3 dispatchThreadId
: SV_DispatchThreadID,
uint3 groupThreadId
: SV_GroupThreadID,
uint groupIndex
: SV_GroupIndex) {
if (all(dispatchThreadId == 0)) {
lightIndexCounter[0] = 0;
}

uint visibleLightCount = 0;
uint visibleLightIndices[MAX_CLUSTER_LIGHTS];

uint clusterIndex = groupIndex + GROUP_SIZE * groupId.z;

ClusterAABB cluster = clusters[clusterIndex];

uint lightOffset = 0;
uint lightCount, dummy;
lights.GetDimensions(lightCount, dummy);

while (lightOffset < lightCount) {
uint batchSize = min(GROUP_SIZE, lightCount - lightOffset);

if (groupIndex < batchSize) {
uint lightIndex = lightOffset + groupIndex;

StructuredLight light = lights[lightIndex];

sharedLights[groupIndex] = light;
}

GroupMemoryBarrierWithGroupSync();

for (uint i = 0; i < batchSize; i++) {
StructuredLight light = lights[i];

if (visibleLightCount < MAX_CLUSTER_LIGHTS && LightIntersectsCluster(light, cluster)) {
visibleLightIndices[visibleLightCount] = lightOffset + i;
visibleLightCount++;
}
}

lightOffset += batchSize;
}

GroupMemoryBarrierWithGroupSync();

uint offset = 0;
InterlockedAdd(lightIndexCounter[0], visibleLightCount, offset);

for (uint i = 0; i < visibleLightCount; i++) {
lightIndexList[offset + i] = visibleLightIndices[i];
}

lightGrid[clusterIndex].offset = offset;
lightGrid[clusterIndex].lightCount = visibleLightCount;
}

//https://www.3dgep.com/forward-plus/#Grid_Frustums_Compute_Shader
Expand Down
51 changes: 29 additions & 22 deletions features/Light Limit Fix/Shaders/LightLimitFix/Common.hlsli
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

#define GROUP_SIZE (16*8*8)
#define GROUP_SIZE (16 * 8 * 8)
#define MAX_CLUSTER_LIGHTS 128

#define CLUSTER_BUILDING_DISPATCH_SIZE_X 16
Expand All @@ -8,41 +8,48 @@

struct ClusterAABB
{
float4 minPoint;
float4 maxPoint;
float4 minPoint;
float4 maxPoint;
};

struct LightGrid
{
uint offset;
uint lightCount;
uint offset;
uint lightCount;
};

struct StructuredLight
{
float3 color;
float radius;
float3 positionWS;
float3 positionVS;
uint shadowMode;
uint pad;
float3 color;
float radius;
float3 positionWS[2];
float3 positionVS[2];
uint shadowMode;
uint pad;
};

cbuffer PerFrame : register(b0)
{
row_major float4x4 InvProjMatrix;
float CameraNear;
float CameraFar;
float pad[2];
row_major float4x4 InvProjMatrix[2];
float CameraNear;
float CameraFar;
float pad[2];
}

float3 GetPositionVS(float2 texcoord, float depth)
{
float4 clipSpaceLocation;
clipSpaceLocation.xy = texcoord * 2.0f - 1.0f;
clipSpaceLocation.y *= -1;
clipSpaceLocation.z = depth;
clipSpaceLocation.w = 1.0f;
float4 homogenousLocation = mul(clipSpaceLocation, InvProjMatrix);
return homogenousLocation.xyz / homogenousLocation.w;
float4 clipSpaceLocation;
#ifdef VR
uint eyeIndex = (texcoord.x > .5);
// next code should convert between eyes in VR (may not be necessary)
// texcoord.x = (texcoord.x * 2 - eyeIndex); // [0, 0.5] -> [0, 1], [0.5, 1] -> [0, 1]
#else
uint eyeIndex = 0;
#endif //VR
clipSpaceLocation.xy = texcoord * 2.0f - 1.0f; // convert from [0,1] to [-1,1]
clipSpaceLocation.y *= -1;
clipSpaceLocation.z = depth;
clipSpaceLocation.w = 1.0f;
float4 homogenousLocation = mul(clipSpaceLocation, InvProjMatrix[0]);
return homogenousLocation.xyz / homogenousLocation.w;
}
Loading