From 914b50d7238fc4a30f23fc2a4ea570e467f4ab75 Mon Sep 17 00:00:00 2001 From: Criss Date: Mon, 17 Jun 2019 01:04:45 +0200 Subject: [PATCH] BRDF explorer app: Some progress on generating shaders --- .../13.BRDF_Explorer/BRDFExplorerApp.cpp | 70 ++++++++------- .../CBRDFBuiltinIncludeLoader.h | 86 +++++++++++++++++-- examples_tests/13.BRDF_Explorer/main.cpp | 7 ++ 3 files changed, 127 insertions(+), 36 deletions(-) diff --git a/examples_tests/13.BRDF_Explorer/BRDFExplorerApp.cpp b/examples_tests/13.BRDF_Explorer/BRDFExplorerApp.cpp index b5a15f9fa..5d1aafd0f 100644 --- a/examples_tests/13.BRDF_Explorer/BRDFExplorerApp.cpp +++ b/examples_tests/13.BRDF_Explorer/BRDFExplorerApp.cpp @@ -142,7 +142,7 @@ class CShaderManager video::E_MATERIAL_TYPE addShader(const SParams& _params) { std::string source = -R"(#version 430 core + R"(#version 430 core layout (location = 0) out vec4 OutColor; @@ -150,30 +150,40 @@ in vec3 WorldPos; in vec2 TexCoords; in vec3 Normal; -layout (location = 0) uniform vec3 uEmissive; -layout (location = 1) uniform vec3 uAlbedo; -layout (location = 2) uniform float uRoughness1; -layout (location = 3) uniform float uRoughness2; -layout (location = 4) uniform float uIoR; -layout (location = 5) uniform float uMetallic; -layout (location = 6) uniform float uHeightFactor; -layout (location = 7) uniform vec3 uLightColor; -layout (location = 8) uniform vec3 uLightPos; -layout (location = 9) uniform sampler2D uAlbedoMap; -layout (location = 10) uniform sampler2D uRoughnessMap; -layout (location = 11) uniform sampler2D uIoRMap; -layout (location = 12) uniform sampler2D uMetallicMap; -layout (location = 13) uniform sampler2D uBumpMap; -layout (location = 14) uniform sampler2D uAOMap; +layout (location = 0) uniform vec3 uEmissive; +layout (location = 1) uniform vec3 uAlbedo; +layout (location = 2) uniform float uRoughness1; +layout (location = 3) uniform float uRoughness2; +layout (location = 4) uniform float uIoR; +layout (location = 5) uniform float uMetallic; +layout (location = 6) uniform float uHeightFactor; +layout (location = 7) uniform vec3 uLightColor; +layout (location = 8) uniform vec3 uLightPos; +layout (binding = 0) uniform sampler2D uAlbedoMap; +layout (binding = 1) uniform sampler2D uRoughnessMap; +layout (binding = 2) uniform sampler2D uIoRMap; +layout (binding = 3) uniform sampler2D uMetallicMap; +layout (binding = 4) uniform sampler2D uBumpMap; +layout (binding = 5) uniform sampler2D uAOMap; float getRoughness(); float getMetallic(); float getIoR(); float getAO(); vec3 getAlbedo(); - -float diffuse(...); -float specular(...); +)" ++ +IncludeHandler->getIncludeStandard("irr/builtin/glsl/brdf/diffuse/oren_nayar.glsl") ++ +IncludeHandler->getIncludeStandard("irr/builtin/glsl/brdf/specular/ndf/ggx_trowbridge_reitz.glsl") ++ +IncludeHandler->getIncludeStandard("irr/builtin/glsl/brdf/specular/geom/ggx_smith.glsl") ++ +IncludeHandler->getIncludeStandard("irr/builtin/glsl/brdf/specular/fresnel/fresnel_schlick.glsl") ++ +R"( +float diffuse(in float a2, in vec3 N, in vec3 L, in vec3 V, in float NdotL, in float NdotV); +float specular(in float a2, in float NdotL, in float NdotV, in float NdotH); void main() { const vec3 N = normalize(Normal); @@ -193,36 +203,36 @@ void main() { const vec3 albedo = getAlbedo(); const float ior = getIoR(); const float ao = getAO(); - const float F0 = mix(vec3(ior, ior, ior), albedo, metallic); + const vec3 F0 = mix(vec3(1.0-ior), albedo, metallic); const vec3 fresnel = FresnelSchlick(F0, NdotV); - float diffuse = diffuse(...) * (1.0 - metallic); - float spec = specular(...); + float diffuse = diffuse(a2, N, L, V, NdotL, NdotV) * (1.0 - metallic); + float spec = specular(a2, NdotL, NdotV, NdotH); vec3 color = ((diffuse * albedo * (vec3(1.0) - fresnel)) + (spec * fresnel)) * uLightColor / dot(relLightPos, relLightPos); - // color *= NdotL; // ??? OutColor = vec4(color, 1.0); } )"; source += genGetters(_params); - source += "float diffuse(...) {\n"; + source += "float diffuse(in float a2, in vec3 N, in vec3 L, in vec3 V, in float NdotL, in float NdotV) {\n"; if (_params.constantMetallic && !_params.metallicIsOne) { - if (_params.constantRoughness && !_params.roughnessIsZero) - source += "\treturn lambert(...);"; + if (_params.constantRoughness && _params.roughnessIsZero) + source += "\treturn NdotL;"; else - source += "\treturn orey_nayar(...);"; + source += "\treturn oren_nayar(a2, N, L, V, NdotL, NdotV);"; } else source += "\treturn 0.0;"; source += "\n}\n"; source += -R"(float specular(...) { +R"(float specular(in float a2, in float NdotL, in float NdotV, in float NdotH) { float ndf = GGXTrowbridgeReitz(a2, NdotH); - float geom = GGXSmith(a2, NdotV); + float geom = GGXSmith(a2, NdotL, NdotV); return ndf*geom / (4.0 * NdotV * NdotL); -})"; +} +)"; return Shaders.insert({flagsToKey(_params), video::EMT_SOLID}).first->second; // TODO } diff --git a/examples_tests/13.BRDF_Explorer/CBRDFBuiltinIncludeLoader.h b/examples_tests/13.BRDF_Explorer/CBRDFBuiltinIncludeLoader.h index 8509e8841..c4d11c2d5 100644 --- a/examples_tests/13.BRDF_Explorer/CBRDFBuiltinIncludeLoader.h +++ b/examples_tests/13.BRDF_Explorer/CBRDFBuiltinIncludeLoader.h @@ -8,16 +8,90 @@ class CBRDFBuiltinIncludeLoader : public irr::asset::IBuiltinIncludeLoader public: const char* getVirtualDirectoryName() const override { return "glsl/brdf/"; } +private: + static std::string getOrenNayar(const std::string&) + { + return +R"(#ifndef _BRDF_DIFFUSE_OREN_NAYAR_INCLUDED_ +#define _BRDF_DIFFUSE_OREN_NAYAR_INCLUDED_ + +float oren_nayar(in float a2, in vec3 N, in vec3 L, in vec3 V, in float NdotL, in float NdotV) +{ + // theta - polar angles + // phi - azimuth angles + vec2 AB = vec2(1.0, 0.0) + vec2(-0.5, 0.45) * vec2(a2, a2)/vec2(a2+0.33, a2+0.09); + vec2 cos_theta = vec2(NdotL, NdotV); + vec2 cos_theta2 = cos_theta*cos_theta; + float sin_theta = sqrt((1.0 - cos_theta2.x) * (1.0 - cos_theta2.y)); //this is actually equal to sqrt(sin(theta_i) * sin(theta_r)) + float C = sin_theta / max(cos_theta.x, cos_theta.y); + + vec3 light_plane = normalize(L - cos_theta.x*N); + vec3 view_plane = normalize(V - cos_theta.y*N); + float cos_phi = max(0.0, dot(light_plane, view_plane));//not sure about this + + return cos_theta.x * (AB.x + AB.y * cos_phi * C) / 3.14159265359; +} + +#endif +)"; + } + static std::string getGGXTrowbridgeReitz(const std::string&) + { + return +R"(#ifndef _BRDF_SPECULAR_NDF_GGX_TROWBRIDGE_REITZ_INCLUDED_ +#define _BRDF_SPECULAR_NDF_GGX_TROWBRIDGE_REITZ_INCLUDED_ + +float GGXTrowbridgeReitz(in float a2, in float NdotH) +{ + float denom = NdotH*NdotH * (a2 - 1.0) + 1.0; + return a2 / (3.14159265359 * denom*denom); +} + +#endif +)"; + } + static std::string getGGXSmith(const std::string&) + { + return +R"(#ifndef _BRDF_SPECULAR_GEOM_GGX_SMITH_INCLUDED_ +#define _BRDF_SPECULAR_GEOM_GGX_SMITH_INCLUDED_ + +float _GGXSmith_G1_(in float a2, in float NdotX) +{ + return (2.0*NdotX) / (NdotX + sqrt(a2 + (1.0 - a2)*NdotX*NdotX)); +} + +float GGXSmith(in float a2, in float NdotL, in float NdotV) +{ + return _GGXSmith_G1_(a2, NdotL) * _GGXSmith_G1_(a2, NdotV); +} + +#endif +)"; + } + static std::string getFresnelSchlick(const std::string&) + { + return +R"(#ifndef _BRDF_SPECULAR_FRESNEL_FRESNEL_SCHLICK_INCLUDED_ +#define _BRDF_SPECULAR_FRESNEL_FRESNEL_SCHLICK_INCLUDED_ + +vec3 FresnelSchlick(in vec3 F0, in float NdotV) +{ + return F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0); +} + +#endif +)"; + } + protected: irr::core::vector> getBuiltinNamesToFunctionMapping() const override { - /* TODO */ return { - { std::regex{"diffuse/lambert\\.glsl"}, [this](const std::string&) { return nullptr; }}, - { std::regex{"diffuse/oren_nayar\\.glsl"}, [](const std::string&) { return nullptr; }}, - { std::regex{"specular/ndf/ggx_trowbridge_reitz\\.glsl"}, nullptr }, - { std::regex{"specular/geom/ggx_smith\\.glsl"}, nullptr }, - { std::regex{"specular/fresnel/fresnel_schlick\\.glsl"}, nullptr } + { std::regex{"diffuse/oren_nayar\\.glsl"}, &getOrenNayar }, + { std::regex{"specular/ndf/ggx_trowbridge_reitz\\.glsl"}, &getGGXTrowbridgeReitz }, + { std::regex{"specular/geom/ggx_smith\\.glsl"}, &getGGXSmith }, + { std::regex{"specular/fresnel/fresnel_schlick\\.glsl"}, &getFresnelSchlick } }; } }; diff --git a/examples_tests/13.BRDF_Explorer/main.cpp b/examples_tests/13.BRDF_Explorer/main.cpp index 7cddef5ee..4e2534b4b 100644 --- a/examples_tests/13.BRDF_Explorer/main.cpp +++ b/examples_tests/13.BRDF_Explorer/main.cpp @@ -2,6 +2,7 @@ #include #include "BRDFExplorerApp.h" +#include "CBRDFBuiltinIncludeLoader.h" using namespace irr; @@ -36,6 +37,12 @@ int main() camera->setFarValue(1000.0f); smgr->setActiveCamera(camera); + { + auto brdfBuiltinLoader = new CBRDFBuiltinIncludeLoader(); + device->getIncludeHandler()->addBuiltinIncludeLoader(brdfBuiltinLoader); + brdfBuiltinLoader->drop(); + } + auto* brdfExplorerApp = new BRDFExplorerApp(device, camera); uint64_t lastFPSTime = 0;