Help: Information on Cycles Bake code

Hey everybody, I just built Blender for my first time and I’m looking for a first project. I think I’d like to work on adding support for baking to vertex colors for Cycles, since it was possible with Blender Render in 2.79, but is no longer possible in 2.8.

I’m having trouble finding information on Cycles bake code. I’ve looked through the information on the project page at developer.blender.org and can’t find anything on baking. I’ve been trying to figure out bake.h and bake.cpp, and I’m not sure what I’m looking at.

If I understand correctly, the code sets up the bake operation by figuring out which pixel (in the output image) belongs to each triangle of the object (it looks like Blender and Cycles are talking back and forth at this point- Blender sets the bake data and the properties of the Bake Manager in blender_session.cpp). Some information is saved about the surface of the object at that point on its surface (I think BakeData.data is the primitive and the uv’s, and BakeData.differentials is the tangent and bitangent of that point? I’m not formally educated in higher math, but eager to learn more) Then, it runs a rendering task for each pixel for the number of samples that Blender requests. This is saved to d_output, which is then copied into result, which looks is an array of floats that are each one channel of a pixel (so the data looks like r,g,b,a,r,g,b,a,r,g,b,a,r,g,b,a in the result).

What confuses me is that I don’t see anything use result. It isn’t a pointer or a reference, so it’s being passed by value, isn’t it? And I don’t see it being returned or referenced anywhere… so how does the result get out of the function? How does Blender get ahold of it?

What I want to do is bake to vertex colors, so I think it should be possible to bake only the pixels at the corners of each triangle, and use the result as a vertex color for the associated vertex-face-corner (loop is what it’s called in mesh Python API).

Am I far off the mark in my understanding of this piece of code? Any advice on finding more info? And most importantly, is this too hard for a first project?
Thanks!

For vertex color baking, the main work would be on the Blender side, in object_bake.c and object_bake_api.c.

You’re right about the approach to doing this. Rather than setting the face index + barycentric uv coordinates corresponding to a pixel, you’d set them for a vertex. So that means a face index + barycentric uv corresponding to the corner of a face where the vertex is.

Regarding the Cycles side, BakeManager::bake has a result parameter, that’s where the output gets written to. But I think vertex color baking may not require any code changes in Cycles at all.

2 Likes

Thanks for the reply! I’ve been looking through the files you mentioned, and I think it will take me a few days to read them and still a few more to understand.

I was confused by result because I thought it was being passed-by-value, but it looks like Blender is giving it a NULL*, so I suppose Cycles is writing the pixels directly to the memory? I think I can figure it out, but it looks like I probably don’t have to in order to do what I want. It will take a while to learn, though.

Thanks again.

1 Like

So I’ve done some poking around, and I think the I can add vertex baking without modifying Cycles at all, as @brecht said. In fact, I think I only need to touch two functions in two source files.

This is my reading of the code, please correct me if I have it wrong somehow:
Cycles recieves an empty list of pixels and a list of pixel-data for rendering. It renders the pixel data to pixels and puts them in the pixel array. At this point, the pixel array is not an image, it’s just a list of pixels that can be made into an image. Blender then receives the pixel array and puts them in an image, and does the cleanup work needed after the bake is finished.

The crucial part of the code for vertex baking is in /source/blender/editors/object/object_bake_api.c, specifically the function aptly named bake. First, the size of the pixel array is set by num_pixels. So I would have to add a bit of code to set the number of pixels to the number of face-corners (or loops I think they’re called) if the bake is going to vertex colors. Once the number of pixels in the array is equal to the number of loops, each BakePixel must have its data set up. So I would have to modify RE_bake_pixels_populate() (in source/blender/render/intern/source/bake_api.c), or write a new, similar function, that create bake data for the loops directly. This should be easy to do, since there wouldn’t have to be any kind of interpolation across the face to find a pixel data value at a specific UV-coordinate. Perhaps I can even re-use the existing code to do this.

Finally, I will need to modify the image saving section at around line 1130 in object_bake_api.c to save the pixel for each loop into vertex color for each loop. This doesn’t seem like it should be very tricky.

Note that none of this takes high-poly/low-poly workflow into account just yet. I want to solve the easier problem first. A couple of other difficulties I foresee are: pixel data may not be normalized and I think vertex colors expect normalized data. Also, vertex colors currently have color space hard-coded into the material node that accesses them. This is not ideal for baking data passes like normals, etc. . That’s a separate issue that I’d really like to fix. I think I can talk to OmarSquircleArt about that since he’s the one that made the new vertex color node (excellent addition). Finally, it’s possible that loops sharing a vertex can have different RGB values from the bake- much like when neighboring pixels in an ordinary bake have different values due to noise or fireflies. This will need to be addressed- since it will look really ugly in vertex colors. I think I can average the pixel value for each loop that shares a vertex. Either that, or I can merely bake one pixel per vertex and find a way to associate them to the loops later on.

Does this sound like a reasonable way to tackle the problem?

1 Like