Skip to content

Commit

Permalink
Traktor: Improved mesh preview rasterizer.
Browse files Browse the repository at this point in the history
  • Loading branch information
apistol78 committed May 20, 2024
1 parent 98f12d8 commit eafa5c4
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 25 deletions.
2 changes: 1 addition & 1 deletion code/Mesh/Editor/MeshAssetRasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ bool MeshAssetRasterizer::generate(const editor::IEditor* editor, const MeshAsse
const Aabb3 boundingBox = model->getBoundingBox();
const Scalar maxExtent = (boundingBox.getExtent() * Vector4(1.0f, 1.0f, 0.0f, 0.0f)).max();
const Scalar invMaxExtent = 1.0_simd / maxExtent;
const Matrix44 modelView = translate(0.0f, 0.0f, 2.25f) * scale(invMaxExtent, invMaxExtent, invMaxExtent) * rotateY(asset->getPreviewAngle()) * translate(-boundingBox.getCenter());
const Matrix44 modelView = translate(0.0f, 0.0f, 2.5f) * scale(invMaxExtent, invMaxExtent, invMaxExtent) * rotateY(asset->getPreviewAngle()) * translate(-boundingBox.getCenter());
return model::ModelRasterizer().generate(model, modelView, outImage);
}

Expand Down
28 changes: 27 additions & 1 deletion code/Mesh/Editor/MeshBrowsePreview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Database/Instance.h"
#include "Drawing/Image.h"
#include "Drawing/PixelFormat.h"
#include "Drawing/Filters/GaussianBlurFilter.h"
#include "Drawing/Filters/ScaleFilter.h"
#include "Mesh/Editor/MeshAsset.h"
#include "Mesh/Editor/MeshAssetRasterizer.h"
Expand Down Expand Up @@ -37,7 +38,7 @@ Ref< ui::IBitmap > MeshBrowsePreview::generate(editor::IEditor* editor, db::Inst
128,
128
);
meshThumb->clear(Color4f(0.4f, 0.4f, 0.6f, 0.0f));
meshThumb->clear(Color4f(0.0f, 0.0f, 0.0f, 0.0f));

MeshAssetRasterizer().generate(editor, asset, meshThumb);

Expand All @@ -49,6 +50,31 @@ Ref< ui::IBitmap > MeshBrowsePreview::generate(editor::IEditor* editor, db::Inst
);
meshThumb->apply(&scaleFilter);

Ref< drawing::Image > shadow = meshThumb->clone();

drawing::GaussianBlurFilter blurFilter(16);
shadow->apply(&blurFilter);

for (int32_t y = 0; y < 64; ++y)
{
const float vy = min(4.0f * min(y, 63 - y) / 32.0f, 1.0f);

for (int32_t x = 0; x < 64; ++x)
{
const float vx = min(4.0f * min(x, 63 - x) / 32.0f, 1.0f);
const Scalar vignette(min(vx, vy));

Color4f alpha;
shadow->getPixelUnsafe(x, y, alpha);

Color4f color;
meshThumb->getPixelUnsafe(x, y, color);

color.setAlpha(max(color.getAlpha(), alpha.getAlpha() * 0.5_simd * vignette));
meshThumb->setPixelUnsafe(x, y, color);
}
}

return new ui::Bitmap(meshThumb);
}

Expand Down
4 changes: 2 additions & 2 deletions code/Model/Formats/Fbx/ModelFormatFbx.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#pragma optimize( "", off )

/*
* TRAKTOR
* Copyright (c) 2022-2024 Anders Pistol.
Expand Down Expand Up @@ -127,13 +125,15 @@ Ref< Model > ModelFormatFbx::read(const Path& filePath, const std::wstring& filt
if (!scene)
return nullptr;

#if defined(_DEBUG)
traverse(scene->root_node, L"", [](ufbx_node* node, int32_t depth) {
for (int32_t i = 0; i < depth; ++i)
log::info << L" ";
log::info << mbstows(node->name.data) << L" " << (node->bind_pose != nullptr ? L"Y" : L"N"
) << Endl;
return true;
});
#endif

const Matrix44 axisTransform = calculateAxisTransform(scene->settings.axes);

Expand Down
54 changes: 36 additions & 18 deletions code/Model/ModelRasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <functional>
#include "Core/Math/Triangle.h"
#include "Drawing/Image.h"
#include "Drawing/Filters/GammaFilter.h"
#include "Model/Model.h"
#include "Model/ModelRasterizer.h"

Expand All @@ -18,12 +17,23 @@ namespace traktor::model
namespace
{

const Vector4 c_sunDirection = Vector4(0.0f, -0.5f, 1.0f).normalized();

int32_t wrap(int32_t v, int32_t l)
{
const int32_t c = v % l;
return (c < 0) ? c + l : c;
}

Color4f lighting(const Vector4& p, const Vector4& n, const Color4f& materialColor)
{
const Vector4 viewDirection = p.xyz0().normalized();
const Vector4 halfWay = (c_sunDirection + viewDirection).normalized();
const Scalar diffuse = clamp(dot3(c_sunDirection, -n), 0.4_simd, 1.0_simd) + 0.1_simd;
const Scalar specular = power(clamp(dot3(halfWay, -n), 0.0_simd, 1.0_simd), 2.0_simd) * 0.25_simd;
return materialColor * diffuse + Color4f(1.0f, 1.0f, 1.0f, 0.0f) * specular;
}

}


Expand Down Expand Up @@ -106,26 +116,34 @@ bool ModelRasterizer::generate(const Model* model, const Matrix44& modelView, dr
const int32_t tw = texture->getWidth();
const int32_t th = texture->getHeight();

const bool textureLinear = (texture->getImageInfo() != nullptr) ? (std::abs(texture->getImageInfo()->getGamma() - 1.0f) < 0.1f) : false;

triangle(sp[0], sp[1], sp[2], [&, tw, th](int32_t x, int32_t y, float alpha, float beta, float gamma) {
if (x < 0 || x >= outImage->getWidth() || y < 0 || y >= outImage->getHeight())
return;

const int32_t offset = x + y * outImage->getWidth();
const Scalar salpha(alpha);
const Scalar sbeta(beta);
const Scalar sgamma(gamma);

const float z = cp[0].z() * Scalar(alpha) + cp[1].z() * Scalar(beta) + cp[2].z() * Scalar(gamma);
if (z < zbuffer[offset])
const Vector4 p = cp[0] * salpha + cp[1] * sbeta + cp[2] * sgamma;
if (p.z() < zbuffer[offset])
{
Color4f color;
const Vector2 tc = uv[0] * alpha + uv[1] * beta + uv[2] * gamma;
const int32_t tu = wrap((int32_t)(tc.x * tw), tw);
const int32_t tv = wrap((int32_t)(tc.y * th), th);
texture->getPixel(tu, tv, color);

const Vector4 n = (nm[0] * Scalar(alpha) + nm[1] * Scalar(beta) + nm[2] * Scalar(gamma)).normalized();
const Scalar d = -n.z() * 0.5_simd + 0.5_simd;
if (!textureLinear)
color = color.linear();

const Vector4 n = (nm[0] * salpha + nm[1] * sbeta + nm[2] * sgamma).normalized();
const Color4f d = lighting(p, n, color);

outImage->setPixelUnsafe(x, y, (color * d * 2.0_simd).rgb1());
zbuffer[offset] = z;
outImage->setPixelUnsafe(x, y, d.sRGB().rgb1());
zbuffer[offset] = p.z();
}
});
}
Expand All @@ -136,25 +154,25 @@ bool ModelRasterizer::generate(const Model* model, const Matrix44& modelView, dr
return;

const int32_t offset = x + y * outImage->getWidth();
const Scalar salpha(alpha);
const Scalar sbeta(beta);
const Scalar sgamma(gamma);

const float z = cp[0].z() * Scalar(alpha) + cp[1].z() * Scalar(beta) + cp[2].z() * Scalar(gamma);
if (z < zbuffer[offset])
const Vector4 p = cp[0] * salpha + cp[1] * sbeta + cp[2] * sgamma;
if (p.z() < zbuffer[offset])
{
const Color4f& color = polygonMaterial.getColor();
const Vector4 n = (nm[0] * Scalar(alpha) + nm[1] * Scalar(beta) + nm[2] * Scalar(gamma)).normalized();
const Scalar d = -n.z() * 0.5_simd + 0.5_simd;
const Color4f color = polygonMaterial.getColor().linear();

outImage->setPixelUnsafe(x, y, (color * d * 2.0_simd).rgb1());
zbuffer[offset] = z;
const Vector4 n = (nm[0] * salpha + nm[1] * sbeta + nm[2] * sgamma).normalized();
const Color4f d = lighting(p, n, color);

outImage->setPixelUnsafe(x, y, d.sRGB().rgb1());
zbuffer[offset] = p.z();
}
});
}
}

// Convert image from linear gamma to sRGB.
drawing::GammaFilter gammaFilter(1.0f, 2.2f);
outImage->apply(&gammaFilter);

return true;
}

Expand Down
2 changes: 1 addition & 1 deletion code/Physics/Editor/MeshAssetRasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ bool MeshAssetRasterizer::generate(const editor::IEditor* editor, const MeshAsse
const Aabb3 boundingBox = model->getBoundingBox();
const Scalar maxExtent = (boundingBox.getExtent() * Vector4(1.0f, 1.0f, 0.0f, 0.0f)).max();
const Scalar invMaxExtent = 1.0_simd / maxExtent;
const Matrix44 modelView = translate(0.0f, 0.0f, 2.25f) * scale(invMaxExtent, invMaxExtent, invMaxExtent) * rotateY(/*asset->getPreviewAngle()*/3.0f) * translate(-boundingBox.getCenter());
const Matrix44 modelView = translate(0.0f, 0.0f, 2.5f) * scale(invMaxExtent, invMaxExtent, invMaxExtent) * rotateY(/*asset->getPreviewAngle()*/3.0f) * translate(-boundingBox.getCenter());
return model::ModelRasterizer().generate(model, modelView, outImage);
}

Expand Down
30 changes: 28 additions & 2 deletions code/Physics/Editor/MeshBrowsePreview.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* TRAKTOR
* Copyright (c) 2022 Anders Pistol.
* Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -9,6 +9,7 @@
#include "Database/Instance.h"
#include "Drawing/Image.h"
#include "Drawing/PixelFormat.h"
#include "Drawing/Filters/GaussianBlurFilter.h"
#include "Drawing/Filters/ScaleFilter.h"
#include "Physics/Editor/MeshAsset.h"
#include "Physics/Editor/MeshAssetRasterizer.h"
Expand Down Expand Up @@ -37,7 +38,7 @@ Ref< ui::IBitmap > MeshBrowsePreview::generate(editor::IEditor* editor, db::Inst
128,
128
);
meshThumb->clear(Color4f(0.4f, 0.6f, 0.4f, 0.0f));
meshThumb->clear(Color4f(0.0f, 0.0f, 0.0f, 0.0f));

MeshAssetRasterizer().generate(editor, asset, meshThumb);

Expand All @@ -49,6 +50,31 @@ Ref< ui::IBitmap > MeshBrowsePreview::generate(editor::IEditor* editor, db::Inst
);
meshThumb->apply(&scaleFilter);

Ref< drawing::Image > shadow = meshThumb->clone();

drawing::GaussianBlurFilter blurFilter(16);
shadow->apply(&blurFilter);

for (int32_t y = 0; y < 64; ++y)
{
const float vy = min(4.0f * min(y, 63 - y) / 32.0f, 1.0f);

for (int32_t x = 0; x < 64; ++x)
{
const float vx = min(4.0f * min(x, 63 - x) / 32.0f, 1.0f);
const Scalar vignette(min(vx, vy));

Color4f alpha;
shadow->getPixelUnsafe(x, y, alpha);

Color4f color;
meshThumb->getPixelUnsafe(x, y, color);

color.setAlpha(max(color.getAlpha(), alpha.getAlpha() * 0.5_simd * vignette));
meshThumb->setPixelUnsafe(x, y, color);
}
}

return new ui::Bitmap(meshThumb);
}

Expand Down

0 comments on commit eafa5c4

Please sign in to comment.