Advertisement
Guest User

Issue

a guest
Jul 16th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.93 KB | None | 0 0
  1. For a long time developers have wanted 3D textures for shaders, more bit depth, or values below 0 or over 1 in their textures.
  2.  
  3. There isn't a portable file type that's a drop in solution for this type of problem, but for shader applications we don't always need portable image types. We're expecting very specific data hopefully, we know the resolution, we know the bit depth, and everything is expected in many use cases. To name a few: baking the sky using a combination of 2D and 3D luts, 3D color grading luts (some file types exist for this technically), bre-baked 1D binary trees to accelerate Ray tracing, and even clouds, both for the noise and lighting. This is just barely scratching the surface for what's possible to pre-bake I'm sure people will get creative with it as well.
  4.  
  5. The solution however is pretty simple and elegant, it does requires a bit of extra information when loading the file such as the value format, resolution, along with the file location though.
  6.  
  7. The file is a direct pixel dump from opengl. Identical a classic C array of values, no separation, no terminators, just the values bits stacked next to each other. Each value is a configurable type, which are then repeated to represent pixels, pixels are then repeated into colums or slices if needed, however it's all stacked in a single dimensional array, then saved to disk.
  8.  
  9. The file can support any combination of what glTexImage#D can support.
  10.  
  11. Formats:
  12. GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL...
  13.  
  14. and types
  15. GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT...
  16.  
  17. I have supplied functions for both the saving and loading in cpp and modern opengl adapting to other languages and older versions of opengl should be clean and easy as well, just with the additional step that 3D texturing must be enabled.
  18.  
  19. Loading such data is extremely trivial, and generating is just as so, the only thing you lose is the ease of manipulation of the file in the progress and you must know the data type stored, and the dimensions of the image otherwise the reconstruction will fail.
  20.  
  21. Here's the C++ code for loading the example lut, which is a 3D lut consisting of 64x64x64 RGBA32F values (easily converted to Java)
  22.  
  23. std::vector read_file(const std::string &path, size_t size)
  24. std::ifstream file(path, std::ios::binary);
  25. if(!file.good()) {
  26. return {};
  27. }
  28.  
  29. std::vector<float> buf(size);
  30. file.read(reinterpret_cast<char *>(buf.data()), size * sizeof(float));
  31. file.close();
  32.  
  33. return buf;
  34. }
  35.  
  36. //Then taking that lut and passing it to opengl as follows
  37. glEnable(GL_TEXTURE_3D);
  38. auto lut_data = read_file_as_float_vec(SHADER_SOURCE_DIR "/inversion_lut.dat", 64 * 64 * 64);
  39.  
  40. glActiveTexture(GL_TEXTURE0);
  41. glCreateTextures(GL_TEXTURE_3D, 1, &lut_texture_id);
  42. glBindTexture(GL_TEXTURE_3D, lut_texture_id);
  43. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  44. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  45. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  46. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  47. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
  48. glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 64, 64, 64, 0, GL_RGBA, GL_FLOAT, lut_data.data());
  49.  
  50. lut_uniform_id = glGetUniformLocation(program_id, "inversionLut");
  51.  
  52. //Then in the render loop
  53. glBindTexture(GL_TEXTURE_3D, lut_texture_id);
  54. glUniform1i(lut_uniform_id, 0);
  55. `
  56. inversion_lut.zip
  57.  
  58. To test it simply use the normalized fragment color [0-1] as coordinates to lookup the 3D lut, it should perform a 1.0- on the color, mapping 0,0,0 to 1,1,1 or 0.25 to 0.75.
  59.  
  60. in vec2 texcoord;
  61.  
  62. uniform sampler2D colortex0;
  63. uniform sampler3D inversion lut;
  64.  
  65. void main() {
  66. vec3 colorCoord = texture(colortex0, texcoord);
  67. fragColor = texture(inversion lut, colorCoord.xyz);
  68. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement