Light probe generation and BRDF authoring for physically based shading.

Overview

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"
Issues
  • vs2015

    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?

    opened by meshula 5
  • OSX Support

    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.

    opened by vorg 5
  • Non consistent behavior of obtained texture

    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.

    opened by vortice3D 4
  • Importance sample diffuse fix

    Importance sample diffuse fix

    Minor tweak.

    It looks like a line got accidentally deleted and the diffuse importance sampling shader was missing the check for NoL > 0.0. The saturate call above will clamp any negative values to 0.0, but following along with the implementation defined in Epic Game's Siggraph 2013 course notes, these samples (now at 0.0) should not contribute to the lighting.

    opened by abwood 2
  • Bake Env Map wont work

    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.

    opened by ranvids 0
  • How to bake texture maps for every mesh in my scene?

    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.

    opened by oschakravarthi 1
  • Issue with sampling input radial or equirectangular map

    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

    opened by remcohuijser 4
  • A quick way to expose cube map images in jpeg format?

    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.

    opened by PsycoTodd 3
Owner
MattD
MattD
Harsh Badwaik 1 Dec 19, 2021
Remote hacker probe - Threat Emulation and Red Teaming Framework, The Hacking Software for normal people.

The Remote Hacker Probe is a Threat Emulation and Red Teaming Framework built to be easy to use. The Remote Hacker Probe is Feature Rich! Including, K

Fahad 159 Aug 2, 2022
General purpose power controller, capable of driving soldering irons using different voltages and probe types.

All-purpose Power Micro Controller This general purpose power micro controller features: Wheatstone Bridge front-end New Texas Instruments INA823 inst

Tomasz Jastrzębski 27 Aug 4, 2022
OSA a is minisatellite/ space probe the size of a can designed to participate in the ESA CanSat 2021 competition 🛰️ 📡 .

Project OSA OSA a is minisatellite/ space probe the size of a can designed to participate in the ESA CanSat 2021 competition ??️ ?? . Our project is c

OSATeam 10 Jul 10, 2022
Decoding light morse code with a light dependent resistor and Arduino board

Morse decoder The project's idea is very simple, the Arduino program has the responsibility to upload the sensor's data to the USB serial port.

null 15 Mar 12, 2022
A Visual Studio extension that provides enhanced support for editing High Level Shading Language (HLSL) files

HLSL Tools for Visual Studio This extension is for Visual Studio 2017 / 2019. Go here for the Visual Studio Code extension. HLSL Tools is a Visual Stu

Tim Jones 404 Aug 3, 2022
ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages

ShaderConductor ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages. Features Converts HLSL to readable, usable and

Microsoft 1.5k Aug 8, 2022
Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WebGL2

Filament Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small a

Google 14.4k Aug 11, 2022
Physically-based GPU and CPU ray-tracer emerging on a surface

etx-tracer Physically-based GPU and CPU ray-tracer emerging on a surface. Features Vertex Connection and Merging algorithm (CPU and GPU); Full-spectra

Serhii Rieznik 226 Aug 9, 2022
Bollu learns physically based sound sythesis

Kavariance bollu learns digital audio synthesis from the blog at the bottom of the sea. the name is a pun on Kaveri, A wav/river goddess, and Covarian

Siddharth 8 Dec 29, 2021
Code accompanying our SIGGRAPH 2021 Technical Communications paper "Transition Motion Tensor: A Data-Driven Approach for Versatile and Controllable Agents in Physically Simulated Environments"

SIGGRAPH ASIA 2021 Technical Communications Transition Motion Tensor: A Data-Driven Framework for Versatile and Controllable Agents in Physically Simu

null 10 Apr 21, 2022
A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code

flutter-hadk A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code 1.Build by android-ndk-to

null 12 Jun 15, 2022
Stack-based texture generation tool written in C99!

Stack-based texture generation tool written in C99! Brought to you by @zaklaus and contributors Introduction zpl.texed is a cross-platform stack-based

zpl | pushing the boundaries of simplicity. 17 May 1, 2022
Windows 10 interface adjustment tool supports automatic switching of light and dark modes, automatic switching of themes and transparent setting of taskbar

win10_tools Windows 10 interface adjustment tool supports automatic switching of light and dark modes, automatic switching of themes and transparent s

Simon 1 Dec 3, 2021
Fast and Light-weight path smoothing methods for vehicles

path_smoother About Fast and Light-weight path smoothing methods for vehicles Denpendencies This project has been tested on Ubuntu 18.04. sudo apt-get

MingwangZhao 4 Dec 1, 2021
Baseline Arduino shield for temperature, humidity, soil moisture and ambient light

Introduction Green-Shield is an Arduino R3 shield for temperature, humidity, soil moisture and ambient light optimized for use in greenhouses where th

#Eduh 3 Dec 29, 2021
Simple and light C++ global keyboard/keybinding manager

Global key binding written in C++ // Style: // Hungarian Notation for variables, eg. float flFloatingPoint; int iInteger; string szString; // Member

Blanket 3 Aug 2, 2022
An 802.11 Frame Generation and Parsing Library in C

libwifi 802.11 Parsing / Generation library Build Status OS Architecture Linux x86_64 What is this? libwifi is a C library with a permissive license f

null 29 Aug 8, 2022
A model checker for the Dynamic Logic of Propositional Assignments (DL-PA) with solving and parameterized random formula generation functionalities.

A model checker for the Dynamic Logic of Propositional Assignments (DL-PA) with solving and parameterized random formula generation functionalities.

Jeffrey Yang 7 Dec 31, 2021