Improve the AO pass

This commit is contained in:
Magnus Norddahl 2021-11-25 01:13:53 +01:00
parent bde4c60f82
commit 0772f148c4
5 changed files with 55 additions and 30 deletions

View file

@ -377,7 +377,7 @@ void CPURaytracer::CreateHemisphereVectors()
vec3 H; vec3 H;
H.x = Xi.x * 2.0f - 1.0f; H.x = Xi.x * 2.0f - 1.0f;
H.y = Xi.y * 2.0f - 1.0f; H.y = Xi.y * 2.0f - 1.0f;
H.z = RadicalInverse_VdC(i) + 0.01f; H.z = 1.5f - length(Xi);
H = normalize(H); H = normalize(H);
HemisphereVectors.push_back(H); HemisphereVectors.push_back(H);
} }

View file

@ -80,7 +80,7 @@ void main()
for (uint i = 0; i < SampleCount; i++) for (uint i = 0; i < SampleCount; i++)
{ {
vec2 Xi = Hammersley(i, SampleCount); vec2 Xi = Hammersley(i, SampleCount);
vec3 H = normalize(vec3(Xi.x * 2.0f - 1.0f, Xi.y * 2.0f - 1.0f, RadicalInverse_VdC(i) + 0.01f)); vec3 H = normalize(vec3(Xi.x * 2.0f - 1.0f, Xi.y * 2.0f - 1.0f, 1.5 - length(Xi)));
vec3 L = H.x * tangent + H.y * bitangent + H.z * N; vec3 L = H.x * tangent + H.y * bitangent + H.z * N;
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 3, 0, 3, origin, minDistance, L, 32768, 0); traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 3, 0, 3, origin, minDistance, L, 32768, 0);
ambience += clamp(payload.hitAttenuation / aoDistance, 0.0, 1.0); ambience += clamp(payload.hitAttenuation / aoDistance, 0.0, 1.0);

View file

@ -84,7 +84,7 @@ void GPURaytracer::Raytrace(LevelMesh* level)
vec3 H; vec3 H;
H.x = Xi.x * 2.0f - 1.0f; H.x = Xi.x * 2.0f - 1.0f;
H.y = Xi.y * 2.0f - 1.0f; H.y = Xi.y * 2.0f - 1.0f;
H.z = RadicalInverse_VdC(i) + 0.01f; H.z = 1.5f - length(Xi);
H = normalize(H); H = normalize(H);
HemisphereVectors.push_back(H); HemisphereVectors.push_back(H);
} }
@ -191,7 +191,7 @@ void GPURaytracer::UploadTasks(const TraceTask* tasks, size_t size)
if (task.id >= 0) if (task.id >= 0)
{ {
Surface* surface = mesh->surfaces[task.id].get(); Surface* surface = mesh->surfaces[task.id].get();
vec3 pos = surface->lightmapOrigin + surface->lightmapSteps[0] * (float)task.x + surface->lightmapSteps[1] * (float)task.y; vec3 pos = surface->lightmapOrigin + surface->lightmapSteps[0] * (task.x + 0.5f) + surface->lightmapSteps[1] * (task.y + 0.5f);
startPositions[i] = vec4(pos, (float)task.id); startPositions[i] = vec4(pos, (float)task.id);
} }
else else

View file

@ -135,10 +135,10 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
// round off dimentions // round off dimentions
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
bounds.min[i] = samples * Math::Floor(bounds.min[i] / samples); bounds.min[i] = samples * (Math::Floor(bounds.min[i] / samples) - 1);
bounds.max[i] = samples * Math::Ceil(bounds.max[i] / samples); bounds.max[i] = samples * (Math::Ceil(bounds.max[i] / samples) + 1);
roundedSize[i] = (bounds.max[i] - bounds.min[i]) / samples + 1; roundedSize[i] = (bounds.max[i] - bounds.min[i]) / samples;
} }
tCoords[0] = vec3(0.0f); tCoords[0] = vec3(0.0f);
@ -184,7 +184,32 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
height = (textureHeight - 2); height = (textureHeight - 2);
} }
surface->lightmapCoords.resize(surface->numVerts * 2); surface->lightmapCoords.resize(surface->numVerts);
for (i = 0; i < surface->numVerts; i++)
{
vec3 tDelta = surface->verts[i] - bounds.min;
surface->lightmapCoords[i].x = dot(tDelta, tCoords[0]);
surface->lightmapCoords[i].y = dot(tDelta, tCoords[1]);
}
/*
surface->coveragemask.resize(width * height);
if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
{
int count = surfaces[i]->numVerts;
for (i = 0; i < count; i++)
{
MarkEdge(surface, i, i + 1 % count);
}
}
else // triangle strip
{
MarkEdge(surface, 0, 2);
MarkEdge(surface, 2, 3);
MarkEdge(surface, 3, 1);
MarkEdge(surface, 1, 0);
}
*/
surface->textureCoords[0] = tCoords[0]; surface->textureCoords[0] = tCoords[0];
surface->textureCoords[1] = tCoords[1]; surface->textureCoords[1] = tCoords[1];
@ -209,10 +234,8 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
surface->lightmapSteps[0] = tCoords[0] * (float)samples; surface->lightmapSteps[0] = tCoords[0] * (float)samples;
surface->lightmapSteps[1] = tCoords[1] * (float)samples; surface->lightmapSteps[1] = tCoords[1] * (float)samples;
int sampleWidth = surface->lightmapDims[0]; surface->samples.resize(width * height);
int sampleHeight = surface->lightmapDims[1]; surface->indirect.resize(width * height);
surface->samples.resize(sampleWidth * sampleHeight);
surface->indirect.resize(sampleWidth * sampleHeight);
} }
BBox LevelMesh::GetBoundsFromSurface(const Surface* surface) BBox LevelMesh::GetBoundsFromSurface(const Surface* surface)
@ -305,12 +328,13 @@ void LevelMesh::FinishSurface(Surface* surface)
uint16_t* currentTexture = textures[surface->lightmapNum]->Pixels(); uint16_t* currentTexture = textures[surface->lightmapNum]->Pixels();
// calculate texture coordinates // calculate final texture coordinates
for (int i = 0; i < surface->numVerts; i++) for (int i = 0; i < surface->numVerts; i++)
{ {
vec3 tDelta = surface->verts[i] - surface->bounds.min; auto& u = surface->lightmapCoords[i].x;
surface->lightmapCoords[i * 2 + 0] = (dot(tDelta, surface->textureCoords[0]) + x + 0.5f) / (float)textureWidth; auto& v = surface->lightmapCoords[i].y;
surface->lightmapCoords[i * 2 + 1] = (dot(tDelta, surface->textureCoords[1]) + y + 0.5f) / (float)textureHeight; u = (u + x) / (float)textureWidth;
v = (v + y) / (float)textureHeight;
} }
surface->lightmapOffs[0] = x; surface->lightmapOffs[0] = x;
@ -881,33 +905,33 @@ void LevelMesh::AddLightmapLump(FWadWriter& wadFile)
{ {
for (int j = count - 1; j >= 0; j--) for (int j = count - 1; j >= 0; j--)
{ {
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j * 2]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j].x);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j * 2 + 1]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j].y);
} }
} }
else if (surfaces[i]->type == ST_CEILING) else if (surfaces[i]->type == ST_CEILING)
{ {
for (int j = 0; j < count; j++) for (int j = 0; j < count; j++)
{ {
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j * 2]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j].x);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j * 2 + 1]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[j].y);
} }
} }
else else
{ {
// zdray uses triangle strip internally, lump/gzd uses triangle fan // zdray uses triangle strip internally, lump/gzd uses triangle fan
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[0]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[0].x);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[1]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[0].y);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[4]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[2].x);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[5]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[2].y);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[6]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[3].x);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[7]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[3].y);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[2]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[1].x);
lumpFile.WriteFloat(surfaces[i]->lightmapCoords[3]); lumpFile.WriteFloat(surfaces[i]->lightmapCoords[1].y);
} }
} }
@ -954,7 +978,7 @@ void LevelMesh::Export(std::string filename)
int uvindex = MeshUVIndex[vertexidx]; int uvindex = MeshUVIndex[vertexidx];
outvertices[vertexidx] = MeshVertices[vertexidx]; outvertices[vertexidx] = MeshVertices[vertexidx];
outuv[vertexidx] = vec2(surface->lightmapCoords[uvindex * 2], surface->lightmapCoords[uvindex * 2 + 1]); outuv[vertexidx] = surface->lightmapCoords[uvindex];
outnormal[vertexidx] = surface->plane.Normal(); outnormal[vertexidx] = surface->plane.Normal();
outface.Push(vertexidx); outface.Push(vertexidx);

View file

@ -64,7 +64,8 @@ struct Surface
BBox bounds; BBox bounds;
int numVerts; int numVerts;
std::vector<vec3> verts; std::vector<vec3> verts;
std::vector<float> lightmapCoords; std::vector<vec2> lightmapCoords;
//std::vector<bool> coveragemask;
std::vector<vec3> samples; std::vector<vec3> samples;
std::vector<vec3> indirect; std::vector<vec3> indirect;
SurfaceType type; SurfaceType type;