knightcrawler25 / GLSL-PathTracer

A toy physically based GPU path tracer (C++/OpenGL/GLSL)
MIT License
1.87k stars 176 forks source link

Crash with Normal Texture #52

Closed pcarret closed 3 years ago

pcarret commented 3 years ago

I am trying to imporve woo rendering with normal map texture to see wood grain but I have an issue (image) when loading this asset.zip :

To see the crash you need to modify ST-CL3-009-00.scene // without crash line 47 : normalTexture ST-CL3-009-00\images\wood_normal_grey.xxx.png // with crash line 47 : normalTexture ST-CL3-009-00\images\wood_normal_grey.png

Is there any known limitation regarding texture size, or POT/NPOT, or format (png vs jpeg) ?

image

assets.zip

knightcrawler25 commented 3 years ago

There is a limitation with the texture sizes. All textures are stored in a 2D array to make it easy to sample and so they need to have the same dimensions. I haven't gotten around to removing this restriction yet.

pcarret commented 3 years ago

The texture is 1024x1024 and is taken from asset repo and grayed. So this is probably not the reason of crash. image

knightcrawler25 commented 3 years ago

What I meant by same dimensions is that all textures that you use should have the same dimensions. The normal textures were 1024x1024 but diffuse textures were 512x512. Changing all of them to be the same size should work.

image

img_73

But then again, texturing is not something that I have focused on yet, so you'll see issues with normal maps where looking at it from grazing angles will show up as dark spots. This is due to the surface normal going below the actual surface.

img_38

pcarret commented 3 years ago

Your explanation are clear and make sense. Many Thx Do you plan to work on texturing ?

Juts FYI : In glsl-pathtracer\src\core\Mesh.cpp I was forced to modify some check and variable initialization to avoid some crashes with some obj files :


              for (size_t v = 0; v < fv; v++)
                {
                    // access to vertex
                    tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
                    tinyobj::real_t vx = attrib.vertices[3 * idx.vertex_index + 0];
                    tinyobj::real_t vy = attrib.vertices[3 * idx.vertex_index + 1];
                    tinyobj::real_t vz = attrib.vertices[3 * idx.vertex_index + 2];
                    tinyobj::real_t nx = 0;
                    tinyobj::real_t ny = 0; 
                    tinyobj::real_t nz = 1;
                    if (idx.normal_index > -1)
                    {
                        nx = attrib.normals[3 * idx.normal_index + 0];
                        ny = attrib.normals[3 * idx.normal_index + 1];
                        nz = attrib.normals[3 * idx.normal_index + 2];
                    }

                    // default initialization
                    tinyobj::real_t tx = 0, ty = 0;

                    // temporary fix
                    if (!attrib.texcoords.empty() && idx.texcoord_index > -1)
                    {
                        tx = attrib.texcoords[2 * idx.texcoord_index + 0];
                        ty = attrib.texcoords[2 * idx.texcoord_index + 1];
                    }

                    verticesUVX.push_back(Vec4(vx, vy, vz, tx));
                    normalsUVY.push_back(Vec4(nx, ny, nz, ty));
                }
knightcrawler25 commented 3 years ago

Yes I do have it in my to do list but have been putting it off since I can't seem to find a simple way to add textures of varying sizes. It's either texture atlases, bindless textures with a driver extension or resizing of all textures to the same dimension once they've been loaded.

For obj files that are missing normals/textures, I'll add your fix in to avoid crashes