Coder Social home page Coder Social logo

iblbaker's Introduction

IBLBaker

IblBakerCover

IblBakerCover1

IblBakerCover1

About

IBLBaker is provided under the MIT License(MIT) Copyright(c) 2015 Matt Davidson. Please see the LICENSE file for full details.

Feel free to contact me with questions, corrections or ideas. https://github.com/derkreature/ http://www.derkreature.com/

This project makes heavy use of subprojects. Downloading the .zip from github is an insufficient method for acquiring the source for all dependencies. Please checkout the repository through git in order to acquire all required dependencies.

Building

1.) Run "IblBaker.bat" in the source root directory. This will run CMake and automatically setup all dependencies.
    IblBaker.bat automatically configures for Visual Studio 2015 x64 and builds with the community edition. 
    You should not need to change any of the CMake config options.
2.) The output of IblBaker.bat is "Build64" in the root directory. 
3.) Open Build64/IblBaker.sln 
4.) Set startup project to IBLBaker. There is no elegant way to do this in CMake.
5.) Build and run.

What on earth is this?

The IBLBaker grew out of a quick implementation of the Siggraph Unreal presentations on Physically Based Rendering that I put together for a presentation on OpenSubDiv during late 2013.

The main reason that it is here is to provide a concise example of all the parts required to realtime evaluate light probes for physically based rendering.

While this is not a complete implementation of the required rendering pipeline (I have omitted cavity, bloom, reflection occlusion and realtime ambient occlusion and IBL shadowing (Kreature does these, but I felt that they detracted from the core exercise), it should serve anyone looking to implement dynamic probes in good stead. (If it doesn't, email me, and I will rectify the problem).

At the very least it can be used for baking diffuse irradiance and specular pre-convolved environment cubemaps evaluated over roughness over mips computed using a user specified brdf.

Still Reading?

The baker uses importance sampling to evaluate the environment maps and visualize the results using the separable method proposed by Epic Games at Siggraph 2013.

The tool allows the user to save the computed environment maps and the BRDF Lut to disk for use in other pipelines.

I have provided example cgfx shaders for maya viewport 2.0 in the /maya directory with 2 example scenes in .ma format.

Please review the example maya workflow video at: https://vimeo.com/110805546

The full purpose of this tool can be found in the following videos: https://vimeo.com/100285383 https://vimeo.com/96235208

A Special thanks must be given to Munkyfun (www.munkyfun.com) who sponsored much of the work in preparing this work for an open source release. Thank you so very much guys!

Thank you also to www.gametextures.com for allowing the use and publication of their "Brown Brick" PBR texture set. I will be releasing this set along with a revised shader ball in the near future.

Codebase notes:

I'm not a huge fan of git subprojects, and I'm also not a fan of having to track down all of the dependencies for a project in order for it to build. I recently reenabled AssImp and FreeImage in the default build. For these reasons the repository has grown by a couple of hundred mb.

This codebase is based on an old version (circa 2009) of my personal research framework. It was developed more as an exercise to learn new techniques, so parts of it are fundamentally flawed. One particular area is the use of abstract base types for render API abstraction. This is clearly a bad idea, and will go away before I release. Mainly, I don't want anyone to ever think that this is a good idea.

If a class has an "I" in front of it, or D3D11 at the end, please hold your nose and ignore for the moment :).

I am holding off on pulling from my current framework(Kreature) until I have implemented Vulkan.

Suggested prior reading:

http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf

http://seblagarde.wordpress.com/2011/08/17/hello-world/

http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf

https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf

http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html

http://blog.selfshadow.com/publications/s2013-shading-course/pixar/s2013_pbs_pixar_notes.pdf

http://blog.selfshadow.com/publications/s2013-shading-course/hoffman/s2013_pbs_physics_math_notes.pdf

http://blog.selfshadow.com/publications/s2012-shading-course/gotanda/s2012_pbs_beyond_blinn_slides_v3.pdf

http://www.pbrt.org/

Similar projects

Known Leaks:

  • D3D11Effects has some serious issues. I will be replacing this in the near future in any case. (Post D3D12/Vulkan in Kreature).
  • Shutdown leaks abound after the latest GUI port. I've been in a bit of a hurry, so, uhhh, please forgive.
  • AssImp is leaky.

What about linux / osx / iris / bsd / ios / nextstep / rasberry pi / abacus support?

The rendering layer is platform agnostic in principle. For the moment only the D3D11 layer has been implemented. The application layer started out with the best intentions of being agnostic. It unfortunately now requires some work to port from Windows to other platforms. I am working on an OpenGL 4.0 implementation for OSX and Linux at the moment.

How do you use it?

The application config file is an xml document that can be found in: data/iblBakerConfig.xml

Upon starting you should see a pistol surrounded by the input probe environment mapped to sphere.

Controls:

Mouse move will orbit the camera.

Left Control key down + mouse move will rotate the visualized object.

W and S keys zoom the camera in and out from the origin.

Mouse scroll zooms the camera in and out from the origin.

Buttons

"Load Environment" Button New maps can be set by click on the "Import Environment" button. Valid input environments are .dds by default. It is probably better that they are setup as RGBA16F or RGBA32F. Maps can be Lat / Long / equirectangular and cubemap layouts.

While only the DDS codec is enabled by default, it is possible to enable the FreeImage code by adding a project define "#if IBL_USE_ASS_IMP_AND_FREEIMAGE = 1". You will have to provide your own builds of FreeImage and AssImp. The reference codec based on Ogre is in src/codecs/IBLFreeImage.cpp/IBLFreeImage.h. Prior warning if you are building static libraries, both AssImp and FreeImage depend on Zlib.

LDR inputs will also work, however, will not light well. Additional sample environment maps are available in IBLBaker/data/sampleMaps/

Environments can be saved by clicking on the "Save Environment" button. You must specify a .dds filename to export to. A number of files will be saved using the specified .dds filename. I recommend installing the nvidia photoshop dds plugin to view the mips of the saved cube maps.

"Compute" Button The compute button forces invalidation of the IBLProbe and causes the probe to be resampled.

"Cancel" Button The cancel button forces the IBLProbe to be marked valid and no further computation will take place until either a dependency to the probe is altered or "Compute" is clicked on.

Tweak Parameters

Exposure: Exposure parameters for tone mapping.

Gamma: Output gamma for color correction.

Input Gamma: The color space of the input environment map. 1.0 for linear.

Debug Visualization:

No Debug: Renders the object lit. Normal: World space normals. Ambient Occlusion: The blue channel from the RMAOC specular map that contains the ambient occlusion. Albedo: The albedo map for the object. IBL Diffuse: The diffuse irradiance contribution from the environment. IBL Specular: The environment map value sample using reflection vector and the mip layer using the roughness value in the specular map. Metal: The green channel from the RMAOC specular map. Roughness: The red channel from the RMAOC specular map. BRDF: The computed bias/scale terms from the BRDF Lut using ndotv and roughness.

Specular Workflow: Inverts roughness and/or metalness terms for the visualized object.

Specular Intensity:A multiplier to the material specular term for the visualized object.

Roughness Gloss Scale: An inverse multiplier to the roughness term for the visualized object.

BRDF: The brdf that is current being used to evaluate the IBLProbe and render the object. BRDFs can be found in data/shadersD3D11 in .brdf files. These files are hlsl that are concatenated with the core shaders IblImportanceSamplingDiffuse.hlsl, IblImportanceSamplingSpecular.hlsl and IblBrdf.hlsl. You can create new .brdf files to experiment. .brdf files are loaded on application startup and are enumerated automatically.

The generated BRDF lut is displayed in the top right hand corner of the applciation

You may edit shaders while the application is running and they will be automatically reloaded. There is no runtime guard around shader failure. If you write an invalid shader the application will crash. Failures are written data/ShadersD3D11/ShaderFailures with the error and warning list at the end of the file.

Diffuse Resolution: The per face dimensions of the diffuse cube map.

Specular Resolution: The per face dimensions of the specular cube map. A full mip chain will be created for the cubemap.

Mip Drop: The number of mips above the 1x1 face in the specular cube map to ignore when computing roughness convolutions.

Total Samples: The number of samples to use per pixel when importance sampling.

Samples per frame: The number of samples that are computed per update of the IBL Probe. If the samples per frame != total samples, the IBL Probe will be progressively sampled. This functionality is still experimental and has some bugs. For the moment, please ensure that the total samples / number of samples per frame is a positive whole number.

Environment Scale: A scale term applied to every sample when importance sampling.

IBL Saturation: A saturation term applied to every sample when importance sampling.

IBL Contrast: Incomplete. A contrast term applied to every sample when importance sampling. I still need to write some code to make this work correctly.

IBL Hue: A hue term applied to every sample when importance sampling.

Max R/G/B: A debug attribute that displays the maximum pixel value in the input environment image.

How does the tool work (a broad overview)?

The quick overview. This is basically a complete implementation of the technique outlined by Epic in: http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf

1.) Starting at Application::updateApplciation() in Application.cpp. _scene->update() is called which updates all of the IBLProbes and BRDFs. At this stage the BRDF lut is computed in Brdf::compute() using the compute shader in data/shaders/IBLBRDF.hlsl which is concatenated with the current .brdf file (which can be found in data/shaders/).

2.) At line 410 of Application::updateApplication in Application.cpp the IBLProbe is computed. The core of this operation can be found in IBLRenderPass::render()

 The IBLRenderPass computes the IBL (if it is not cached):

 - Projects the sphere geometry of the scene to a 2048x2048 cubemap using the geometry shader that we will nominate the "environment source". It would also be possible to render a scene using this technique to an environment map. The shader for this operation can be found under: data/ShadersD3D11/IBLEnvironmentSphereSpherical.fx.
 - Mip maps are generated for the environment source.
 - The diffuse irradiance environment map is computed by projecting a sphere using a geometry shader over the diffuse irradiance environment map and importance sampling per pixel using the source environment with the shader data/ShadersD3D11/IBLImportanceSamplingDiffuse.fx concatenated with the current .brdf file.
 - The specular environment map is computed by rendering to each mip of an environment map with an associated roughness term by projecting a sphere using a geometry shader over the specular environment map mip level and importance sampling per pixel using the source environment with the shader data/ShadersD3D11/IBLImportanceSamplingSpecular.fx concatenated with the current .brdf file.
 The ColorPass is then rendered using IblColorPass.cpp:
 - The pistol is rendered using the shader IblPBRDebug.fx . The inputs to this shader are the diffuse irradiance environment map, the specular roughness environment map, the brdf LUT, the object albedo map, the specular map and a normal map.

How does the tool work (a more detailed overview)?

1.) Computing the BRDF LUT:

IBlBaker/data/shadersD3D11/IBLBrdf.hlsl
For each pixel (x, y) in the target LUT:
   Compute roughness (0 to 1.0) based on pixel x coordinate.
   Compute normal dot view (NoV) (0 to 1.0) based on pixel y coordinate.
   Set normal as float3(0,0,1).  
   Set view as float3(sqrt(1.0-NoV*NoV), 0, NoV);
   Compute roughness squared (k==r2==r*r)
   Integrate number of importance samples for (roughness and NoV).
   For each sample:
        Compute a Hammersely coordinate.
        Convert Hammersley to world space coordinate based on roughness.
        Compute reflection vector L
        Compute NoL (normal dot light), NoH (normal dot half), VoH (view dot half)
        If NoL > 0
          Sample contributes.
          The following functions are implemented in the .brdf file.
          Compute the geometry term for the BRDF given roughness squared, NoV, NoL
          Compute the visibility term given G, VoH, NoH, NoV, NoL
          Compute the fresnel term given VoH.
          Sum the result given fresnel, geoemtry, visibility.
   Average result over number of samples.

2.) Computing the diffuse irradiance environment:

IBlBaker/data/shadersD3D11/IBLImportanceSamplingDiffuse.fx
Given a sphere mesh input centered at the world origin.
Vertex shader:
Transform vertex position to the world.
Transform normal to world.

Geometry shader:
Transform the world position to 6 faces of a cubemap.

Pixel Shader:
For each pixel:
    Set View (V) = Normal (N).
    Compute the sample step as MaxSamples / SampleCountPerFrame.
    sampleStartId = sample offset (current offset in all samples).
    For (0 through to SampleCountPerFrame)
        Compute a Hammersley coordinate given the current sampleId
        H = Convert the Hammersely coordinate to a world coordinate H.
        L = reflection vector V, H
        NoL = Normal dot Light
        If the sample contributes.
        if (NoL > 0)
            The following functions are implemented in the .brdf file.
            pdf = evaluate the probability density function
            Mip map (lod) = compute the mip map using the solid angle, source map size, distortion and the pdf.
            Sample = Cubemap sample at coordinate H and mip map level lod.
            Sum the Sample to Result.xyz and Sum weight to Result.w.     
        Increment the sampleId by the by the sample step.

    Result = Divide Result.xyz by accumulated weight in Result.w.
    OutputResult = interpolate the last result to the current result by 1.0 / ConvolutionSamplesOffset)

3.) Computing the specular irradiance environment:

IBlBaker/data/shadersD3D11/IBLImportanceSamplingSpecular.fx
Given a sphere mesh input centered at the world origin and a mip map target that will be sampled using Roughness (0 to 1.0 over all mips, where mip=0 represents roughness 0 and mip = (NumMips-1) = 1.0.

Vertex shader:
Transform vertex position to the world.
Transform normal to world.

Geometry shader:
Transform the world position to 6 faces of a cubemap.

Pixel Shader:
For each pixel:
    Set View (R) = Normal (R) = R = world vertex normal.
    Compute the sample step as MaxSamples / SampleCountPerFrame.
    sampleStartId = sample offset (current offset in all samples).
    For (0 through to SampleCountPerFrame)
        Compute a Hammersley coordinate given the current sampleId
        H = Convert the Hammersely coordinate to a world coordinate H given Roughness.
        L = reflection vector V, H
        NoL = Normal dot Light
        VoL = Normal dot View
       
        If the sample contributes.
        if (NoL > 0)
            The following functions are implemented in the .brdf file.
            pdf = evaluate the probability density function give NoL, VoL and Roughness
            Mip map (lod) = compute the mip map using the solid angle, source map size, distortion and the pdf.
            Sample = Cubemap sample at coordinate L and mip map level lod.
            Sum the Sample to Result.xyz and Sum weight to Result.w.     
        Increment the sampleId by the by the sample step.

    Result = Divide Result.xyz by accumulated weight in Result.w.
OutputResult = interpolate the last result to the current result by 1.0 / ConvolutionSamplesOffset)

What would you like my input on?

So, this is left over documentation from the review release of the baker. I am still very, very interested in finding out where/if my math is incorrect. Please contact me through github (https://github.com/derkreature/). if you have any ideas or opinions. 1.) The math that is used in computing the IBL Probe. These files are:

 IBLBrdf.fx

 IBLImportanceSamplingDiffuse.fx

 IBLImportanceSamplingSpecular.fx

 schlick.brdf

 smith.brdf

 I will be writing more about the math in here, and will be relying on 
 questions from you in preparing a future invitation to other individuals 
 that I do not have a close working relationship within the industry.

2.) The math for shading the object: IBLPBRDebug.fx

3.) The validity of my method for progressive sampling using importance sampling and where I have gone wrong (if possible).

Am I taking contributions? Yes, please. I would be happy to merge any changes you suggest into the release if they do not conflict with your employment situation and will not endanger the project's ability to be released publicly.

How far away am I from a public release? This depends on whether my math is bunk or not. I still need to fix some memory leaks and perform one final pass on the codebase so that it is clean/er. I hope to have the library available to the general public by the end of August / start of September.

Please email me if you have any questions.

IBLBaker depends upon the following libraries

I recently moved all of my dependencies to a static library "critter". Critter is still provided under the MIT license. The motivation for this was to have a central library that I could use as a subproject for maintaining multiple public tools and experiments. Please see: https://github.com/derkreature/critter

IBLBaker uses the following resources

Cerberus by Andrew Maximov

Thank you to Andrew Maximov for the use of his pistol asset: http://artisaverb.info/

HDR Probes by HDRLabs

IBLs form HDRLabs are used under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 License. http://www.hdrlabs.com/sibl/index.html

Cupcake icon:

from: http://www.flaticon.com/free-icon/cupcake-sugar_12348

Icon made by Freepik from www.flaticon.com
The author of this icon will be grateful if you use the following legal attribution "Icon made by Freepik from Flaticon.com"

iblbaker's People

Contributors

abwood avatar derkreature avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iblbaker's Issues

A quick way to expose cube map images in jpeg format?

Thank you for this awesome tool.

Notice that the current git contains a built exe which exports the images (BRDF, diffuse, specular) in dds compact format. However, Is there a way to expose them separately in jpg format? Or is there any tool you have in mind which can convert the generated dds to separated jpg format?

Thank you.

IBLBaker returns .dds with negative float values

I have a .hdr file that when run through IBLBaker produces an output image containing negative values. For the image I tried, this is specifically only in the green channel. These negative values result in artifacts when I go on to BC6H-compress the images IBLBaker produces (bright green splotches in this case). I assume it's not expected that any of IBLBaker's output images should contain negative values?

The source .hdr
The output specular HDR map containing negative values

The diffuse HDR map and EnvHDR map appear to be fine. I haven't looked at the MDR maps as I don't use them.

My settings:
IBLBaker settings

Let me know if there's any additional information I can provide.

Non consistent behavior of obtained texture

Hi there.

We plan to use your amazing tool in order to get the environments for our PBR WebGL developments, by means of BabylonJS.

The case is that, when using a DDS environment generated by your tool (from an HDR file), we experiment an inconsistent behavior between Chrome-Windows, which shows a nice scene; and Chrome-Android, what renders the geometries with PBR materials all in black (by the way, the scene is also shown perfect on FF-Windows, Safari-macOSX and Safari-iOS).

Of course, we've tried with different HDRs obtaining always the same result.

This way, we suspect some kind of DDS environment format error, as trying the same scene with an existent DDS (that is, not generated by us with the help of IBLBaker) we get the correct results on Chrome-Android.

Any tip on generating DDS files which are Chrome-Android compatible?

Thanks for your time.

Best regards.

OSX Support

I thought it could be useful to start an issue and track the progress here. I don't have access to Win/DX11 machine so can't wait for the OSX release.

How to bake texture maps for every mesh in my scene?

Hi,

How to bake texture maps for every mesh in my scene?

I would like to bake the textures programmatically. Is it possible?

If not possible, will you be able to suggest an open source/free library?

Thanks in advance.

Issue with sampling input radial or equirectangular map

Very nice tool Matt!

I just wanted to point out something I found. Not sure if you find this valuable.

When using a radial or equirectangular map the result did not look right as can be seen below:

image

After replacing the function texSpherical in IblEnvironmentSphereSpherical.fx and IblSinglePassSphericalEnvironment.fx with "proper" sampling code the results looked much better :)

float4 texSpherical(float3 dir, float lod)
{
	float3 normalizedDir = normalize(dir);

	float lon = atan2(-normalizedDir.z, normalizedDir.x);
	float lat = acos(normalizedDir.y);
	
	float2 radians = float2(1.0 / (3.141592 * 2.0), 1.0 / 3.141592);
	
	float2 uv = float2(lon, lat) * radians;
	
	return environmentMap.SampleLevel(anisotropicSampler, uv, lod);
}

image

Bake Env Map wont work

Issue is that if you don't specify at least ".dds" in the name while saving environment, it wont write on disk.

I would ask op if he could update the tool with export in different compressions algorithms like :

A8R8G8B8: (32 bits per pixel, A:8, R:8, G:8, B:8)
X8R8G8B8: (32 bits per pixel, A:x, R:8, G:8, B:8) <<< i'm looking for this one
DXT5: (compressed, interpolated nonpremultiplied alpha)

i'm following an hobby project and the only free solution in creating skyboxes along their irradiance map and cubemaps from panorama without using any other software, is IBLMaker. Other solution just dont work. The issue with that is exporting compression formats. Thank you.

vs2015

I finally have a Windows PC, which means I got the latest VS which is 2015. The precompiled libs with IBLBaker give VS2015 fits (in other words dozens of link errors in assimp etc) since the stdlib has diverged a bit. Have you thought of including the libraries as submodules or something so they can just be built as part of the solution, rather than distroing bins?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.