Importing a 3d model - do I have to use a custom vertex type for indexing?
I'm importing a 3d model(using FBX SDK) with C++ and OpenGL.
I made a vertex type:
struct Vertex {
Vec3 position;
Vec2 texCoord;
Vec3 normal;
Vec3 binormal;
Vec3 tangent;
SkinInfo skin;
}
Currently, I'm assigning a std::numeric_limits<float>::infinity() to unused components when loads a model. And construct a mesh class with std::vector<Vertex>.
The ctor of a mesh class changes vertex list to interleaved array and calculates offset and stride, omitting unused components.
The problem is, when loading a model. In case of a simple object, there's only position, UV and normal info; what a waste of memory.
Maybe the best solution is a exporting fbx file to game-friendly format, but I don't have enough time.
I have to use indexed vertex array for performance(glDrawElements), but I cannot find a better solution without using a vertex type for deduplication and indexing. Any better idea?
c++ opengl graphics
|
show 3 more comments
I'm importing a 3d model(using FBX SDK) with C++ and OpenGL.
I made a vertex type:
struct Vertex {
Vec3 position;
Vec2 texCoord;
Vec3 normal;
Vec3 binormal;
Vec3 tangent;
SkinInfo skin;
}
Currently, I'm assigning a std::numeric_limits<float>::infinity() to unused components when loads a model. And construct a mesh class with std::vector<Vertex>.
The ctor of a mesh class changes vertex list to interleaved array and calculates offset and stride, omitting unused components.
The problem is, when loading a model. In case of a simple object, there's only position, UV and normal info; what a waste of memory.
Maybe the best solution is a exporting fbx file to game-friendly format, but I don't have enough time.
I have to use indexed vertex array for performance(glDrawElements), but I cannot find a better solution without using a vertex type for deduplication and indexing. Any better idea?
c++ opengl graphics
Instead ofstd::numeric_limits<float>::infinity()you should use some NaN (not a number) value. either…::quiet_NaN()or…::signaling:NaN().
– datenwolf
Nov 12 '18 at 9:28
@datenwolf Good point. I'll change it.
– dragon-kurve
Nov 12 '18 at 9:38
@dragon-kurve not really sure I got the question right, why not use separate arrays for each component? That's quite likely to have better cache utilisation too.
– keltar
Nov 12 '18 at 13:56
@keltar: That's not how it works. The GPU needs the entire vertex before it can begin processing data. With separate arrays, it has to make several memory reads before it can begin processing. With a single interleaved array, you only need one. It's not a huge performance deficit or anything, but interleaving is always preferred where possible.
– Nicol Bolas
Nov 12 '18 at 14:48
@NicolBolas but you can freely disable some arrays where you don't need them (depth pre-pass, ....). Likely to give net positive, I think. And certainly better than NaN or INF gaps which will just destroy cache.
– keltar
Nov 12 '18 at 15:23
|
show 3 more comments
I'm importing a 3d model(using FBX SDK) with C++ and OpenGL.
I made a vertex type:
struct Vertex {
Vec3 position;
Vec2 texCoord;
Vec3 normal;
Vec3 binormal;
Vec3 tangent;
SkinInfo skin;
}
Currently, I'm assigning a std::numeric_limits<float>::infinity() to unused components when loads a model. And construct a mesh class with std::vector<Vertex>.
The ctor of a mesh class changes vertex list to interleaved array and calculates offset and stride, omitting unused components.
The problem is, when loading a model. In case of a simple object, there's only position, UV and normal info; what a waste of memory.
Maybe the best solution is a exporting fbx file to game-friendly format, but I don't have enough time.
I have to use indexed vertex array for performance(glDrawElements), but I cannot find a better solution without using a vertex type for deduplication and indexing. Any better idea?
c++ opengl graphics
I'm importing a 3d model(using FBX SDK) with C++ and OpenGL.
I made a vertex type:
struct Vertex {
Vec3 position;
Vec2 texCoord;
Vec3 normal;
Vec3 binormal;
Vec3 tangent;
SkinInfo skin;
}
Currently, I'm assigning a std::numeric_limits<float>::infinity() to unused components when loads a model. And construct a mesh class with std::vector<Vertex>.
The ctor of a mesh class changes vertex list to interleaved array and calculates offset and stride, omitting unused components.
The problem is, when loading a model. In case of a simple object, there's only position, UV and normal info; what a waste of memory.
Maybe the best solution is a exporting fbx file to game-friendly format, but I don't have enough time.
I have to use indexed vertex array for performance(glDrawElements), but I cannot find a better solution without using a vertex type for deduplication and indexing. Any better idea?
c++ opengl graphics
c++ opengl graphics
asked Nov 12 '18 at 9:21
dragon-kurve
285
285
Instead ofstd::numeric_limits<float>::infinity()you should use some NaN (not a number) value. either…::quiet_NaN()or…::signaling:NaN().
– datenwolf
Nov 12 '18 at 9:28
@datenwolf Good point. I'll change it.
– dragon-kurve
Nov 12 '18 at 9:38
@dragon-kurve not really sure I got the question right, why not use separate arrays for each component? That's quite likely to have better cache utilisation too.
– keltar
Nov 12 '18 at 13:56
@keltar: That's not how it works. The GPU needs the entire vertex before it can begin processing data. With separate arrays, it has to make several memory reads before it can begin processing. With a single interleaved array, you only need one. It's not a huge performance deficit or anything, but interleaving is always preferred where possible.
– Nicol Bolas
Nov 12 '18 at 14:48
@NicolBolas but you can freely disable some arrays where you don't need them (depth pre-pass, ....). Likely to give net positive, I think. And certainly better than NaN or INF gaps which will just destroy cache.
– keltar
Nov 12 '18 at 15:23
|
show 3 more comments
Instead ofstd::numeric_limits<float>::infinity()you should use some NaN (not a number) value. either…::quiet_NaN()or…::signaling:NaN().
– datenwolf
Nov 12 '18 at 9:28
@datenwolf Good point. I'll change it.
– dragon-kurve
Nov 12 '18 at 9:38
@dragon-kurve not really sure I got the question right, why not use separate arrays for each component? That's quite likely to have better cache utilisation too.
– keltar
Nov 12 '18 at 13:56
@keltar: That's not how it works. The GPU needs the entire vertex before it can begin processing data. With separate arrays, it has to make several memory reads before it can begin processing. With a single interleaved array, you only need one. It's not a huge performance deficit or anything, but interleaving is always preferred where possible.
– Nicol Bolas
Nov 12 '18 at 14:48
@NicolBolas but you can freely disable some arrays where you don't need them (depth pre-pass, ....). Likely to give net positive, I think. And certainly better than NaN or INF gaps which will just destroy cache.
– keltar
Nov 12 '18 at 15:23
Instead of
std::numeric_limits<float>::infinity() you should use some NaN (not a number) value. either …::quiet_NaN() or …::signaling:NaN().– datenwolf
Nov 12 '18 at 9:28
Instead of
std::numeric_limits<float>::infinity() you should use some NaN (not a number) value. either …::quiet_NaN() or …::signaling:NaN().– datenwolf
Nov 12 '18 at 9:28
@datenwolf Good point. I'll change it.
– dragon-kurve
Nov 12 '18 at 9:38
@datenwolf Good point. I'll change it.
– dragon-kurve
Nov 12 '18 at 9:38
@dragon-kurve not really sure I got the question right, why not use separate arrays for each component? That's quite likely to have better cache utilisation too.
– keltar
Nov 12 '18 at 13:56
@dragon-kurve not really sure I got the question right, why not use separate arrays for each component? That's quite likely to have better cache utilisation too.
– keltar
Nov 12 '18 at 13:56
@keltar: That's not how it works. The GPU needs the entire vertex before it can begin processing data. With separate arrays, it has to make several memory reads before it can begin processing. With a single interleaved array, you only need one. It's not a huge performance deficit or anything, but interleaving is always preferred where possible.
– Nicol Bolas
Nov 12 '18 at 14:48
@keltar: That's not how it works. The GPU needs the entire vertex before it can begin processing data. With separate arrays, it has to make several memory reads before it can begin processing. With a single interleaved array, you only need one. It's not a huge performance deficit or anything, but interleaving is always preferred where possible.
– Nicol Bolas
Nov 12 '18 at 14:48
@NicolBolas but you can freely disable some arrays where you don't need them (depth pre-pass, ....). Likely to give net positive, I think. And certainly better than NaN or INF gaps which will just destroy cache.
– keltar
Nov 12 '18 at 15:23
@NicolBolas but you can freely disable some arrays where you don't need them (depth pre-pass, ....). Likely to give net positive, I think. And certainly better than NaN or INF gaps which will just destroy cache.
– keltar
Nov 12 '18 at 15:23
|
show 3 more comments
1 Answer
1
active
oldest
votes
Most performance rendering applications have a (small) set of vertex formats they use. For your attributes, I see three possible vertex formats: unskinned/unbumpmapped, unskinned-with-bump-mapping, and skinned (with bump-mapping). There might be a possibility of a skinned-without-bump-mapping format too, but that's up to you and your data.
So you should have 3 separate formats (if you want to define them by C++ data structures, you can use 3 separate structs). You should render as much as you reasonably can without changing vertex formats though, so you should group models based on format. That is, if most of your terrain is unskinned, render all your terrain at once using the unskinned format.
In short, there is nothing forcing you to use a single vertex format. So if that's not appropriate for your needs, don't limit yourself to just that format.
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53259083%2fimporting-a-3d-model-do-i-have-to-use-a-custom-vertex-type-for-indexing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Most performance rendering applications have a (small) set of vertex formats they use. For your attributes, I see three possible vertex formats: unskinned/unbumpmapped, unskinned-with-bump-mapping, and skinned (with bump-mapping). There might be a possibility of a skinned-without-bump-mapping format too, but that's up to you and your data.
So you should have 3 separate formats (if you want to define them by C++ data structures, you can use 3 separate structs). You should render as much as you reasonably can without changing vertex formats though, so you should group models based on format. That is, if most of your terrain is unskinned, render all your terrain at once using the unskinned format.
In short, there is nothing forcing you to use a single vertex format. So if that's not appropriate for your needs, don't limit yourself to just that format.
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
add a comment |
Most performance rendering applications have a (small) set of vertex formats they use. For your attributes, I see three possible vertex formats: unskinned/unbumpmapped, unskinned-with-bump-mapping, and skinned (with bump-mapping). There might be a possibility of a skinned-without-bump-mapping format too, but that's up to you and your data.
So you should have 3 separate formats (if you want to define them by C++ data structures, you can use 3 separate structs). You should render as much as you reasonably can without changing vertex formats though, so you should group models based on format. That is, if most of your terrain is unskinned, render all your terrain at once using the unskinned format.
In short, there is nothing forcing you to use a single vertex format. So if that's not appropriate for your needs, don't limit yourself to just that format.
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
add a comment |
Most performance rendering applications have a (small) set of vertex formats they use. For your attributes, I see three possible vertex formats: unskinned/unbumpmapped, unskinned-with-bump-mapping, and skinned (with bump-mapping). There might be a possibility of a skinned-without-bump-mapping format too, but that's up to you and your data.
So you should have 3 separate formats (if you want to define them by C++ data structures, you can use 3 separate structs). You should render as much as you reasonably can without changing vertex formats though, so you should group models based on format. That is, if most of your terrain is unskinned, render all your terrain at once using the unskinned format.
In short, there is nothing forcing you to use a single vertex format. So if that's not appropriate for your needs, don't limit yourself to just that format.
Most performance rendering applications have a (small) set of vertex formats they use. For your attributes, I see three possible vertex formats: unskinned/unbumpmapped, unskinned-with-bump-mapping, and skinned (with bump-mapping). There might be a possibility of a skinned-without-bump-mapping format too, but that's up to you and your data.
So you should have 3 separate formats (if you want to define them by C++ data structures, you can use 3 separate structs). You should render as much as you reasonably can without changing vertex formats though, so you should group models based on format. That is, if most of your terrain is unskinned, render all your terrain at once using the unskinned format.
In short, there is nothing forcing you to use a single vertex format. So if that's not appropriate for your needs, don't limit yourself to just that format.
answered Nov 12 '18 at 15:39
Nicol Bolas
282k33466642
282k33466642
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
add a comment |
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
Okay, I'll try various vertex formats and overload some functions.
– dragon-kurve
Nov 13 '18 at 15:26
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53259083%2fimporting-a-3d-model-do-i-have-to-use-a-custom-vertex-type-for-indexing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Instead of
std::numeric_limits<float>::infinity()you should use some NaN (not a number) value. either…::quiet_NaN()or…::signaling:NaN().– datenwolf
Nov 12 '18 at 9:28
@datenwolf Good point. I'll change it.
– dragon-kurve
Nov 12 '18 at 9:38
@dragon-kurve not really sure I got the question right, why not use separate arrays for each component? That's quite likely to have better cache utilisation too.
– keltar
Nov 12 '18 at 13:56
@keltar: That's not how it works. The GPU needs the entire vertex before it can begin processing data. With separate arrays, it has to make several memory reads before it can begin processing. With a single interleaved array, you only need one. It's not a huge performance deficit or anything, but interleaving is always preferred where possible.
– Nicol Bolas
Nov 12 '18 at 14:48
@NicolBolas but you can freely disable some arrays where you don't need them (depth pre-pass, ....). Likely to give net positive, I think. And certainly better than NaN or INF gaps which will just destroy cache.
– keltar
Nov 12 '18 at 15:23