(C++) Trouble adding more than 1 set of uv coords using setTexCoord()?

My actual goal here is to write N number of uv sets based on what assimp finds in a 3d model it’s importing. However everything I try outside of the below example to accommodate more than 3 uv channels (more than 2 sets) causes an instant crash for TD.

How would I modify the below code to add more than 1 set of uv point coordinates ?

for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++)
{
	pos.x = scene->mMeshes[0]->mVertices[i][0];
	pos.y = scene->mMeshes[0]->mVertices[i][1];
	pos.z = scene->mMeshes[0]->mVertices[i][2];

	output->addPoint(pos);

	tex.u = scene->mMeshes[0]->mTextureCoords[0][i][0];
	tex.v = scene->mMeshes[0]->mTextureCoords[0][i][1];
	tex.w = scene->mMeshes[0]->mTextureCoords[0][i][2];
	int numTextures = 1;

	output->setTexCoord(
		&tex,
		numTextures, // number of texture layers. 1-8
		i // point index we wish to apply these uv settings to.
	);

}

Related issue in SimpleShapesSOP ?

If I take the SimpleShapesSOP sample c++ project straight out of the samples folder, and compile it, I get a working dll that I can load into a c++ SOP:

Next I plug another SOP into the c++ SOP that has 2 uv sets:

Looking at line ~400-425 in the SimpleShapes.cpp, I see this:


		if (sinput->getTextures()->numTextureLayers)
		{
			textures = sinput->getTextures()->textures;
			numTextures = sinput->getTextures()->numTextureLayers;
		}

		for (int i = 0; i < sinput->getNumPoints(); i++)
		{
			output->addPoint(ptArr[i]);

			if (normals)
			{
				output->setNormal(normals[i], i);
			}

			if (colors)
			{
				output->setColor(colors[i], i);
			}

			if (textures)
			{
				//output->setTexCoord((float*)(textures + (i * numTextures * 3)), numTextures, i);
				output->setTexCoord(textures + (i * numTextures), numTextures, i);
			}

		}

which leads me to believe that it’s trying to copy N number of uv sets depending on what the input has, though this seems to not be working:

It only copies one uv set, but interestingly it makes all the new data point attributes not vertex attributes.

I feel that this may be a related issue, but not sure. Including it as it’s reproducible with the included sample code.

There is a few things happening here. The first is that the C++ SOP only knows about point attributes, it can’t interact with vertex attributes (or create them). It’s a limitation right now we did for simplicity, but likely needs to be upgraded.

With the non-VBO workflow though there is a bug and multiple texture don’t work right now, I’ll fix that today.

To make use of them in the future you would create an array of TexCoord structs to pass in for each point.

std::array<TD::TexCoord, 2> tcs;
tcs[0].u = 0.5;
tcs[0].v = 0.5;
tcs[0].w = 0.5;
tcs[1].u = 1.5;
tcs[1].v = 1.5;
tcs[1].w = 1.5;

output->setTexCoord(tcs.data(), 2, i);

Good to know! Thanks for the x++ snippet. Still figuring things out, been cherry picking some useful bits off the derivative GitHub repos as well.

Does this mean that the VBO direct GPU method of adding data does work with multiple UV sets and all the other types just fine?

If so I might look into making use of that since assimp seems to do a lot of post processing of the mesh in a way that makes it ideal for real-time.

Is the big deal about the VBO method that it saves cpu time downstream when the render top uploads geometry data by not having to process cpu SOP stuff as extensively?

Ya, the VBO method works. Yeah, the VBO method has it in the form the GPU can just read and render as-is. The non-VBO form is setup in an old format that SOPs can use to do extra processing, but it needs to be converted to a GPU friendly form at render time.

Super interesting! Is there any reason why I shouldn’t just make a whole separate c++ sop that takes an input and converts it to a vbo sop and use that as a last sop in the chain for all renderables?

Either way will def work to implement this in my assimp plugin as I can see myself bringing in heavier geometry to build our static parts of scenes.

If you already have your data in SOP format, then you’re better off letting me handle the conversion to VBO in the SOP you are rendering than doing it yourself. I’ll be able to do it faster (and it’ll be multi-threaded)

Ah, so the results of the automatic conversation to VBO are cached in some way ie they don’t happen every frame? I had thought it incurred a per frame extra cost because it wasn’t in that format

Only if the SOP is cooking. It’s not converted on the fly for every render. If the SOP cooks less than 3 times (we assume it means it’s static), then the data will actually live and stay on the GPU. Otherwise it uses streaming buffers for changing SOP data

1 Like

Amazing I would not have guessed it worked that way. Is that 3 times over a period of time? What about typical network usage and doing things that cause the sop to cook a 4th time, is it no longer cached from that point onwards until the sop data itself changes in some other way?

It’ll always be cached, but it’ll be cached in a streaming buffer, which may or may not be on the GPU, depending on what driver decides to.

1 Like