Skip to content

Commit

Permalink
Traktor: Removed supersampling in bake gbuffer, didn't fix enough qua…
Browse files Browse the repository at this point in the history
…lity for the cost.
  • Loading branch information
apistol78 committed Oct 5, 2023
1 parent 6b2b184 commit 2a1d057
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 95 deletions.
2 changes: 1 addition & 1 deletion code/Model/Operations/UnwrapUV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ bool UnwrapUV::apply(Model& model) const

xatlas::PackOptions po;
po.blockAlign = true;
po.padding = 2;
po.padding = 4;
po.resolution = m_textureSize;

xatlas::Generate(atlas, co, po);
Expand Down
7 changes: 6 additions & 1 deletion code/Shape/Editor/Bake/BakePipelineOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,11 +675,13 @@ bool BakePipelineOperator::build(

// Check if model already contain lightmap UV or if we need to unwrap.
uint32_t channel = model->getTexCoordChannel(L"Lightmap");
bool generated = false;
if (channel == model::c_InvalidIndex)
{
// No lightmap UV channel, need to add and unwrap automatically.
channel = model->addUniqueTexCoordChannel(L"Lightmap");
model::UnwrapUV(channel, /*lightmapSize*/1024).apply(*model);
generated = true;
}

// Evaluate lightmap size by measuring each edge ratio.
Expand Down Expand Up @@ -716,10 +718,13 @@ bool BakePipelineOperator::build(
lightmapSize = std::min< int32_t >(configuration->getMaximumLightMapSize(), lightmapSize);
lightmapSize = alignUp(lightmapSize, 4);

// Re-run UV unwrapping with proper lightmap size.
if (generated)
model::UnwrapUV(channel, lightmapSize).apply(*model);

model->setProperty< PropertyInteger >(L"LightmapDesiredSize", lightmapDesiredSize);
model->setProperty< PropertyInteger >(L"LightmapSize", lightmapSize);


// Attach an unique ID for this mesh; since visual model is cached this will get reused automatically.
model->setProperty< PropertyString >(L"ID", Guid::create().format());
return model;
Expand Down
37 changes: 14 additions & 23 deletions code/Shape/Editor/Bake/Embree/RayTracerEmbree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,6 @@ Ref< render::SHCoeffs > RayTracerEmbree::traceProbe(const Vector4& position) con

void RayTracerEmbree::traceLightmap(const model::Model* model, const GBuffer* gbuffer, drawing::Image* lightmapDiffuse, const int32_t region[4]) const
{
RTCRayHit T_ALIGN64 rh;
RandomGeometry random;

const Scalar ambientOcclusion(m_configuration->getAmbientOcclusionFactor());
Expand All @@ -342,34 +341,26 @@ void RayTracerEmbree::traceLightmap(const model::Model* model, const GBuffer* gb
{
for (int32_t x = region[0]; x < region[2]; ++x)
{
const GBuffer::element_vector_t& ev = gbuffer->get(x, y);
if (ev.empty())
const auto& e = gbuffer->get(x, y);
if (e.polygon == ~0U)
continue;

Color4f lightmapColor(0.0f, 0.0f, 0.0f, 0.0f);

for (int32_t i = 0; i < ev.size(); ++i)
{
auto& elm = ev[i];

const auto& originPolygon = polygons[elm.polygon];
const auto& originMaterial = materials[originPolygon.getMaterial()];

const Color4f emittance = originMaterial.getColor().linear() * Scalar(100.0f * originMaterial.getEmissive());
const auto& originPolygon = polygons[e.polygon];
const auto& originMaterial = materials[originPolygon.getMaterial()];

// Trace IBL and indirect illumination.
const Color4f incoming = tracePath0(elm.position, elm.normal, random, 0);
const Color4f emittance = originMaterial.getColor().linear() * Scalar(100.0f * originMaterial.getEmissive());

// Trace ambient occlusion.
Scalar occlusion = 1.0_simd;
if (ambientOcclusion > Scalar(FUZZY_EPSILON))
occlusion = (1.0_simd - ambientOcclusion) + ambientOcclusion * traceAmbientOcclusion(elm.position, elm.normal, random);
// Trace IBL and indirect illumination.
const Color4f incoming = tracePath0(e.position, e.normal, random, 0);

// Combine and write final lumel.
lightmapColor += emittance + incoming * occlusion;
}
// Trace ambient occlusion.
Scalar occlusion = 1.0_simd;
if (ambientOcclusion > Scalar(FUZZY_EPSILON))
occlusion = (1.0_simd - ambientOcclusion) + ambientOcclusion * traceAmbientOcclusion(e.position, e.normal, random);

lightmapDiffuse->setPixel(x, y, (lightmapColor / Scalar(ev.size())).rgb1());
// Combine and write final lumel.
const Color4f lightmapColor = emittance + incoming * occlusion;
lightmapDiffuse->setPixel(x, y, lightmapColor.rgb1());
}
}
}
Expand Down
66 changes: 23 additions & 43 deletions code/Shape/Editor/Bake/GBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ class Interpolants

T_IMPLEMENT_RTTI_CLASS(L"traktor.shape.GBuffer", GBuffer, Object)

bool GBuffer::create(int32_t width, int32_t height, const model::Model& model, const Transform& transform, uint32_t texCoordChannel, uint32_t maxElements)
bool GBuffer::create(int32_t width, int32_t height, const model::Model& model, const Transform& transform, uint32_t texCoordChannel)
{
T_FATAL_ASSERT(maxElements <= 4);

AlignedVector< Vector4 > positions;
AlignedVector< Vector4 > normals;
AlignedVector< Vector4 > tangents;
Expand All @@ -115,7 +113,6 @@ bool GBuffer::create(int32_t width, int32_t height, const model::Model& model, c
// Extract data for polygon.
positions.resize(0);
normals.resize(0);
tangents.resize(0);
texCoords.resize(0);

for (const auto index : polygon.getVertices())
Expand All @@ -128,11 +125,8 @@ bool GBuffer::create(int32_t width, int32_t height, const model::Model& model, c
const uint32_t normalIndex = vertex.getNormal();
normals.push_back((transform * model.getNormal(normalIndex).xyz0()).normalized());

const uint32_t tangentIndex = vertex.getTangent();
tangents.push_back((transform * model.getNormal(tangentIndex).xyz0()).normalized());

const uint32_t texCoordIndex = vertex.getTexCoord(texCoordChannel);
texCoords.push(model.getTexCoord(texCoordIndex) * wh);
texCoords.push(model.getTexCoord(texCoordIndex) * wh - Vector2(0.5f, 0.5f));

m_boundingBox.contain(positions.back());
}
Expand All @@ -157,17 +151,17 @@ bool GBuffer::create(int32_t width, int32_t height, const model::Model& model, c
normals[i2]
);

const Interpolants< Vector4 > ipolTangents(
tangents[i0],
tangents[i1],
tangents[i2]
);

Aabb2 bbox;
bbox.contain(texCoords[i0]);
bbox.contain(texCoords[i1]);
bbox.contain(texCoords[i2]);

const float a = (texCoords[i1] - texCoords[i0]).length();
const float b = (texCoords[i2] - texCoords[i1]).length();
const float c = (texCoords[i0] - texCoords[i2]).length();
const float s = 0.5f * (a + b + c);
const float area = sqrt(s * (s - a) * (s - b) * (s - c));

const int32_t pad = 2;
const int32_t sx = (int32_t)(bbox.mn.x - pad - 0.5f);
const int32_t ex = (int32_t)(bbox.mx.x + pad + 0.5f);
Expand All @@ -181,50 +175,36 @@ bool GBuffer::create(int32_t width, int32_t height, const model::Model& model, c
if (x < 0 || x >= width || y < 0 || y >= height)
continue;

const Vector2 texelCenterRnd = Vector2(rnd.nextFloat() * 0.5f - 0.5f, rnd.nextFloat() * 0.5f - 0.5f);
const Vector2 texelCenter = Vector2((float)x + 0.5f, (float)y + 0.5f) + texelCenterRnd;
const float maxDistance = 1.0f;

const Vector2 texelCenter = Vector2((float)x, (float)y);
Vector2 pt = texelCenter;
if (!bary.inside(pt))
{
const Vector2 cpt = texCoords.closest(pt);
const Vector2 d = (pt - cpt).absolute();
if (d.x > 1.5f || d.y > 1.5f)
if (d.x > maxDistance || d.y > maxDistance)
continue;
pt = cpt;
}

float distance = distance = (pt - texelCenter).length();
element_vector_t& ev = m_data[x + y * m_width];
const float distance = (pt - texelCenter).length();

// Add to elements, if full we try to replace a worst entry if possible.
Element* elm = nullptr;
if (ev.size() < maxElements)
elm = &ev.push_back();
else
auto& e = m_data[x + y * m_width];
if (e.polygon != ~0U)
{
// Sort worst to best; replace worst if distance is less than any entry.
std::sort(ev.begin(), ev.end(), [&](Element& lh, Element& rh) {
return lh.distance > rh.distance;
});
for (auto& it : ev)
{
if (distance < it.distance)
{
elm = ev.ptr();
break;
}
}
if (!elm)
if (distance > e.distance)
continue;
if (abs(distance - e.distance) < FUZZY_EPSILON && area < e.area)
continue;
}

elm->position = ipolPositions.evaluate(bary, pt).xyz1();
elm->normal = ipolNormals.evaluate(bary, pt).xyz0().normalized();
elm->tangent = ipolTangents.evaluate(bary, pt).xyz0().normalized();
elm->polygon = i;
elm->material = polygon.getMaterial();
elm->distance = distance;
e.position = ipolPositions.evaluate(bary, pt).xyz1();
e.normal = ipolNormals.evaluate(bary, pt).xyz0().normalized();
e.polygon = i;
e.material = polygon.getMaterial();
e.area = area;
e.distance = distance;
}
}
});
Expand Down
13 changes: 5 additions & 8 deletions code/Shape/Editor/Bake/GBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#include "Core/Object.h"
#include "Core/Containers/AlignedVector.h"
#include "Core/Containers/StaticVector.h"
#include "Core/Math/Aabb3.h"
#include "Shape/Editor/Bake/Types.h"
#include "Model/Model.h"
Expand All @@ -34,17 +33,15 @@ class GBuffer : public Object
{
Vector4 position;
Vector4 normal;
Vector4 tangent;
uint32_t polygon;
uint32_t polygon = ~0U;
uint32_t material;
float area;
float distance;
};

typedef StaticVector< Element, 4 > element_vector_t;
bool create(int32_t width, int32_t height, const model::Model& model, const Transform& transform, uint32_t texCoordChannel);

bool create(int32_t width, int32_t height, const model::Model& model, const Transform& transform, uint32_t texCoordChannel, uint32_t maxElements);

const element_vector_t& get(int32_t x, int32_t y) const { return m_data[x + y * m_width]; }
const Element& get(int32_t x, int32_t y) const { return m_data[x + y * m_width]; }

int32_t getWidth() const { return m_width; }

Expand All @@ -55,7 +52,7 @@ class GBuffer : public Object
private:
int32_t m_width = 0;
int32_t m_height = 0;
AlignedVector< element_vector_t > m_data;
AlignedVector< Element > m_data;
Aabb3 m_boundingBox;
};

Expand Down
73 changes: 54 additions & 19 deletions code/Shape/Editor/Bake/TracerProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
# include <OpenImageDenoise/oidn.h>
#endif

#include "Core/Math/Random.h"
#include "Model/ModelFormat.h"

namespace traktor
{
namespace shape
Expand Down Expand Up @@ -89,17 +92,10 @@ Ref< drawing::Image > denoise(const GBuffer& gbuffer, drawing::Image* lightmap,
{
for (int32_t x = 0; x < width; ++x)
{
const GBuffer::element_vector_t& ev = gbuffer.get(x, y);

if (ev.empty())
const auto& e = gbuffer.get(x, y);
if (e.polygon == ~0U)
continue;

Vector4 normal = Vector4::zero();
for (const auto& elm : ev)
normal += elm.normal;
normal.normalize();

normals.setPixelUnsafe(x, y, Color4f(normal));
normals.setPixelUnsafe(x, y, Color4f(e.normal));
}
}

Expand Down Expand Up @@ -278,13 +274,13 @@ TracerProcessor::TracerProcessor(const TypeInfo* rayTracerType, const std::wstri
m_thread = ThreadManager::getInstance().create([this](){ processorThread(); }, L"Tracer");
m_thread->start();

if (!m_editor)
//if (!m_editor)
m_queue = &JobManager::getInstance().getQueue();
else
{
m_queue = new JobQueue();
m_queue->create(4, Thread::Below);
}
//else
//{
// m_queue = new JobQueue();
// m_queue->create(4, Thread::Below);
//}
}

TracerProcessor::~TracerProcessor()
Expand All @@ -300,8 +296,8 @@ TracerProcessor::~TracerProcessor()
m_thread = nullptr;
}

if (m_editor)
safeDestroy(m_queue);
//if (m_editor)
// safeDestroy(m_queue);
}

void TracerProcessor::enqueue(const TracerTask* task)
Expand Down Expand Up @@ -446,7 +442,46 @@ bool TracerProcessor::process(const TracerTask* task)

// Create GBuffer of mesh's geometry.
GBuffer gbuffer;
gbuffer.create(width, height, *renderModel, tracerOutput->getTransform(), channel, 4);
gbuffer.create(width, height, *renderModel, tracerOutput->getTransform(), channel);

//{
// model::ModelFormat::writeAny(str(L"data/Temp/Model_%03d.obj", i), renderModel);
// Ref< drawing::Image > img = new drawing::Image(drawing::PixelFormat::getR8G8B8A8(), width, height);
// for (int y = 0; y < height; ++y)
// {
// for (int x = 0; x < width; ++x)
// {
// const auto& g = gbuffer.get(x, y);
// if (!g.empty())
// {
// switch (g.size())
// {
// case 1:
// img->setPixel(x, y, Color4f(0.0f, 1.0f, 0.0f, 1.0f));
// break;
// case 2:
// img->setPixel(x, y, Color4f(1.0f, 1.0f, 0.0f, 1.0f));
// break;
// case 3:
// img->setPixel(x, y, Color4f(1.0f, 0.0f, 0.0f, 1.0f));
// break;
// case 4:
// img->setPixel(x, y, Color4f(0.0f, 0.0f, 1.0f, 1.0f));
// break;
// case 5:
// img->setPixel(x, y, Color4f(0.0f, 1.0f, 1.0f, 1.0f));
// break;
// default:
// img->setPixel(x, y, Color4f(1.0f, 1.0f, 1.0f, 1.0f));
// break;
// }
// }
// else
// img->setPixel(x, y, Color4f(0.0f, 0.0f, 0.0f, 1.0f));
// }
// }
// img->save(str(L"data/Temp/Model_%03d.png", i));
//}

// Trace lightmaps.
Ref< drawing::Image > lightmapDiffuse = new drawing::Image(
Expand Down

0 comments on commit 2a1d057

Please sign in to comment.