![]() Note that none of the APIs generate lighting, but they only give you a very flexible way of fast ray-primitive intersection on the GPU, and there are potentially lots of different ways to (ab)use it. Although you can write a completely custom ray-tracing implementation using bare DirectX/WebGL/Vulkan/Whatever, there are already very efficient APIs to do that, such as OptiX, RadeonRays and DXR. They have a lot of similarities, so knowing one should give you an idea of how to operate the other: you define surfaces, build an acceleration structure and intersect rays against it. To generate more sophisticated lighting, with area shadows, sky occlusion, colored light bounces, etc, we’ll have to trace some rays. There are still many imperfections, but it’s much better. Hereis one from Pla圜anvas, in GLSL: varying vec2 vUv0 Ĭ = c.a>0.0? c : texture2D(source, vUv0 - pixelOffset) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + vec2(0, -pixelOffset.y)) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + vec2(pixelOffset.x, -pixelOffset.y)) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + vec2(-pixelOffset.x, 0)) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + vec2(pixelOffset.x, 0)) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + vec2(-pixelOffset.x, pixelOffset.y)) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + vec2(0, pixelOffset.y)) Ĭ = c.a>0.0? c : texture2D(source, vUv0 + pixelOffset) įor every empty background pixel, it simply looks at 8 neighbours around it and copies the first non-empty value value it finds. So let’s try to process our lightmap with a very simple dilation shader. ![]() But if you ever worked with any baking software you know about padding, and how they expand or dilate pixels around to cover the background. That was easy, now let’s try to apply this texture:īecause of the bilinear interpolation and typical non-conservative rasterization, our texels now blend into background color. Note that “*2-1” is necessary to transform from typical UV space into typical clip space. You just output UVs straight on the screen: OUT.Position = float4(IN.LightmapUV * 2 - 1, 0, 1) You want to bake this lighting, how do you that? Instead of outputting transformed vertex position OUT.Position = mul(IN.Position, MVP) Let’s say, you have a simple lighting shader, and a mesh with lightmap UVs: All of them had one thing in common – something had to be rasterized in UV space. First one simply rasterized forward lights in UV space, 2ndgenerated UV surface position and normal and then rendered the scene from every texel to get GI (huge batches with instancing), 3rd was Pla圜anvas’ runtime lightmapper, which is actually very similar to 1st. We will start with picture on the left and will make it look like the one on the right:īakery is in fact a 4th lightmapper I designed. This blog post won’t cover lighting computation much, but will instead focus on what it takes to produce a high quality lightmap. The major focus of this project was to minimize any kinds of artifacts lightmapping often produces, like seams and leaks, and also make it flexible and fast. ![]() ![]() I also thought of open-sourcing it at the time, but having spent almost more than a year of work and coding it full-time now, I think it’s fair to delay it a bit. In my old tweetI promised to write about how it works, as there were many, MANY unexpected problems on the way, and I think such write-up would be useful. Originally intended for my own game, I decided to make it a product by itself and hopefully help other people bake nice lighting. It’s finally done, and you can even buy it on Unity’s Asset Store (it can be used outside of Unity as well, but the demand is higher there). Since 2015 I was working on a GPU lightmapper called Bakery. ![]()
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |