From 7257bbb87180f6b8031453b018b3983cd0649732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 8 Sep 2020 00:45:30 +0200 Subject: [PATCH] Shaders: rework Phong to support directional and attenuated point lights. This is a -- long overdue -- breaking change to the rendering output of this shader, finally adding support for lights that get darker over distance. The attenuation equation is basically what's documented in LightData, and the distinction between directional and point lights is made using a newly added the fourth component of position (which means the old three-component setters are all deprecated). This allows the shader code to be practically branchless, which I find to be nice. This breaks basically all rendering output so all existing Phong and MeshTools::compile() test outputs had to be regenerated. --- doc/changelog.dox | 17 +- doc/generated/primitives.cpp | 2 +- doc/generated/shaders.cpp | 2 +- doc/snippets/MagnumSceneGraph-gl.cpp | 9 +- doc/snippets/MagnumShaders.cpp | 38 ++- src/Magnum/MeshTools/Test/CompileGLTest.cpp | 10 +- .../Test/CompileTestFiles/phong-flat.tga | Bin 2998 -> 2998 bytes .../Test/CompileTestFiles/phong-smooth.tga | Bin 2953 -> 3012 bytes .../MeshTools/Test/CompileTestFiles/phong.tga | Bin 3000 -> 2998 bytes src/Magnum/Shaders/Flat.h | 2 +- src/Magnum/Shaders/Phong.cpp | 136 ++++++++-- src/Magnum/Shaders/Phong.frag | 28 ++- src/Magnum/Shaders/Phong.h | 204 ++++++++++++--- src/Magnum/Shaders/Phong.vert | 13 +- src/Magnum/Shaders/Test/CMakeLists.txt | 7 + src/Magnum/Shaders/Test/PhongGLTest.cpp | 233 ++++++++++++++---- .../Shaders/Test/PhongTestFiles/colored.tga | Bin 19218 -> 12875 bytes .../Shaders/Test/PhongTestFiles/defaults.tga | Bin 15082 -> 15458 bytes .../Test/PhongTestFiles/instanced-normal.tga | Bin 9875 -> 10289 bytes .../Shaders/Test/PhongTestFiles/instanced.tga | Bin 8962 -> 9748 bytes .../light-directional-intensity2.tga | Bin 0 -> 850 bytes .../Test/PhongTestFiles/light-directional.tga | Bin 0 -> 850 bytes .../Test/PhongTestFiles/light-none.tga | Bin 0 -> 850 bytes .../light-point-attenuated-specular.tga | Bin 0 -> 7885 bytes .../light-point-intensity10-range0.5.tga | Bin 0 -> 1619 bytes .../PhongTestFiles/light-point-range1.5.tga | Bin 0 -> 6810 bytes .../Test/PhongTestFiles/light-point.tga | Bin 0 -> 8129 bytes .../Test/PhongTestFiles/low-light-angle.tga | Bin 8325 -> 5746 bytes .../shininess-black-specular.tga | Bin 19218 -> 11478 bytes .../Test/PhongTestFiles/shininess0.tga | Bin 19218 -> 4773 bytes .../Test/PhongTestFiles/shininess10.tga | Bin 19218 -> 11412 bytes .../Test/PhongTestFiles/shininess80.tga | Bin 19218 -> 11477 bytes .../Test/PhongTestFiles/textured-ambient.tga | Bin 19218 -> 9728 bytes .../textured-diffuse-alpha-mask0.5.tga | Bin 19218 -> 8206 bytes .../PhongTestFiles/textured-diffuse-alpha.tga | Bin 19218 -> 11206 bytes .../textured-diffuse-transformed.tga | Bin 19218 -> 10527 bytes .../Test/PhongTestFiles/textured-diffuse.tga | Bin 19218 -> 10965 bytes .../PhongTestFiles/textured-normal-left.tga | Bin 11105 -> 11101 bytes .../Test/PhongTestFiles/textured-normal.tga | Bin 11108 -> 11121 bytes .../PhongTestFiles/textured-normal0.0.tga | Bin 3070 -> 2723 bytes .../PhongTestFiles/textured-normal0.5.tga | Bin 10855 -> 10988 bytes .../Test/PhongTestFiles/textured-specular.tga | Bin 19218 -> 6593 bytes .../Shaders/Test/PhongTestFiles/textured.tga | Bin 19218 -> 11090 bytes .../Test/PhongTestFiles/vertexColor.tga | Bin 10876 -> 10314 bytes 44 files changed, 573 insertions(+), 128 deletions(-) create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-directional-intensity2.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-directional.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-none.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-point-attenuated-specular.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-point-intensity10-range0.5.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-point-range1.5.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-point.tga diff --git a/doc/changelog.dox b/doc/changelog.dox index 4992773ed..1d01cf92c 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -77,6 +77,9 @@ See also: - Added @ref Shaders::Phong::setNormalTextureScale(), consuming the recently added @ref Trade::MaterialAttribute::NormalTextureScale material attribute +- @ref Shaders::Phong was reworked to support directional and + range-attenuated point lights to follow the additions to + @ref Trade::LightData @subsubsection changelog-latest-new-scenegraph SceneGraph library @@ -179,6 +182,13 @@ See also: @subsection changelog-latest-deprecated Deprecated APIs +- @ref Shaders::Phong::setLightPositions() and + @ref Shaders::Phong::setLightPosition() taking three-component vectors are + deprecated in favor of variants taking four-component vectors, where the + last component distinguishes between directional and point lights +- @cpp Shaders::Phong::setLightPosition(const Vector3&) @ce is deprecated in + favor of @ref Shaders::Phong::setLightPositions() with a single item --- + it's short enough to not warrant the existence of a dedicated overload - @cpp Trade::AbstractMaterialData @ce as well as its containing header `Magnum/Trade/AbstractMaterialData.h` is now a deprecated alias to the new and more flexible @ref Trade::MaterialData. @@ -264,6 +274,11 @@ See also: afterwards. This can cause compilation breakages in case the type constructor has the parent parameter non-optional, pass the parent explicitly in that case. +- Due to the rework of @ref Shaders::Phong to support directional and + attenuated point lights, the original behavior of unattenuated point lights + isn't available anymore. For backwards compatibility, light positions + supplied through three-component vectors are now represented as directional + lights, which is close, but not exactly the same as before. - Mutable access to @ref Trade::PhongMaterialData color and texture information, deprecated in 2020.06, is now removed, as it's impossible to implement through the redesigned @ref Trade::MaterialData APIs. However @@ -1499,7 +1514,7 @@ Released 2019-10-24, tagged as - @ref Shaders::Phong now clamps the specular factor to minimize artifacts when shininess is near zero - @ref Shaders::Phong can now handle zero lights, in which case its output is - equivalent to @ref Shaders::Flat3D. See @ref Shaders-Phong-zero-lights for + equivalent to @ref Shaders::Flat3D. See @ref Shaders-Phong-lights-zero for more information. - @ref Shaders::MeshVisualizer is fixed to work properly on Intel Windows drivers, adding a new diff --git a/doc/generated/primitives.cpp b/doc/generated/primitives.cpp index a0e8ec4de..df60eee77 100644 --- a/doc/generated/primitives.cpp +++ b/doc/generated/primitives.cpp @@ -321,7 +321,7 @@ int PrimitiveVisualizer::exec() { phong.setAmbientColor(0x22272e_srgbf) .setDiffuseColor(BaseColor) .setSpecularColor(0x000000_srgbf) - .setLightPosition({5.0f, 5.0f, 7.0f}) + .setLightPositions({{5.0f, 5.0f, 7.0f, 0.0f}}) .setProjectionMatrix(Projection3D) .setTransformationMatrix(Transformation3D) .setNormalMatrix(Transformation3D.normalMatrix()); diff --git a/doc/generated/shaders.cpp b/doc/generated/shaders.cpp index f2fd5aa3f..ac10c18d9 100644 --- a/doc/generated/shaders.cpp +++ b/doc/generated/shaders.cpp @@ -165,7 +165,7 @@ std::string ShaderVisualizer::phong() { .setAmbientColor(0x22272e_srgbf) .setDiffuseColor(BaseColor) .setShininess(200.0f) - .setLightPosition({5.0f, 5.0f, 7.0f}) + .setLightPositions({{5.0f, 5.0f, 7.0f, 0.0f}}) .setProjectionMatrix(Projection) .setTransformationMatrix(Transformation) .setNormalMatrix(Transformation.normalMatrix()) diff --git a/doc/snippets/MagnumSceneGraph-gl.cpp b/doc/snippets/MagnumSceneGraph-gl.cpp index 9c295e131..6aaf43ef2 100644 --- a/doc/snippets/MagnumSceneGraph-gl.cpp +++ b/doc/snippets/MagnumSceneGraph-gl.cpp @@ -103,8 +103,6 @@ class RedCubeDrawable: public SceneGraph::Drawable3D { using namespace Math::Literals; _shader.setDiffuseColor(0xa5c9ea_rgbf) - .setLightPosition(camera.cameraMatrix().transformPoint( - {5.0f, 5.0f, 7.0f})) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setProjectionMatrix(camera.projectionMatrix()) @@ -185,7 +183,8 @@ struct MyApplication: Platform::Application { SceneGraph::Object* _cameraObject; SceneGraph::Camera3D* _camera; - Vector3 _lightPositionRelativeToCamera, _lightColor, _ambientColor; + Vector4 _lightPositionRelativeToCamera; + Vector3 _lightColor, _ambientColor; /* [Drawable-multiple-groups] */ // ... @@ -195,8 +194,8 @@ struct MyApplication: Platform::Application { void MyApplication::drawEvent() { _shader.setProjectionMatrix(_camera->projectionMatrix()) - .setLightPosition(_lightPositionRelativeToCamera) - .setLightColor(_lightColor) + .setLightPositions({_lightPositionRelativeToCamera}) + .setLightColors({_lightColor}) .setAmbientColor(_ambientColor); /* Each drawable sets only unique properties such as transformation matrix diff --git a/doc/snippets/MagnumShaders.cpp b/doc/snippets/MagnumShaders.cpp index 9e25cfc9b..75211da65 100644 --- a/doc/snippets/MagnumShaders.cpp +++ b/doc/snippets/MagnumShaders.cpp @@ -52,6 +52,9 @@ #include "Magnum/Shaders/Phong.h" #include "Magnum/Shaders/Vector.h" #include "Magnum/Shaders/VertexColor.h" +#include "Magnum/Trade/LightData.h" + +#define DOXYGEN_IGNORE(...) __VA_ARGS__ using namespace Magnum; using namespace Magnum::Math::Literals; @@ -90,7 +93,6 @@ GL::Texture2D diffuseTexture, specularTexture; Shaders::Phong shader{Shaders::Phong::Flag::DiffuseTexture}; shader.bindDiffuseTexture(diffuseTexture) - .setLightPosition({5.0f, 5.0f, 7.0f}) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setProjectionMatrix(projectionMatrix) @@ -489,7 +491,6 @@ Matrix4 projectionMatrix = Shaders::Phong shader; shader.setDiffuseColor(0x2f83cc_rgbf) .setShininess(200.0f) - .setLightPosition({5.0f, 5.0f, 7.0f}) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setProjectionMatrix(projectionMatrix) @@ -525,7 +526,6 @@ GL::Texture2D diffuseTexture, specularTexture; Shaders::Phong shader{Shaders::Phong::Flag::DiffuseTexture| Shaders::Phong::Flag::SpecularTexture}; shader.bindTextures(nullptr, &diffuseTexture, &specularTexture, nullptr) - .setLightPosition({5.0f, 5.0f, 7.0f}) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.normalMatrix()) .setProjectionMatrix(projectionMatrix) @@ -534,6 +534,38 @@ shader.bindTextures(nullptr, &diffuseTexture, &specularTexture, nullptr) } #endif +{ +/* [Phong-usage-lights] */ +Matrix4 directionalLight, pointLight1, pointLight2; // camera-relative + +Shaders::Phong shader{{}, 3}; // 3 lights +shader + .setLightPositions({Vector4{directionalLight.up(), 0.0f}, + Vector4{pointLight1.translation(), 1.0f}, + Vector4{pointLight2.translation(), 1.0f}}) + .setLightColors({0xf0f0ff_srgbf*0.1f, + 0xff8080_srgbf*10.0f, + 0x80ff80_srgbf*10.0f}) + .setLightRanges({Constants::inf(), + 2.0f, + 2.0f}); +/* [Phong-usage-lights] */ +} + +{ +Color3 ambientColor; +GL::Texture2D diffuseTexture; +/* [Phong-usage-lights-ambient] */ +Trade::LightData ambientLight = DOXYGEN_IGNORE(Trade::LightData{{}, {}, {}}); + +Shaders::Phong shader{Shaders::Phong::Flag::AmbientTexture|DOXYGEN_IGNORE(Shaders::Phong::Flag::DiffuseTexture), DOXYGEN_IGNORE(3)}; +shader + .setAmbientColor(ambientColor + ambientLight.color()*ambientLight.intensity()) + .bindAmbientTexture(diffuseTexture) + .bindDiffuseTexture(diffuseTexture); +/* [Phong-usage-lights-ambient] */ +} + { GL::Texture2D diffuseAlphaTexture; Color3 diffuseRgb, specularRgb; diff --git a/src/Magnum/MeshTools/Test/CompileGLTest.cpp b/src/Magnum/MeshTools/Test/CompileGLTest.cpp index e257ca150..de73c7e7a 100644 --- a/src/Magnum/MeshTools/Test/CompileGLTest.cpp +++ b/src/Magnum/MeshTools/Test/CompileGLTest.cpp @@ -303,6 +303,12 @@ CompileGLTest::CompileGLTest() { #endif {4, 4}) .setSubImage(0, {}, ImageView2D{PixelFormat::RGBA8Unorm, {4, 4}, ImageData}); + /* Use a point light instead of a directional light to better highlight the + difference in normals; disable specular as that only causes unnecessary + rounding errors across GPUs */ + _phong.setLightPositions({{0.0f, 0.0f, -0.0f, 1.0f}}) + .setLightColors({0xffffff_rgbf*9.0f}) + .setSpecularColor(0x00000000_rgbaf); #ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES @@ -762,7 +768,7 @@ template void CompileGLTest::threeDimensions() { _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "phong-flat.tga"), /* SwiftShader has some minor off-by-one precision differences */ - (DebugTools::CompareImageToFile{_manager, 0.5f, 0.0079f})); + (DebugTools::CompareImageToFile{_manager, 0.5f, 0.012f})); } else if(data.flags & Flag::GeneratedSmoothNormals) { _framebuffer.clear(GL::FramebufferClear::Color); _phong @@ -777,7 +783,7 @@ template void CompileGLTest::threeDimensions() { _framebuffer.read({{}, {32, 32}}, {PixelFormat::RGBA8Unorm}), Utility::Directory::join(COMPILEGLTEST_TEST_DIR, "phong-smooth.tga"), /* SwiftShader has some minor off-by-one precision differences */ - (DebugTools::CompareImageToFile{_manager, 0.25f, 0.0059f})); + (DebugTools::CompareImageToFile{_manager, 0.5f, 0.0088f})); } /* Check with the colored shader, if we have colors */ diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/phong-flat.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/phong-flat.tga index 4947cdb13de8fb27eb46ed96a72666ddf1e8eebc..1be253521ce7a43399b94677c7adbb3244cba8ce 100644 GIT binary patch literal 2998 zcmZ9O*=vKKWQgb8n`bQGFC=jYDD*HH{;p__x@Cf)9eCbaZa5twWvK+SXZG z2h>V!rHDc)h)?|+w(GaN=j6*#yu^FH?6udh_xV~{rnjU&^%nh|cC1#b#pK6c{ySsg z!P&9sP-`syq&1d&UW=t))?(SwdMrO)j}<5DG5kYk3}5Mtp-UaH=KGFVeXc!LecK)@ zPq)R2Q*A+!J$!u3#|QKG&58y4XT`z;DtlNZKW&YrUsOu!R|dasi_{z^d{#5uN0V?srS3C~O7d$!&?z0SR!O?&JGvhI zrOU9e8@k+?nHf^;(H4*(Rp4NSP#p0{hWSnq=LK=G!{vsrcAC)|nCJ|~qt_cT^0S!! z)MY_=mex>#bLtgv2nZ{V(3?`g;02x_8YM@6?TWD*jQ}>671Obs4WAjZde#&+!RB>XDD?&BGE<#Gj^*H>+W>N`g`5)%c~7Uq%{QOoR-$g*C{ROEJbE_#-53P znWeg>43IE`)wFUW9Qqs zZh=-Zw4TLl$4oG&#zdfE^1gs&Uoy^Y8ahi+BC*5=FA)}&K<@f~o_~hDp{0hsR?KLZ zwmm>ZOk%SK*jNQDUwK975z;t?u}V>LiqL`wnignR z31n4h;ztbGR>aa9tQjq0TficOw~}CpM4Df=4=OO1X_yQxFA)}&uxGd!vXp3s&jJ%G z1XipV(gN1(SoiYS!y_2B4FcsQnV?Cxyv9p}#d9E8DXbP&3_IMbqdC6_%t|U?y(R>K zC@e+aFcJ!AM=Y^sh2XVfMtoq7u&@L&M@cm>&X=LC76fJi7qGtMbn_>%OK4alI9_7{ zks+}}4KIO%B{|4TGBMTgaLsVt6tHM-QDwg`Jg#pbxL2F3eea?M(bM;a61*=v;Mhj# z)@iN^E>W0rsdBky*!S;BetW>nDr^!PpEUs0Ggtu)GupsMuX`~>Skz+=n5AAFfUCT` zaKykc&bcgN3X+lt%DJz732g`|;mb^nP{1&1i`J>fix58YVpPE8cO)PaOAQg_oMr@; zXcnK%r8E4cHR1>R3?mU?1r+`*&}&}-$ID@cRChpf^OIIYLM#|Dt6r7~LhaE4gMe4S v;1};+umXyg+6=dspJupgUdfV}Fl)lVj(wR+YOI;D)P0JAUz?9nZt~+Dlm_GE literal 2998 zcmZ{m*-lhJ6h-^d_~fJE1)qSXf%Zcb(FPm<`4%TE04)j$E5dE7x`1m`g`* z>bj-tb~kN&SxOt97t^Uvx;`wXlkauCTSzC~ETrSF77`CR&&N4F_8+=9lMY{+Nz0d; z$HpV?bkniBy6$z;;C|QG&96cP=3~Zyc&qERFfV&){dq5~J?$BHc7!vkt{#l4J_aTu z1`p=b>O)M`@wI}ngbnRKsN+}0Zw|)ruO-fOV zp%aiTPRgj(in1Cjc`O7NAuwkBMb9Ro6xBwmL?c7#1Z2Tk;uKK`br?v0Fb&jtM$rq} zPG5+?s!AEi+<~y%Lu|Hw_D2Rc*oe%T!k!|1wMrBkDP;vG6ulvN^a zrxjv_9aBpGqy&{9QD&S_gq~h808V0{<;*0s`y0a|bc3~0nM9w)lwztB29Ah$C={2m zAwYGDj%aC!B33Pyv95bsDaBB31IJL1(k;cNjCssojn=bPB4UwfIn`jg8{)r6cweY1o^w4w*U0gM%6Pf zH&o|dlkhTFtdFd?#cI^c(6k2Y@k9e-Q3-PU@4?|ZsL^@hk#G+eGfleXB#}jNgXLHJ zsWzKid4$s(%GDoKQU+*BpcG2tcNpm<$ZD5*myn~zN@=mVclGRIl=~cLJ<6tMw2?C0 zD}rT6|5$|dTV>KH);yD8!_~+JOO@P4`+ZnpdOJ*ch68Pt>a`bQ?j3{1z_F2hx+r2^ zpxNvei-Ibxgn!qP%o~gNfW}ycDNdT0&4|~S!3>mA-C)ONlf-IJSacq$dOrtRCVB(O zp*UqGDXk5rfi0Fnsp5j!^lTzJ_nO9_koz1Xj_({L2C1YuuMQ&HV8b}iXf}HyI>!tH zK{-BwQ$O3aQO_>NO@sA;rrV3zlh7}rO zYpnWA#LCgHHDFa55T{kjy%beSIRs-ls-K~kv{Tbgt`hxl@pOMzhIeRUU2jnObdk1)ds`&j8gx2?Q3vUx(k_89C7m6 z5SGUj1mmtgk!;k|7*v7crMBRPug#839&^V=q4#D|55Zs}k3<=!jy*OfZ#Q*>R diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/phong-smooth.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/phong-smooth.tga index 07f653f909e15bdfb14fb89fe73125883ef2d047..d13c884404d019dd4638cdb02ff9ebc33eedc172 100644 GIT binary patch literal 3012 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 diff --git a/src/Magnum/MeshTools/Test/CompileTestFiles/phong.tga b/src/Magnum/MeshTools/Test/CompileTestFiles/phong.tga index c952c51a2de1aad36ee2c236301f220d9ecad964..bbd24f458493884489484aaf004b7d21f5df1840 100644 GIT binary patch literal 2998 zcmZwJSBTwJ5C-r(ich{IZZ>5%yJ@>AyV)3%nBJR-MonT&OpGCjFXD@eV!_1TI~FuH z>QOQ0+WdP>zOEV-v#%H#vo0N3 z&&=4<9MjJp9)4?+3%u>|*3^08(3o=au;@OmDSGk|+s?eCcgs1~jgEOYj*j`aw8Vm2 zTVmnf)>v>`Ys|m7r9Pi~{pf<7b$Kt$LA#ry=gi^Jb;^M;`J`ddal+7o+dTjWYT6l1 z;nA5FkEqIR1H$%;?iv$I?i~|L?{ABx59aHEwpe`6m{@e@0QB4&5;hsmOm@ocIV&Mg zZ7N7egW#|NMI_>=eBte_wWaNsKiVEE9v>SkpBx*jo*oygo*G;0We>Mk8Op(U-c2p_ zd;82de?%{2vTT4OAXcCVw)pO3k_=Wn)*h=8V)e7*;?U>E$J!V3_40&R`_hD1lk3&b zjO&GcsI6cZ-q9;E0}2w$6t*9(C^oZ`0PM#M+_Fd7W91XQP-|ZpAM0M75Qo1$G1k8| zF^+hrBi6s&QR{UHzvj8|#dvxCX32eRC9-{#Ph86NMdsXo>}Kf`5xx-6W4@XaTfUhZTffWKw^PGf85=)I==VDdx>#q#mZi_4MQnWwqXCxfde37- zDyHcrVX?$)Yr-A-eOGMzu`9O!+#TD0>Z z9_Oj}6w?$IE0EiN>5d)0=Ii%qvE#RCaa^vq{m>Plu_icE#7w$1lpaROWNLsVf`-xd zdQpQ&toYcDuvmiJ`Ny=_`BzWu{Ie&HPk7KuQX21-s$`9Yf~=I#8Lb9bLGSl9)2Js^ zT>@u(cu80+LGJozdhGhU7aD7V^O_kLYc4%)jOYr{GLIWzedH^Tc+^k))E4DyZfR=} zSb_wt1f?iRX%enfB`aO3MHD5}8evm_8WWl)g(1+syd@}ML6^`eIN=$m|e<*iuurP0;Z@_h-MO=pm5Ld~ctQPQLhuv(c2g!Y(L=dso|eT)LoSWB$< z@RG3BAdQqtagG?H#>naSHAm4t#)ZLUfEi?cjE!}X;88&*Yl3SMFyf;OYb-%l&*nhI z)PSw#`A=X2xPh%PU5qnY#hR0vQi8-<^OCSwf^=v)JnbV&nEvnJ>%A*Ef_=qy zM}o(TaSls9OQdvbEInOEe2R}5C_WMuLvR|V&f2^(xH@1t=QOf%2y?49&rA;`u@4NTh^Vk2^Uv*ATPj64>-<+QOf6|fJ zvuDTn`Ca7_|8F&>|%C!E8 zg~i1(h4JQ4?09=o?0h%Jdy8Y&`-@|zk-t6Pp6@|#d3mtn6X&{=b7 zP$EUgGCST`RLfuZ;gY!Mqa|_i$4la{OP^n!?)qSH%`$uItAj!74NtcKainVlRs{R# z=oJm+2-pR0wYXT)`nx|}8hbup8e?A$$H`+~4cE<{FNS0HXG?2>iOBnqD21CuM^jt* z?0DvI1Ac0eOpnlmmO{1!D!V^Pyj=d0Z-!&EaEbs=AcpL0cj;5 z42Tn8xwxq2G?CI&^dK<F6AMTwD`~0cyrxU#=URY#5gTh_PHY##DM;N4(@aj2SDi}TW-FSa zU1(e-bVjA2P3p-hc0p&()MdeE4nZj{b&VxR?$=P8E=AyW@l4SioBb{so2HFx=ZZ;= zw0X`ZAj@E1!+pYejwQ&-X{RT*JCviyiCe+6Izi;-WRsF(hS#x9*!_~Z<%KZ4+5OT# z;-V~?>|0wvLdphysZtZ5i1nBvQ+Wx}dY#r!}Xu#PFhUGCpx?18Bjbqhntep2HzbH0kQF z;S(-~YZ+|=W%$#G?FJV?sf5Bwj|f=cc)@b4ZSem8;0((W6A#W>iMm!~9B #endif #include @@ -55,7 +55,7 @@ namespace { }; } -Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _lightCount{lightCount}, _lightColorsUniform{_lightPositionsUniform + Int(lightCount)} { +Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _lightCount{lightCount}, _lightColorsUniform{_lightPositionsUniform + Int(lightCount)}, _lightRangesUniform{_lightPositionsUniform + 2*Int(lightCount)} { CORRADE_ASSERT(!(flags & Flag::TextureTransformation) || (flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture)), "Shaders::Phong: texture transformation enabled but the shader is not textured", ); @@ -76,22 +76,53 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l GL::Shader frag = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Fragment); #ifndef MAGNUM_TARGET_GLES - std::string lightInitializer; + std::string lightInitializerVertex, lightInitializerFragment; if(lightCount) { using namespace Containers::Literals; - /* Initializer for the light color array -- we need a list of vec4(1.0) - joined by commas. For GLES we'll simply upload the values directly. */ - constexpr Containers::StringView lightInitializerPreamble = "#define LIGHT_COLOR_INITIALIZER "_s; - constexpr Containers::StringView lightInitializerItem = "vec4(1.0), "_s; - lightInitializer.reserve(lightInitializerPreamble.size() + lightCount*lightInitializerItem.size()); - lightInitializer.append(lightInitializerPreamble.data(), lightInitializerPreamble.size()); + /* Initializer for the light color / position / range arrays -- we need + a list of initializers joined by commas. For GLES we'll simply + upload the values directly. */ + constexpr Containers::StringView lightPositionInitializerPreamble = "#define LIGHT_POSITION_INITIALIZER "_s; + constexpr Containers::StringView lightColorInitializerPreamble = "#define LIGHT_COLOR_INITIALIZER "_s; + constexpr Containers::StringView lightRangeInitializerPreamble = "#define LIGHT_RANGE_INITIALIZER "_s; + constexpr Containers::StringView lightPositionInitializerItem = "vec4(0.0, 0.0, 1.0, 0.0), "_s; + constexpr Containers::StringView lightColorInitializerItem = "vec4(1.0), "_s; + constexpr Containers::StringView lightRangeInitializerItem = "1.0/0.0, "_s; + + lightInitializerVertex.reserve( + lightPositionInitializerPreamble.size() + + lightCount*(lightPositionInitializerItem.size())); + + lightInitializerVertex.append(lightPositionInitializerPreamble.data(), lightPositionInitializerPreamble.size()); for(std::size_t i = 0; i != lightCount; ++i) - lightInitializer.append(lightInitializerItem.data(), lightInitializerItem.size()); + lightInitializerVertex.append(lightPositionInitializerItem.data(), lightPositionInitializerItem.size()); /* Drop the last comma and add a newline at the end */ - lightInitializer[lightInitializer.size() - 2] = '\n'; - lightInitializer.resize(lightInitializer.size() - 1); + lightInitializerVertex[lightInitializerVertex.size() - 2] = '\n'; + lightInitializerVertex.resize(lightInitializerVertex.size() - 1); + + lightInitializerFragment.reserve( + lightColorInitializerPreamble.size() + + lightRangeInitializerPreamble.size() + + lightCount*(lightColorInitializerItem.size() + + lightRangeInitializerItem.size())); + + lightInitializerFragment.append(lightColorInitializerPreamble.data(), lightColorInitializerPreamble.size()); + for(std::size_t i = 0; i != lightCount; ++i) + lightInitializerFragment.append(lightColorInitializerItem.data(), lightColorInitializerItem.size()); + + /* Drop the last comma and add a newline at the end */ + lightInitializerFragment[lightInitializerFragment.size() - 2] = '\n'; + lightInitializerFragment.resize(lightInitializerFragment.size() - 1); + + lightInitializerFragment.append(lightRangeInitializerPreamble.data(), lightRangeInitializerPreamble.size()); + for(std::size_t i = 0; i != lightCount; ++i) + lightInitializerFragment.append(lightRangeInitializerItem.data(), lightRangeInitializerItem.size()); + + /* Drop the last comma and add a newline at the end */ + lightInitializerFragment[lightInitializerFragment.size() - 2] = '\n'; + lightInitializerFragment.resize(lightInitializerFragment.size() - 1); } #endif @@ -105,8 +136,11 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l .addSource(flags >= Flag::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "") #endif .addSource(flags & Flag::InstancedTransformation ? "#define INSTANCED_TRANSFORMATION\n" : "") - .addSource(flags >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : "") - .addSource(rs.get("generic.glsl")) + .addSource(flags >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : ""); + #ifndef MAGNUM_TARGET_GLES + if(lightCount) vert.addSource(std::move(lightInitializerVertex)); + #endif + vert.addSource(rs.get("generic.glsl")) .addSource(rs.get("Phong.vert")); frag.addSource(flags & Flag::AmbientTexture ? "#define AMBIENT_TEXTURE\n" : "") .addSource(flags & Flag::DiffuseTexture ? "#define DIFFUSE_TEXTURE\n" : "") @@ -121,9 +155,13 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l #endif .addSource(Utility::formatString( "#define LIGHT_COUNT {}\n" - "#define LIGHT_COLORS_LOCATION {}\n", lightCount, _lightPositionsUniform + lightCount)); + "#define LIGHT_COLORS_LOCATION {}\n" + "#define LIGHT_RANGES_LOCATION {}\n", + lightCount, + _lightPositionsUniform + lightCount, + _lightPositionsUniform + 2*lightCount)); #ifndef MAGNUM_TARGET_GLES - if(lightCount) frag.addSource(std::move(lightInitializer)); + if(lightCount) frag.addSource(std::move(lightInitializerFragment)); #endif frag.addSource(rs.get("generic.glsl")) .addSource(rs.get("Phong.frag")); @@ -186,6 +224,7 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l _normalTextureScaleUniform = uniformLocation("normalTextureScale"); _lightPositionsUniform = uniformLocation("lightPositions"); _lightColorsUniform = uniformLocation("lightColors"); + _lightRangesUniform = uniformLocation("lightRanges"); } if(flags & Flag::AlphaMask) _alphaMaskUniform = uniformLocation("alphaMask"); #ifndef MAGNUM_TARGET_GLES2 @@ -218,7 +257,9 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l setShininess(80.0f); if(flags & Flag::NormalTexture) setNormalTextureScale(1.0f); + setLightPositions(Containers::Array{Containers::DirectInit, lightCount, Vector4{0.0f, 0.0f, 1.0f, 0.0f}}); setLightColors(Containers::Array{Containers::DirectInit, lightCount, Magnum::Color4{1.0f}}); + setLightRanges(Containers::Array{Containers::DirectInit, lightCount, Constants::inf()}); /* Light position is zero by default */ setNormalMatrix({}); } @@ -328,26 +369,53 @@ Phong& Phong::setTextureMatrix(const Matrix3& matrix) { return *this; } -Phong& Phong::setLightPositions(const Containers::ArrayView positions) { +Phong& Phong::setLightPositions(const Containers::ArrayView positions) { CORRADE_ASSERT(_lightCount == positions.size(), "Shaders::Phong::setLightPositions(): expected" << _lightCount << "items but got" << positions.size(), *this); if(_lightCount) setUniform(_lightPositionsUniform, positions); return *this; } -Phong& Phong::setLightPosition(UnsignedInt id, const Vector3& position) { +/* It's light, but can't be in the header because MSVC needs to know the size + of Vector3 for the initializer list use */ +Phong& Phong::setLightPositions(const std::initializer_list positions) { + return setLightPositions(Containers::arrayView(positions)); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +Phong& Phong::setLightPositions(const Containers::ArrayView positions) { + Containers::Array fourComponent{Containers::NoInit, positions.size()}; + for(std::size_t i = 0; i != positions.size(); ++i) + fourComponent[i] = Vector4{positions[i], 0.0f}; + setLightPositions(fourComponent); + return *this; +} + +Phong& Phong::setLightPositions(const std::initializer_list positions) { + CORRADE_IGNORE_DEPRECATED_PUSH + return setLightPositions(Containers::arrayView(positions)); + CORRADE_IGNORE_DEPRECATED_POP +} +#endif + +Phong& Phong::setLightPosition(const UnsignedInt id, const Vector4& position) { CORRADE_ASSERT(id < _lightCount, "Shaders::Phong::setLightPosition(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); setUniform(_lightPositionsUniform + id, position); return *this; } -/* It's light, but can't be in the header because MSVC needs to know the size - of Vector3 for the initializer list use */ -Phong& Phong::setLightPositions(std::initializer_list lights) { - return setLightPositions({lights.begin(), lights.size()}); +#ifdef MAGNUM_BUILD_DEPRECATED +Phong& Phong::setLightPosition(UnsignedInt id, const Vector3& position) { + return setLightPosition(id, Vector4{position, 0.0f}); } +Phong& Phong::setLightPosition(const Vector3& position) { + /* Use the list variant to check the shader really has just one light */ + return setLightPositions({Vector4{position, 0.0f}}); +} +#endif + Phong& Phong::setLightColors(const Containers::ArrayView colors) { CORRADE_ASSERT(_lightCount == colors.size(), "Shaders::Phong::setLightColors(): expected" << _lightCount << "items but got" << colors.size(), *this); @@ -357,17 +425,35 @@ Phong& Phong::setLightColors(const Containers::ArrayView c /* It's light, but can't be in the header because MSVC needs to know the size of Color for the initializer list use */ -Phong& Phong::setLightColors(std::initializer_list colors) { - return setLightColors({colors.begin(), colors.size()}); +Phong& Phong::setLightColors(const std::initializer_list colors) { + return setLightColors(Containers::arrayView(colors)); } -Phong& Phong::setLightColor(UnsignedInt id, const Magnum::Color4& color) { +Phong& Phong::setLightColor(const UnsignedInt id, const Magnum::Color4& color) { CORRADE_ASSERT(id < _lightCount, "Shaders::Phong::setLightColor(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); setUniform(_lightColorsUniform + id, color); return *this; } +Phong& Phong::setLightRanges(const Containers::ArrayView ranges) { + CORRADE_ASSERT(_lightCount == ranges.size(), + "Shaders::Phong::setLightRanges(): expected" << _lightCount << "items but got" << ranges.size(), *this); + if(_lightCount) setUniform(_lightRangesUniform, ranges); + return *this; +} + +Phong& Phong::setLightRanges(const std::initializer_list ranges) { + return setLightRanges(Containers::arrayView(ranges)); +} + +Phong& Phong::setLightRange(const UnsignedInt id, const Float range) { + CORRADE_ASSERT(id < _lightCount, + "Shaders::Phong::setLightRange(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this); + setUniform(_lightRangesUniform + id, range); + return *this; +} + Debug& operator<<(Debug& debug, const Phong::Flag value) { debug << "Shaders::Phong::Flag" << Debug::nospace; diff --git a/src/Magnum/Shaders/Phong.frag b/src/Magnum/Shaders/Phong.frag index a6edc6849..09587b3c7 100644 --- a/src/Magnum/Shaders/Phong.frag +++ b/src/Magnum/Shaders/Phong.frag @@ -149,6 +149,15 @@ uniform lowp vec4 lightColors[LIGHT_COUNT] = vec4[](LIGHT_COLOR_INITIALIZER) #endif ; + +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = LIGHT_RANGES_LOCATION) +#endif +uniform lowp float lightRanges[LIGHT_COUNT] + #ifndef GL_ES + = float[](LIGHT_RANGE_INITIALIZER) + #endif + ; #endif #if LIGHT_COUNT @@ -161,7 +170,7 @@ in mediump vec3 transformedTangent; in mediump vec3 transformedBitangent; #endif #endif -in highp vec3 lightDirections[LIGHT_COUNT]; +in highp vec4 lightDirections[LIGHT_COUNT]; in highp vec3 cameraDirection; #endif @@ -244,14 +253,25 @@ void main() { /* Add diffuse color for each light */ for(int i = 0; i < LIGHT_COUNT; ++i) { - highp vec3 normalizedLightDirection = normalize(lightDirections[i]); - lowp float intensity = max(0.0, dot(normalizedTransformedNormal, normalizedLightDirection)); + /* Attenuation. Directional lights have the .w component set to 0, use + that to make the distance zero -- which will then ensure the + attenuation is always 1.0 */ + highp float dist = length(lightDirections[i].xyz)*lightDirections[i].w; + /* If range is 0 for whatever reason, clamp it to a small value to + avoid a NaN when dist is 0 as well (which is the case for + directional lights). */ + highp float attenuation = clamp(1.0 - pow(dist/max(lightRanges[i], 0.0001), 4.0), 0.0, 1.0)/(1.0 + dist); + attenuation = attenuation*attenuation; + + highp vec3 normalizedLightDirection = normalize(lightDirections[i].xyz); + lowp float intensity = max(0.0, dot(normalizedTransformedNormal, normalizedLightDirection))*attenuation; fragmentColor += vec4(finalDiffuseColor.rgb*lightColors[i].rgb*intensity, lightColors[i].a*finalDiffuseColor.a/float(LIGHT_COUNT)); /* Add specular color, if needed */ if(intensity > 0.001) { highp vec3 reflection = reflect(-normalizedLightDirection, normalizedTransformedNormal); - mediump float specularity = clamp(pow(max(0.0, dot(normalize(cameraDirection), reflection)), shininess), 0.0, 1.0); + /* Use attenuation for the specularity as well */ + mediump float specularity = clamp(pow(max(0.0, dot(normalize(cameraDirection), reflection)), shininess), 0.0, 1.0)*attenuation; fragmentColor += vec4(finalSpecularColor.rgb*specularity, finalSpecularColor.a); } } diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index 1e48b73c0..b7182d628 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -73,6 +73,82 @@ Common rendering setup: @snippet MagnumShaders.cpp Phong-usage-texture2 +@section Shaders-Phong-lights Light specification + +By default, the shader provides a single directional "fill" light, coming from +the center of the camera. Using the @p lightCount parameter in constructor, you +can specify how many lights you want, and then control light parameters using +the following @ref setLightPositions(), @ref setLightColors() and +@ref setLightRanges(). Light positions are specified as four-component vectors, +the last component distinguishing between directional and point lights. + +
  • +Point lights are specified with camera-relative position and the last component +set to @cpp 1.0f @ce together with @ref setLightRanges() describing the +attenuation. The range corresponds to the @ref Trade::LightData::range() and +the attenuation is calculated as the following --- see +@ref Trade-LightData-attenuation for more information: @f[ + F_{att} = \frac{\operatorname{clamp}(1 - (\frac{d}{\color{m-info} R})^4, 0, 1)^2}{1 + d^2} +@f] + +If you use @ref Constants::inf() as a range (which is also the default), the +equation reduces down to a simple inverse square: @f[ + F_{att} = \lim_{{\color{m-info} R} \to \infty} \frac{{\color{m-dim} \operatorname{clamp}(} 1 \mathbin{\color{m-dim} -} {\color{m-dim} (\frac{d}{R})^4, 0, 1)^2}}{1 + d^2} = \frac{1}{1 + d^2} +@f] +
  • +Directional lights are specified with a camera-relative direction *to* the +light with the last component set to @cpp 0.0f @ce --- which effectively makes +@f$ d = 0 @f$ --- and are not affected by values from @ref setLightRanges() in +any way: @f[ + F_{att} = \lim_{d \to 0} \frac{{\color{m-dim} \operatorname{clamp}(} 1 \mathbin{\color{m-dim} -} {\color{m-dim} (\frac{d}{R})^4, 0, 1)^2}}{1 \mathbin{\color{m-dim} +} {\color{m-dim} d^2}} = 1 +@f] +
+ +Light color and intensity, corresponding to @ref Trade::LightData::color() and +@ref Trade::LightData::intensity(), is meant to be multiplied together and +passed to @ref setLightColors(). + +The following example shows a three-light setup with one dim directional light +shining from the top and two stronger but range-limited point lights: + +@snippet MagnumShaders.cpp Phong-usage-lights + +@subsection Shaders-Phong-lights-ambient Ambient lights + +In order to avoid redundant uniform inputs, there's no dedicated way to specify +ambient lights. Instead, they are handled by the ambient color input, as the +math for ambient color and lights is equivalent. Add the ambient colors +together and reuse the diffuse texture in the @ref bindAmbientTexture() slot to +have it affected by the ambient as well: + +@snippet MagnumShaders.cpp Phong-usage-lights-ambient + +@subsection Shaders-Phong-lights-zero Zero lights + +As a special case, creating this shader with zero lights makes its output +equivalent to the @ref Flat3D shader --- only @ref setAmbientColor() and +@ref bindAmbientTexture() (if @ref Flag::AmbientTexture is enabled) are taken +into account, which corresponds to @ref Flat::setColor() and +@ref Flat::bindTexture(). This is useful to reduce complexity in apps that +render models with pre-baked lights. For instanced workflows using zero lights +means the @ref NormalMatrix instance attribute doesn't need to be supplied +either. In addition, enabling @ref Flag::VertexColor and using a default +ambient color with no texturing makes this shader equivalent to +@ref VertexColor. + +@see @ref Trade::MaterialType::Flat + + + +@m_class{m-note m-dim} + +@par + Attenuation based on constant/linear/quadratic factors (the + @ref Trade::LightData::attenuation() property) and spot lights + (@ref Trade::LightData::innerConeAngle(), + @ref Trade::LightData::outerConeAngle() "outerConeAngle()") are not + implemented at the moment. + @section Shaders-Phong-alpha Alpha blending and masking Alpha / transparency is supported by the shader implicitly, but to have it @@ -169,18 +245,6 @@ well to ensure lighting works: @requires_webgl20 Extension @webgl_extension{ANGLE,instanced_arrays} in WebGL 1.0. -@section Shaders-Phong-zero-lights Zero lights - -Creating this shader with zero lights makes its output equivalent to the -@ref Flat3D shader --- only @ref setAmbientColor() and @ref bindAmbientTexture() -(if @ref Flag::AmbientTexture is enabled) are taken into account, which -correspond to @ref Flat::setColor() and @ref Flat::bindTexture(). This is -useful to reduce complexity in apps that render models with pre-baked lights. -For instanced workflows using zero lights means the @ref NormalMatrix instance -attribute doesn't need to be supplied either. In addition, enabling -@ref Flag::VertexColor and using a default ambient color with no texturing -makes this shader equivalent to @ref VertexColor. - @see @ref shaders */ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { @@ -544,7 +608,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { * If @ref Flag::AmbientTexture is set, default value is * @cpp 0xffffffff_rgbaf @ce and the color will be multiplied with * ambient texture, otherwise default value is @cpp 0x00000000_rgbaf @ce. - * @see @ref bindAmbientTexture() + * @see @ref bindAmbientTexture(), @ref Shaders-Phong-lights-ambient */ Phong& setAmbientColor(const Magnum::Color4& color); @@ -554,7 +618,8 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { * * Expects that the shader was created with @ref Flag::AmbientTexture * enabled. - * @see @ref bindTextures(), @ref setAmbientColor() + * @see @ref bindTextures(), @ref setAmbientColor(), + * @ref Shaders-Phong-lights-ambient */ Phong& bindAmbientTexture(GL::Texture2D& texture); @@ -740,40 +805,77 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { /** * @brief Set light positions * @return Reference to self (for method chaining) + * @m_since_latest * - * Initial values are zero vectors --- that will in most cases cause - * the object to be rendered black (or in the ambient color), as the - * lights are is inside of it. Expects that the size of the @p lights - * array is the same as @ref lightCount(). - * @see @ref setLightPosition(UnsignedInt, const Vector3&), - * @ref setLightPosition(const Vector3&) + * Depending on the fourth component, the value is treated as either a + *camera-relative position of a point light, if the fourth component is + * @cpp 1.0f @ce; or a direction *to* a directional light, if the + * fourth component is @cpp 0.0f @ce. Expects that the size of the + * @p positions array is the same as @ref lightCount(). Initial values + * are @cpp {0.0f, 0.0f, 1.0f, 0.0f} @ce --- a directional "fill" light + * coming from the camera. + * @see @ref Shaders-Phong-lights, @ref setLightPosition() */ - Phong& setLightPositions(Containers::ArrayView lights); + Phong& setLightPositions(Containers::ArrayView positions); - /** @overload */ - Phong& setLightPositions(std::initializer_list lights); + /** + * @overload + * @m_since_latest + */ + Phong& setLightPositions(std::initializer_list positions); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief setLightPositions(Containers::ArrayView) + * @m_deprecated_since_latest Use @ref setLightPositions(Containers::ArrayView) + * instead. This function sets the fourth component to + * @cpp 0.0f @ce to preserve the original behavior as close as + * possible. + */ + CORRADE_DEPRECATED("use setLightPositions(Containers::ArrayView) instead") Phong& setLightPositions(Containers::ArrayView positions); + + /** + * @brief @copybrief setLightPositions(std::initializer_list) + * @m_deprecated_since_latest Use @ref setLightPositions(std::initializer_list) + * instead. This function sets the fourth component to + * @cpp 0.0f @ce to preserve the original behavior as close as + * possible. + */ + CORRADE_DEPRECATED("use setLightPositions(std::initializer_list) instead") Phong& setLightPositions(std::initializer_list positions); + #endif /** * @brief Set position for given light * @return Reference to self (for method chaining) + * @m_since_latest * - * Unlike @ref setLightPosition() updates just a single light position. - * Expects that @p id is less than @ref lightCount(). - * @see @ref setLightPosition(const Vector3&) + * Unlike @ref setLightPositions() updates just a single light + * position. If updating more than one light, prefer the batch function + * instead to reduce the count of GL API calls. Expects that @p id is + * less than @ref lightCount(). + */ + Phong& setLightPosition(UnsignedInt id, const Vector4& position); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief setLightPosition(UnsignedInt, const Vector4&) + * @m_deprecated_since_latest Use @ref setLightPosition(UnsignedInt, const Vector4&) + * instead. This function sets the fourth component to + * @cpp 0.0f @ce to preserve the original behavior as close as + * possible. */ - Phong& setLightPosition(UnsignedInt id, const Vector3& position); + CORRADE_DEPRECATED("use setLightPosition(UnsignedInt, const Vector4&) instead") Phong& setLightPosition(UnsignedInt id, const Vector3& position); /** * @brief Set light position - * @return Reference to self (for method chaining) - * - * Convenience alternative to @ref setLightPositions() when there is - * just one light. - * @see @ref setLightPosition(UnsignedInt, const Vector3&) + * @m_deprecated_since_latest Use @ref setLightPositions(std::initializer_list) + * with a single item instead --- it's short enough to not warrant + * the existence of a dedicated overload. This function sets the + * fourth component to @cpp 0.0f @ce to preserve the original + * behavior as close as possible. */ - Phong& setLightPosition(const Vector3& position) { - return setLightPositions({&position, 1}); - } + CORRADE_DEPRECATED("use setLightPositions(std::initializer_list) instead") Phong& setLightPosition(const Vector3& position); + #endif /** * @brief Set light colors @@ -809,6 +911,35 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { return setLightColors({&color, 1}); } + /** + * @brief Set light attenuation ranges + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Initial values are @ref Constants::inf(). Expects that the size of + * the @p ranges array is the same as @ref lightCount(). + * @see @ref Shaders-Phong-lights, @ref setLightRange() + */ + Phong& setLightRanges(Containers::ArrayView ranges); + + /** + * @overload + * @m_since_latest + */ + Phong& setLightRanges(std::initializer_list ranges); + + /** + * @brief Set attenuation range for given light + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Unlike @ref setLightRanges() updates just a single light range. If + * updating more than one light, prefer the batch function instead to + * reduce the count of GL API calls. Expects that @p id is less than + * @ref lightCount(). + */ + Phong& setLightRange(UnsignedInt id, Float range); + private: /* Prevent accidentally calling irrelevant functions */ #ifndef MAGNUM_TARGET_GLES @@ -834,7 +965,8 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram { Int _objectIdUniform{10}; #endif Int _lightPositionsUniform{11}, - _lightColorsUniform; /* 11 + lightCount, set in the constructor */ + _lightColorsUniform, /* 11 + lightCount, set in the constructor */ + _lightRangesUniform; /* 11 + 2*lightCount, set in the constructor */ }; /** @debugoperatorclassenum{Phong,Phong::Flag} */ diff --git a/src/Magnum/Shaders/Phong.vert b/src/Magnum/Shaders/Phong.vert index 0eb740916..038f4b1ef 100644 --- a/src/Magnum/Shaders/Phong.vert +++ b/src/Magnum/Shaders/Phong.vert @@ -77,7 +77,11 @@ uniform mediump mat3 textureMatrix #ifdef EXPLICIT_UNIFORM_LOCATION layout(location = 11) #endif -uniform highp vec3 lightPositions[LIGHT_COUNT]; /* defaults to zero */ +uniform highp vec4 lightPositions[LIGHT_COUNT] + #ifndef GL_ES + = vec4[](LIGHT_POSITION_INITIALIZER); + #endif + ; #endif #ifdef EXPLICIT_ATTRIB_LOCATION @@ -168,7 +172,7 @@ out mediump vec3 transformedTangent; out mediump vec3 transformedBitangent; #endif #endif -out highp vec3 lightDirections[LIGHT_COUNT]; +out highp vec4 lightDirections[LIGHT_COUNT]; out highp vec3 cameraDirection; #endif @@ -209,9 +213,10 @@ void main() { #endif #endif - /* Direction to the light */ + /* Direction to the light. Directional lights have the last component set + to 0, which gets used to ignore the transformed position. */ for(int i = 0; i < LIGHT_COUNT; ++i) - lightDirections[i] = lightPositions[i] - transformedPosition; + lightDirections[i] = vec4(lightPositions[i].xyz - transformedPosition*lightPositions[i].w, lightPositions[i].w); /* Direction to the camera */ cameraDirection = -transformedPosition; diff --git a/src/Magnum/Shaders/Test/CMakeLists.txt b/src/Magnum/Shaders/Test/CMakeLists.txt index 9781971f1..6850dfff6 100644 --- a/src/Magnum/Shaders/Test/CMakeLists.txt +++ b/src/Magnum/Shaders/Test/CMakeLists.txt @@ -240,6 +240,13 @@ if(BUILD_GL_TESTS) PhongTestFiles/textured-specular.tga PhongTestFiles/textured.tga PhongTestFiles/vertexColor.tga + PhongTestFiles/light-directional-intensity2.tga + PhongTestFiles/light-directional.tga + PhongTestFiles/light-none.tga + PhongTestFiles/light-point-attenuated-specular.tga + PhongTestFiles/light-point-intensity10-range0.5.tga + PhongTestFiles/light-point-range1.5.tga + PhongTestFiles/light-point.tga # For zero lights test (equivalency to Flat3D) FlatTestFiles/textured3D-alpha-mask0.5.tga) diff --git a/src/Magnum/Shaders/Test/PhongGLTest.cpp b/src/Magnum/Shaders/Test/PhongGLTest.cpp index 76217abfb..a1d8cafa2 100644 --- a/src/Magnum/Shaders/Test/PhongGLTest.cpp +++ b/src/Magnum/Shaders/Test/PhongGLTest.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -103,6 +104,7 @@ struct PhongGLTest: GL::OpenGLTester { void renderObjectId(); #endif + void renderLights(); void renderLowLightAngle(); void renderZeroLights(); @@ -337,6 +339,93 @@ constexpr struct { }; #endif +const struct { + const char* name; + const char* file; + Vector4 position; + Float intensity; + Float range; + Containers::Array> picks; +} RenderLightsData[] { + {"directional", "light-directional.tga", + {1.0f, -1.5f, 0.5f, 0.0f}, 1.0f, Constants::inf(), + {Containers::InPlaceInit, { + /* Ambient isn't affected by light direction, otherwise it's a + dot product of a normalized direction */ + {{40, 40}, 0x222222_rgb + 0xff8080_rgb*dot(Vector3{1.0f, -1.5f, 0.5f}.normalized(), Vector3::zAxis())}, + /* and it's the same across the whole surface */ + {{70, 70}, 0x222222_rgb + 0xff8080_rgb*dot(Vector3{1.0f, -1.5f, 0.5f}.normalized(), Vector3::zAxis())}, + }}}, + /* These two should produce the same output as the *normalized* dot product + is the same */ + {"directional, from the other side", "light-directional.tga", + {-1.0f, 1.5f, 0.5f, 0.0f}, 1.0f, Constants::inf(), {}}, + {"directional, scaled direction", "light-directional.tga", + {10.0f, -15.0f, 5.0f, 0.0f}, 1.0f, Constants::inf(), {}}, + /* Range should have no effect either, especially zero range should not + cause any NaNs */ + {"directional, range=0.1", "light-directional.tga", + {1.0f, -1.5f, 0.5f, 0.0f}, 1.0f, 1.0f, {}}, + {"directional, range=0", "light-directional.tga", + {1.0f, -1.5f, 0.5f, 0.0f}, 1.0f, 1.0f, {}}, + /* Light from the other side doesn't contribute anything */ + {"directional, from back", "light-none.tga", + {-1.0f, 1.5f, -0.5f, 0.0f}, 1.0f, Constants::inf(), + {Containers::InPlaceInit, { + /* Only ambient color left */ + {{40, 40}, 0x222222_rgb} + }}}, + /* This is the same as above, except that twice the intensity causes it to + be 2x brighter */ + {"directional, intensity=2", "light-directional-intensity2.tga", + {1.0f, -1.5f, 0.5f, 0.0f}, 2.0f, 1.0f, + {Containers::InPlaceInit, { + {{40, 40}, 0x222222_rgb + 0xff8080_rgb*dot(Vector3{1.0f, -1.5f, 0.5f}.normalized(), Vector3::zAxis())*2.0f} + }}}, + {"point", "light-point.tga", + {0.75f, -0.75f, -1.25f, 1.0f}, 1.0f, Constants::inf(), + {Containers::InPlaceInit, { + /* The range is inf, so it doesn't get fully ambient even at the + edge */ + {{8, 71}, 0x242324_rgb}, + /* Closest to the light. TODO figure out the equation, sigh */ + {{63, 16}, 0xc57474_rgb /*0x222222_rgb + 0xff8080_rgb/(1 + 0.25f*0.25f)*/}, + /* Specular highlight */ + {{60, 19}, 0xfefefe_rgb} + }}}, + {"point, attenuated specular", "light-point-attenuated-specular.tga", + {1.0f, -1.0f, -0.25f, 1.0f}, 1.0f, 2.5f, + {Containers::InPlaceInit, { + /* Specular highlight shouldn't be brighter than the attenuated + intensity */ + {{57, 22}, 0x665656_rgb} + }}}, + {"point, range=1.5", "light-point-range1.5.tga", + {0.75f, -0.75f, -1.25f, 1.0f}, 1.0f, 1.5f, + {Containers::InPlaceInit, { + /* Color goes back to ambient at distance = 1.5 */ + {{59, 60}, 0x222222_rgb}, + {{29, 50}, 0x222222_rgb}, + {{19, 14}, 0x222222_rgb}, + /* But the center and specular stays ~ the same */ + {{63, 16}, 0xc57474_rgb}, + {{60, 19}, 0xfefcfc_rgb} + }}}, + {"point, intensity=10, range=0.5", "light-point-intensity10-range0.5.tga", + {0.75f, -0.75f, -1.25f, 1.0f}, 10.0f, 0.5f, {}}, + /* Range ends right at the surface, so no contribution */ + {"point, range=0.25", "light-none.tga", + {0.75f, -0.75f, -1.25f, 1.0f}, 1.0f, 0.25f, {}}, + /* Zero range should not cause any NaNs, so the ambient contribution is + still there */ + {"point, range=0.0", "light-none.tga", + {0.75f, -0.75f, -1.25f, 1.0f}, 1.0f, 0.0f, {}}, + /* Distance is 0, which means the direction is always prependicular and + thus contributes nothing */ + {"point, distance=0", "light-none.tga", + {0.75f, -0.75f, -1.25f, 1.0f}, 1.0f, 0.0f, {}} +}; + constexpr struct { const char* name; const char* file; @@ -346,19 +435,19 @@ constexpr struct { {"diffuse", "instanced.tga", {}, #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* AMD has one off pixel; SwiftShader a bit more */ - 93.67f, 0.106f, + 96.34f, 0.113f, #else /* WebGL 1 doesn't have 8bit renderbuffer storage */ - 93.67f, 0.106f, + 96.34f, 0.113f, #endif }, {"diffuse + normal", "instanced-normal.tga", Phong::Flag::NormalTexture, #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* AMD has one off pixel, llvmpipe more */ - 94.5f, 0.333f, + 96.0f, 0.333f, #else /* WebGL 1 doesn't have 8bit renderbuffer storage */ - 94.5f, 0.132f, + 96.0f, 0.333f, #endif } }; @@ -425,6 +514,11 @@ PhongGLTest::PhongGLTest() { &PhongGLTest::renderObjectIdTeardown); #endif + addInstancedTests({&PhongGLTest::renderLights}, + Containers::arraySize(RenderLightsData), + &PhongGLTest::renderSetup, + &PhongGLTest::renderTeardown); + addTests({&PhongGLTest::renderLowLightAngle, &PhongGLTest::renderZeroLights}, #ifndef MAGNUM_TARGET_GLES2 @@ -606,17 +700,20 @@ void PhongGLTest::setWrongLightCount() { /* This is okay */ shader.setLightColors({{}, {}, {}, {}, {}}) - .setLightPositions({{}, {}, {}, {}, {}}); + .setLightPositions(Containers::arrayView({{}, {}, {}, {}, {}})) + .setLightRanges({0.0f, 0.0f, 0.0f, 0.0f, 0.0f}); MAGNUM_VERIFY_NO_GL_ERROR(); /* This is not */ - shader.setLightColor({}) - .setLightPosition({}); + shader.setLightColors({Color3{}}) + .setLightPositions({Vector4{}}) + .setLightRanges({0.0f}); CORRADE_COMPARE(out.str(), "Shaders::Phong::setLightColors(): expected 5 items but got 1\n" - "Shaders::Phong::setLightPositions(): expected 5 items but got 1\n"); + "Shaders::Phong::setLightPositions(): expected 5 items but got 1\n" + "Shaders::Phong::setLightRanges(): expected 5 items but got 1\n"); } void PhongGLTest::setWrongLightId() { @@ -631,17 +728,20 @@ void PhongGLTest::setWrongLightId() { /* This is okay */ shader.setLightColor(2, {}) - .setLightPosition(2, {}); + .setLightPosition(2, Vector4{}) + .setLightRange(2, 0.0f); MAGNUM_VERIFY_NO_GL_ERROR(); /* This is not */ shader.setLightColor(3, {}) - .setLightPosition(3, {}); + .setLightPosition(3, Vector4{}) + .setLightRange(3, 0.0f); CORRADE_COMPARE(out.str(), "Shaders::Phong::setLightColor(): light ID 3 is out of bounds for 3 lights\n" - "Shaders::Phong::setLightPosition(): light ID 3 is out of bounds for 3 lights\n"); + "Shaders::Phong::setLightPosition(): light ID 3 is out of bounds for 3 lights\n" + "Shaders::Phong::setLightRange(): light ID 3 is out of bounds for 3 lights\n"); } constexpr Vector2i RenderSize{80, 80}; @@ -673,16 +773,7 @@ void PhongGLTest::renderTeardown() { } void PhongGLTest::renderDefaults() { - /* The light is at the center by default, so we scale the sphere to half - and move the vertices back a bit to avoid a fully-black render but - still have the thing in the default [-1; 1] cube */ - Trade::MeshData meshData = Primitives::uvSphereSolid(16, 32); - Matrix4 transformation = - Matrix4::translation(Vector3::zAxis(-1.0f))*Matrix4::scaling(Vector3(1.0f, 1.0f, 0.25f)); - MeshTools::transformPointsInPlace(transformation, meshData.mutableAttribute(Trade::MeshAttribute::Position)); - /** @todo use Matrix4::normalMatrix() */ - MeshTools::transformVectorsInPlace(transformation.inverted().transposed(), meshData.mutableAttribute(Trade::MeshAttribute::Normal)); - GL::Mesh sphere = MeshTools::compile(meshData); + GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); Phong{} .draw(sphere); @@ -716,8 +807,8 @@ void PhongGLTest::renderColored() { Phong{{}, 2} .setLightColors({data.lightColor1, data.lightColor2}) - .setLightPositions({{data.lightPosition1, -3.0f, 0.0f}, - {data.lightPosition2, -3.0f, 0.0f}}) + .setLightPositions({{data.lightPosition1, -3.0f, 2.0f, 0.0f}, + {data.lightPosition2, -3.0f, 2.0f, 0.0f}}) .setAmbientColor(0x330033_rgbf) .setDiffuseColor(0xccffcc_rgbf) .setSpecularColor(0x6666ff_rgbf) @@ -799,8 +890,8 @@ void PhongGLTest::renderSinglePixelTextured() { Phong shader{Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture, 2}; shader.setLightColors({0x993366_rgbf, 0x669933_rgbf}) - .setLightPositions({{-3.0f, -3.0f, 0.0f}, - { 3.0f, -3.0f, 0.0f}}) + .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, + { 3.0f, -3.0f, 2.0f, 0.0f}}) .setTransformationMatrix(Matrix4::translation(Vector3::zAxis(-2.15f))) .setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)); @@ -905,8 +996,8 @@ void PhongGLTest::renderTextured() { /* Using default (white) light colors to have the texture data visible better */ - shader.setLightPositions({{-3.0f, -3.0f, 0.0f}, - { 3.0f, -3.0f, 0.0f}}) + shader.setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, + { 3.0f, -3.0f, 2.0f, 0.0f}}) .setTransformationMatrix( Matrix4::translation(Vector3::zAxis(-2.15f))* Matrix4::rotationY(-15.0_degf)* @@ -921,10 +1012,10 @@ void PhongGLTest::renderTextured() { #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) /* SwiftShader has few rounding errors at the edges (giving a large max error), but that's basically it. Apple A8 has more. */ - const Float maxThreshold = 210.4f, meanThreshold = 0.202f; + const Float maxThreshold = 227.0f, meanThreshold = 0.202f; #else /* WebGL 1 doesn't have 8bit renderbuffer storage, so it's a bit worse */ - const Float maxThreshold = 210.4f, meanThreshold = 3.434f; + const Float maxThreshold = 227.0f, meanThreshold = 3.434f; #endif CORRADE_COMPARE_WITH( /* Dropping the alpha channel, as it's always 1.0 */ @@ -979,8 +1070,8 @@ void PhongGLTest::renderTexturedNormal() { exactly the same images. */ Phong shader{Phong::Flag::NormalTexture|data.flags, 2}; shader.setLightPositions({ - Matrix4::rotationZ(data.rotation).transformPoint({-3.0f, -3.0f, 0.0f}), - Matrix4::rotationZ(data.rotation).transformPoint({ 3.0f, -3.0f, 0.0f})}) + Matrix4::rotationZ(data.rotation)*Vector4{-3.0f, -3.0f, 2.0f, 0.0f}, + Matrix4::rotationZ(data.rotation)*Vector4{ 3.0f, -3.0f, 2.0f, 0.0f}}) .setTransformationMatrix(Matrix4::translation(Vector3::zAxis(-2.35f))* Matrix4::rotationZ(data.rotation)* Matrix4::rotationY(-15.0_degf)* @@ -1068,8 +1159,8 @@ template void PhongGLTest::renderVertexColor() { .setSubImage(0, {}, *image); Phong{Phong::Flag::DiffuseTexture|Phong::Flag::VertexColor, 2} - .setLightPositions({{-3.0f, -3.0f, 0.0f}, - { 3.0f, -3.0f, 0.0f}}) + .setLightPositions({{-3.0f, -3.0f, 0.0f, 0.0f}, + { 3.0f, -3.0f, 0.0f, 0.0f}}) .setTransformationMatrix( Matrix4::translation(Vector3::zAxis(-2.15f))* Matrix4::rotationY(-15.0_degf)* @@ -1106,7 +1197,7 @@ void PhongGLTest::renderShininess() { GL::Mesh sphere = MeshTools::compile(Primitives::uvSphereSolid(16, 32)); Phong{} - .setLightPosition({-3.0f, -3.0f, 0.0f}) + .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}}) .setDiffuseColor(0xff3333_rgbf) .setSpecularColor(data.specular) .setShininess(data.shininess) @@ -1180,7 +1271,7 @@ void PhongGLTest::renderShininess() { Utility::Directory::join({_testDir, "PhongTestFiles", "shininess0-overflow.tga"}), /* The threshold = 0.001 case has a slight reddish tone on SwiftShader; ARM Mali has one pixel off */ - (DebugTools::CompareImageToFile{_manager, 255.0f, 1.476f})); + (DebugTools::CompareImageToFile{_manager, 255.0f, 23.1f})); } } @@ -1240,8 +1331,8 @@ void PhongGLTest::renderAlpha() { Primitives::UVSphereFlag::TextureCoordinates)); Phong shader{data.flags, 2}; - shader.setLightPositions({{-3.0f, -3.0f, 0.0f}, - { 3.0f, -3.0f, 0.0f}}) + shader.setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, + { 3.0f, -3.0f, 2.0f, 0.0f}}) .setTransformationMatrix( Matrix4::translation(Vector3::zAxis(-2.15f))* Matrix4::rotationY(-15.0_degf)* @@ -1272,10 +1363,10 @@ void PhongGLTest::renderAlpha() { That's okay, as we have only 8bit texture precision. SwiftShader has additionally a few minor rounding errors at the edges, Apple A8 a bit more. */ - const Float maxThreshold = 172.667f, meanThreshold = 0.385f; + const Float maxThreshold = 189.4f, meanThreshold = 0.385f; #else /* WebGL 1 doesn't have 8bit renderbuffer storage, so it's way worse */ - const Float maxThreshold = 172.667f, meanThreshold = 4.736f; + const Float maxThreshold = 189.4f, meanThreshold = 4.736f; #endif CORRADE_COMPARE_WITH( /* Dropping the alpha channel, as it's always 1.0 */ @@ -1343,8 +1434,8 @@ void PhongGLTest::renderObjectId() { Phong{data.flags, 2} .setLightColors({0x993366_rgbf, 0x669933_rgbf}) - .setLightPositions({{-3.0f, -3.0f, 0.0f}, - { 3.0f, -3.0f, 0.0f}}) + .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, + { 3.0f, -3.0f, 2.0f, 0.0f}}) .setAmbientColor(0x330033_rgbf) .setDiffuseColor(0xccffcc_rgbf) .setSpecularColor(0x6666ff_rgbf) @@ -1389,6 +1480,58 @@ void PhongGLTest::renderObjectId() { } #endif +void PhongGLTest::renderLights() { + auto&& data = RenderLightsData[testCaseInstanceId()]; + setTestCaseDescription(data.name); + + GL::Mesh plane = MeshTools::compile(Primitives::planeSolid()); + + Matrix4 transformation = + Matrix4::translation({0.0f, 0.0f, -1.5f}); + + Phong{{}, 1} + /* Set non-black ambient to catch accidental NaNs -- the render should + never be fully black */ + .setAmbientColor(0x222222_rgbf) + .setLightPositions({data.position}) + .setLightColors({0xff8080_rgbf*data.intensity}) + .setLightRanges({data.range}) + .setShininess(60.0f) + .setTransformationMatrix(transformation) + .setNormalMatrix(transformation.normalMatrix()) + .setProjectionMatrix(Matrix4::perspectiveProjection(80.0_degf, 1.0f, 0.1f, 20.0f)) + .draw(plane); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + const Image2D image = _framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); + + /* Analytical output check. Comment this out when image comparison fails + for easier debugging. */ + for(const auto& pick: data.picks) { + CORRADE_ITERATION(pick.first); + CORRADE_COMPARE_WITH( + image.pixels()[pick.first.y()][pick.first.x()].xyz(), + pick.second, TestSuite::Compare::around(0x010101_rgb)); + } + + if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) || + !(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found."); + + #if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) + const Float maxThreshold = 3.0f, meanThreshold = 0.02f; + #else + /* WebGL 1 doesn't have 8bit renderbuffer storage, so it's way worse */ + const Float maxThreshold = 3.0f, meanThreshold = 0.02f; + #endif + CORRADE_COMPARE_WITH( + /* Dropping the alpha channel, as it's always 1.0 */ + Containers::arrayCast(image.pixels()), + Utility::Directory::join({_testDir, "PhongTestFiles", data.file}), + (DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold})); +} + void PhongGLTest::renderLowLightAngle() { GL::Mesh plane = MeshTools::compile(Primitives::planeSolid()); @@ -1404,7 +1547,7 @@ void PhongGLTest::renderLowLightAngle() { fragment-interpolated light direction being incorrect, most visible with long polygons and low light angles. */ Phong{{}, 1} - .setLightPosition({0.0f, 0.1f, 0.0f}) + .setLightPositions({{0.0f, 0.1f, 0.0f, 1.0f}}) .setShininess(200) .setTransformationMatrix(transformation) .setNormalMatrix(transformation.normalMatrix()) @@ -1476,7 +1619,7 @@ void PhongGLTest::renderZeroLights() { .setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)) /* Keep alpha mask at the default 0.5 to test the default */ /* Passing a zero-sized light position / color array, shouldn't assert */ - .setLightPositions({}) + .setLightPositions(Containers::ArrayView{}) .setLightColors({}) /* Using a bogus normal matrix -- it's not used so it should be okay. Same for all other unused values, they should get ignored. */ @@ -1622,8 +1765,8 @@ void PhongGLTest::renderInstanced() { Phong::Flag::InstancedTransformation| Phong::Flag::InstancedTextureOffset|data.flags, 2}; shader - .setLightPositions({{-3.0f, -3.0f, 0.0f}, - { 3.0f, -3.0f, 0.0f}}) + .setLightPositions({{-3.0f, -3.0f, 2.0f, 0.0f}, + { 3.0f, -3.0f, 2.0f, 0.0f}}) .setTransformationMatrix( Matrix4::translation(Vector3::zAxis(-1.75f))* Matrix4::rotationY(-15.0_degf)* diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/colored.tga b/src/Magnum/Shaders/Test/PhongTestFiles/colored.tga index 6d99eeb91282a36421d1637578008ed86cbbfbc8..7192259a0aa6849bb270b7dd6d03207f61730abb 100644 GIT binary patch literal 12875 zcmZvj2XNfydFDmhmTg(RQzAu?V($e+?{$Igz4zXG@4fe3ltu4_U;#*wAVIKqQlg}k zN#Zz;XD;OuU+!jZlHBEP4)^^5P^OY_-gkBZEcbhU&+{xW0RDLGwKraS`496N=Cw~> zd-2|T@4dPs;O(~y+3ySa@AJj)^F80?`o7DRzReDNn;m?S8Gex-`6fO3b!z;1a^hKH z@+o-qFxUaG9~UFv72@9)lHV87-{rI4<@4X=3g70szs>f3o9%m%DSeX}_$EF0b$a;g z)X4MX=(FV5)5OHn_~et=)Z^&%!^q47@GSjc`@n85xW6s>zbk~kD@496#JoS8#s(iohaN0k8^-0%;s_=Z-z!`D3{*W9DauJNnRi6zJ6W&6~kb^4-t`W(=b0h%;}~NioMv(yXi9DFsTA>cnsYBLxSy8XPs{J8l@C(t z2Pxfyl;M8Tct2^rpS0dj*zYGC_Y6*Hx{@X3*L=}??fYaBGKEC*zIuq zRycVpl)4#8-wb9}gSpi}{zjm1!(UwSbzk@OT=Vu`^Y$%!N>|QUC2o@Kz*rD;&NRj@%5zRzvaC zU}80xyb(y>2xM0L+3Wt?bzlCPx3KIjE_=GKx_hp;d#||qmYk)_j{ZxIfkpe^f^F!6 zb@;qx1?~)rf61Y+nsKZ-iYpLY^BT?@G|O67;VG zg4Y9~YyR*xf8?4ky6lTDdlOf^$*Z2!6;FD}omp~cFS~M=T=`4R!lI+NVDG+Y@3~;> zJ#XzhXDQ8_`_GyN=8S_ghM{TQ(4=;FTs<5n_C@eS&E^6?3FnAMx1^l z&RUIeR%86tm~b^FUX4muqw>|Lay6=6jcHe7`qh|mHEOyMG2aMVRzkLwko|hlaXsj| z9&ld^c&-J!%YNUoKXBC-yy^>G^@gu_BUe1JB~N_Gow)2yUUH=_xzdZS%%Ur|;L0yJ z3l|;53%25UYxlgR=d8JR&eS(+EX^4Dr}YDq+JSM+;FxM?STQ^(8}1VfW`XMHOXbmy zD^b*P40kO?x*nxnk1|%G?3E~YB`R2nh*lz!m8fhbrnr$%ucmdY8Nmp#GD?$Bj-_>wDn$rW34#TQ(O z1y^#xonG)}7yS7Je__E}yx=UJvlZtp#W_=P#@I7$=$+E{P3ro_wWTq2|A=Z}NHI7d z8|)JeLSI!N<>HGqO49ybaetB54}ETnywo3RSqyhx4kMSs*ehYel`#2An07VH zxEf+z4RfwW_{%BD^*+_jS<{1Su4nfGFK!3FS@b>`b==9DSE9z{pz(^|wB$2i_F67` zt(U#_OCHB1k8{!OT6DV?T%HA&_oCB((HXel2wrf6&O5^Aoze5&_=RX@vAgH$^w8?1 z$vaEacjhKm`-YYxy#Qgxn4i?;$F+q~O>sosJ*?^;RP^-Ad;6q)J>tHCpbz@G0qKXf zK2UQ$*t!scErt-6LYT`T{N)hwa)`1Nq%8%ROJVkvq+q#Ue)F>V@gIl&P7tf3!aC)mK$-y)qwu8&v40WT=bY0J?2HXb-`_0aM>@q92Z^A3r^Psr{{vh zd*0zYZ}*?G2j=a;d1rXu7dxNIEKc^X+?#py+okV*zw)QQTmJ6;`3K{pSEIf2w)~_% zH>$~vsPjXr!l1IyFE5s4-My0TqNpb?=*e(;pjT~pa~pkSbAkHvftCw_j*CI~LJ+kW z#4ZL2iviN50QFLkeksac>JhJ8GCcfk_|Mh`f4_F_-_|bvpS8(<`rG_pT=P9HS#HGi zOMcy=SGVBNFSrdC-KL8!^97gXg4255X*=(*pL00QIb7%L?s>as-sU}P^PRQ%=N!Q~ zUvxf`Sv)_u`WF|!S-bzcweSDi+V}ss_TVqSS$H%$ayigFW6X|fGDE8DfHK!F&-Kaj zz0!QQxKI!lv;1P3TZ}Ub0l*RZfu(%TUpMb>KJRb8;P1TPM_%-!FZyu{e!_yEybz=< zrr1l zd8hH5({#>Zo_AR0?bdm_{jAM#*5;hEy5_9zS&L`Z>YcIqXFQ>~RPw^P{*}L8c(L~E z@7I3!f7kwQZSB|pbM5}0-#L4$P&#J=Ea^dIx?hp$lVy6P*=|X;Aj;*0`3ygw`fAVm8s~kj=X|hpKKOYb>bwtg!H2)#Cte6q7Yf`fSGD*5Df;WR zsege$9scHACM6Tl#?lY6_s%dxKjHhYV(>CjY z&3U@!Jjgi@`m7gsHbOpM;#^tL-1~d~pR9HN?b_&nUmN;|f64s%iRa0L{(4e=(I=UA zN#-2VS-Wi3E}yX}W^Ae%t9sh1nYL=DEV?O+e#&f^G@B+(<_VK!!e|{g+Qtp`F@s~w z=p40r#{9vl-t_q!!#Dox;@4|;|8nioZ`W@B>7QP>KRa|WoE_80`{dDXNwgr2#EK}OO?O}aLTpqyF(k@MJ?vuwguIq9mMay3r7TBcp?GcMSS3qIpQ z&U!GjA>w?Ixi~Lbd189>JMVXY7yP3?_kDBIdT(64oRVJf3(q=*Gj`FmO+0OrOk1T> zR@szQF=bIsT2zx}^@Le7VbYG9bmJz&xY0OfG>sX|qXx^U-a4YU4eRa02IsKFJ>m~e zbf?ZPl$M@N-ukoo``^ypULL(t>Ynu`hqaL&S-2n$=S1O*Fp?5Ple}o08;i1IA!a;4 zk9#R`=LQ$_*zkP-3GB5rcT0nh-`4_uC8BetVM z_LC#_Go$vZF-P5)qjB8PJnm?laCA&Kx+a{6NjG{bfS-v`&Sn|s3hWCx&iMpqKFFSR zv!)!ZNgI2@${DwC$1VJEvtZmT95ai?Op-B^bkrytHOfZ}iV=fy#Go41YlijOA)RhW zrytZB2DQckjj3N_?pK>jYHLYjE9spji)X;)AM%HW1Cb$jc)$|u)%uHaUry{x3wz!GIySi=wssJf{pgVO$e```pzZXqtzy_#Gh(YB zwKa~~TE=W`V>Z~By=%;Y9Cx87Jh(|8amr7g@=>PT)JX?z!bTgn(#I^!F*9q_%pNsy zM@_s@6Mw`g7%_@QjN)N~WY{1b(#wYQ@*$mKP^TKysRy*00j;)Qqw81eOKL-($_S=c zY3fm0dQ{dPwY^8{?9sb=^qy|5r>OGeW$vulofdkM0#BUhjd8tEjxWsi1(|+7!|$a9 z+?0TW6tI#*b`Tt(@^2EhgUA4y<#4~{XutL3fc4CvwQ9&(Gi-VH0!M$R0LwhK<}I18>M67}5&| z^`b$&ct9r^&`AfhvVN_iU!yE(R3){#Pp#=wX?s<=9;F^kx57}A8;f#NL2k**t$DdE zC%5Nhj*P^S7CTZxXF}kN^ITD`JHl~?*q$KE<7ariG_RZLb&!2FlFzaZXnU1z6YX%x ze7MhiyktJzZ>botR1H{a2QBr3mZl*~%aEmg$O0R(bPZV$!xq%A1wCxW4x8~qCc==3 zG-M`|$Dl13a&tYoSvnX3Cuwf&}s zepAzcsb#>_K45|km^uec@BtHYz=$3&Vg`)30Rw)(KpZfT`t_84J+)s?@7FQ4hm=K!c0&|RSj`A!Kt~JE51=+R$)9z!~J#>eg=5SIRc9PRVaGKTu%>Zzd z4r(XNvYwi0oz8f$+igVy*I3zWtnM?`^%)!bj7=qDOUc+)GIW#-oh1Xj zWI&b-sFEI2(ql_{d`U;>(~Y-a*G^>MRvy*KWqRm9G8zDxQiRdvCy%3{slM`k>)CT||x`Rc-fr9>E zUVpTpKT$NC?lzq1HdOW)s(TD|J^F?oeN(T#rB~n9tMBO5clPSLdUc3i9jaG{?$u&@ zw74EEp+`&X(U5vHlx_{RTTSa$(~Bx*QN=2%*aao0pycKiyu5;+lM8ZkVOA!}%ETF| zBqNokC9;%6o)RmPB4t9PiVM|ofjY+5METkXPZ#FuLL7aNZSb=UKBm#jFuCa_7tQRT zm~CXUg=jJ1Eqc7wK(HGK4kLu=HowXU%DDlk2Y?6iy8T(*p`7kmUUxFDJ6+I~7j%_H zT}@F}SJX8WbxlQGOSi7ATiemCg>`GYy0wU+23gdgiyBN(gDa}>MKz(ICKXiVf{Id5 zQS(ZAUdhNSm^lS2Cue8noUELik?}Gzep)I>ONA+kC?ysr#gc?bnh?q2LU~Lej|vnK zzB0^Hg}LewR~_VN0&K01rS&p(9){jU*E^{OJH=ol8!aTGiC{F~Ogg+7VCo4r2onVQ zDx(p^cW|BVKn?(E_h&Q*(%K^#?Xj%(WL8_2)0XG7Re5bqUR#&fHsm!;c}+`R)0)?` z=QXgrx-+ka=heu(8kJX}^D1m!h07`NIVCZtBxM!ktb&r2(=u{;M$X8{m}wa+EoG;q zoRox{l<<;benKpWi-d8JC?*s~1rjh3zBJ5}g?REHR}tVS{A{I|4q&yo7rGA~Q+VJh4Vg^R9q(v)_p%0^LJ$!ar6VR)Bl{Se>2v>E{JO{n(9Rr?dFLkZQg{+8>9T9NC0&a-U4e@wE9zVbp1UN!JN91FRyezSYDRDEUE{4=empN!M zJ5_F_C@f@!iKsLZlzO~Ui&LpFDiwsORpa!U9|C=q5h~})_*CnF$~`f~-l$@KOnE4# zJQ`OXk1J0llw}EJc|uW{P*f)swMj*NQqho9G$rLNNqK8h-ky-d60**OtSccyB&5i= z6cv}E;}UFKf{RJ;F)<+~CPqc1sE8a9QX@iISU?X87$H702!_WB@Yn$^$Is#VI6N<# z?_q%vxS2v1L*%5395k_=Cb3c_7K+qNk{XFJ13{+4%QaZJ8Y5R?6iNtFtpb?qfkLFO zGOm{s#Fqqs$~|%Ao~Yuhi2SRtd~aC3KO#RAkspo9k4NRFV)C+>ygVkajLEBG@|u{e zE+%V;$r@v_=9sKCCT)vJJ7Q8;Owt*Zz@rjGRE&&@Q4ujFBEm*QxUdi(77{{2Vn{#= z3dlh|CBUZ!cr-tk?&mUm9Hy7U^0L_;7RSxvxR_iggXf_0?R374Ca_Y47K+eJ7MVyQ z15vCeh_yJ01}jlvBnq@tj+QAPOr;XSTn`kGzRI{>PN<(yd@liIyF=35LD}A*Y=200 zC?q=?mK_hvPKITtBhoVwX+=a@6_M6Nq_q)geMHh2ku*glEfGm;MBE-0cZ9{Tu&666 zf`>$ikPsOXqJu(AP=E~zZ~;C(z$f^5L_d$@awI4@9+aF6N=^qQXM&RQkfbsst`3Q7 zL*lxSxFIBN3W}P8qL!ejEhuac3OfSA&VZmRAb|S?2tOa`=c9c*jE{%)a&cZR-oqhy zI7By_m5>M)_MF}J*p%eumB_K;VS`Ok|=Ts_RB?M?*P|Vhi;5OjIyL{p=J>uP7@m{ZZzfXL~ zCqCj6AM=Y(_(iAuqB6gz+%Ky1i>myh8o#j4FRb?q8~ws2zo6MKX!Qx&eEfDFALiwE zdU;)59^Au4c(_Op2j%9V-E6E23=8LE;T=qZgGsbANHzx9MyFV5R11}ArqWClx{=H< zkQjO*Q%7KG2`mkst-`XE7>*pxk)k*fBv*{&iBbG@#6Ls{QG$7uPySV?9kBf&IEc+F z`qCr%(k2k5*PBy~HMmkt12NP{)V(bj8je)b$@m4y) zLL-`~L=%-{qL7Vbih)GYlc+i(O-rDu@pKiAp~Ny27^V!(lp>j81WSlui;x@<#0elb zq7=!X%7Qc{@=ZeM`$I3ttQBe`0NdpSxov{&bP9Gl_&Xhf-44NCr(nNRaL^?*ChCxD76Dqm$F*g@!THFeWP2M8z2?cmtWBClPfdqLxU~5XfpgS%sr0u@nV{ zDo4|#D4GOG6CvmVI75J73O6CwlY9kI3YcDgcjyIBt?N`!V#4*r1UsGlFC6?Y?7ST| z-cB2Dw~e>Q&f9P29klZf*?C7CykidD2?zI-gIng{o^fz19NbC=r`o}(v2$we?0P%9 z!Om{9v6^kH78|qG%51YT+pUZa3j=1Rcbe&4CK}vCMHs0_0|jNEp!H;oj*Qijuv#Kc zL%^%?com+Y#1Z9Kq6|ZlqDc}IS&SqL;S@fc!h_TJa5^8cLC6+vX2^qL1oJ8zAZmrO zdPybNp!&kb+hOJIuyD4UIXf-f-4^a1D`%gTbHK_uWaS*Oa*kR#$E}=`R?cZFyUfZi zx3Vj&tST$3+RCc2FzYPLdJD6`!e}%zn$3(BGriSBZ!^)_jkFE}6=tAz>M31%GF(SS zXh~p@8X`(fK&$W=B_5-|VdYqy41<%R@e&kXj3fvV1Oc4L>mqWxNZc-fN8KP4K!i|B zg$U5n^?8NO2VPl?AgF(b#NA=$Y&WsD8=={0V(&7szcR7+n%MhI?1N_3VKeKfnRU#} zI$>s=GP6#bnP<$*auc({#Hcbcs!fag475fAt;s-b)>B*blvW+3O-pXq zk~=gcn1-6sj~E!o42wO&VQ&{7(; zeV>-TUq?TvqaW7MkLu{hbhHyX+DR?#l$KhirJm7J%Qcir4W&v$sn(Ed)Z{uf zsa{2DP!SuH#6|_7NkM3q<6C67RvE5Mifxx*I>3n0Fd?c_fb8TWx_Iy|ZWo->31`6& z%nk$thGM|bOc;i>i3Kv-s3gE5^FT4dyaLn;DArjv3bz@~1`!hweWsyrQ`5JpXxo&u z&sDS?D%wsJZI_C+TTR=ertVWy52&e!)YQXj>QOc2n3{4zMLDS=pHh*_ROB;CQn`{; zp(Ir)h}8;Wjhs*`C)COC^)g(86xS%hHh~dinnmaq5xP}~Y7-#a_=t8cyq(k4!R~~y zI$=y$C%vPS*3m`pfYUpWfR6bix{Xo-Kq3dUbCYZRS0U`r4I4!RUHdT(L`3^kMg3Gs z{Zv8uL{8Zzr+hA_?2uD-Dk!@Yl&=(&y$bSv1^J+Yd`Lk)tRNj#kdDbo$K}M6a^fjD z@wAL^Mn))?;VY#0N-3^Nf~yu|YsA=E5vERrsTZOf1gJ(n7-SO<(aeQ6bGlksovqBy zRtBt%-qA*DZ>O|(P}^Zt2n}!{{v+CYC2?#(1ihFbqAef}P%|&sdZ=rg$v`NyA5cD# zkw2D_K9-O^m5@G@khV)nUr0$`N=dt=q&-s7J}Gg(lz2c&JR~I?mJ*Ii2*)J&;}ZNy z3I3EAcUp`q6JgJYu;oHbg%DFIKv(fm)qGS94_V7a)^QQ_9C$sutAW+o!0c?K!gN?S9jt%cmyMtO-v`w`X;p@CMSn6CgegIdwIfiyNMrlx_Gy&4N(`DC5tV=?g~ z5#b{t;S(WYn~3nah_FLM*eN3H5)r-<5%!4idqw#DBK!dn?vN07Scp3!#2yo3j|;FT z1elWo%qc$lG!IqAL!IFw%Q?sj4x*9`uVTTgSzR^E&Kd@+mJX|>cGOYY>&b2Pq}B#P zYa_9>i3D-AzRI;8SJ!%C8=-;Ry6Brk(Cv2Hk+U(blL5Kk4BLV(HKK?@< z?qfdgQ$Fr9K5jc7_XQvKr2w~!kKN73?%`wi^0E7Qm;*e_K_2=r4}FA-KFUQMkzf`Fco%$0y|3XI7aR`PHI0v zY&%J4J4I+cg=;yDZ9a`@DnmD&K{uCUnkylimJOQCd^SqA**h=j-WCwpW){$u8(Rn; z3czc?3$|>%KTw5mo909Qzm(2Iy~jYlOGmy-L%vT#en>-pOhbH1Lu{iVKBvLA)8IR( z@SW7IFR5L-sa;=DI`>dI_flZ{$gusSjsv8QgT(ejgto(kwj=n~qqvr1*p}m%=Huw5 z6R5@$$i|b%rqifRjEYT+^-yq7%{FqWCwN=y30qp~2tYOD{?XE_)eIg>K%1YTk=% z+J|V|k7zsqZ#d9Zf3UOuP-ny8t{?((gs=hN18TQ`W^H;6Dc%a)1L{B(d|;2Q z3#DyXi+Fe4+IL7@8$#d0!`{MmyoK#}6Vv_{ru`jE`@5L7_c3iBpxZt|w|c?Yt22cqcKJ9AU*4gk`XT#^P`t2Qc+uQ4Q zwAFsmRS%nsqv73- zhW9!eKIo|bu)Y4Hwz`koYCmbM{j{a#)8^`JP1T<_Rc~*u`J$y}XG`suKsZp{2B}^* zydE-qT{!Uk(7N`+T|g%o@Bp9^@)o-Ga%<}w2#_+!`p8QgU#9-=%zOjh@0U)V$$C+K3bcd10QUhIPzZSnUF&rUoCc-_30Nh4oc z*wwV|;;Z`VUT>~_y{YDBjWw?~)cm}m`j-vWzpAf#v%c!By2`g}E8eN8c(MB2aMeApf!8JcJc->>D98f=?mh5T;R6rTzBXkAuPrz9~K=T`2AWtvYL+g(H*tA~& z(^`RVf6(=_`s$z7RsFQK@+UQwKdY{Iy}IHT)#bmaD*t6=`LC+V->R;7`xT9lpY>Ir zytEX^1RB8rS2v6W-tK4y+AH6$1Ck))vS7D>LqTL)Hk|Q+yI(Z?LCJqErs5}6420-&qiplist z*8HrY?)4@>?*qFN+y&{>f^>e?Q2o+~DqzGjrQA6#Q547;p~^cm(uE3eX>1^n*8{Tj)sN0fq@K A(*OVf literal 19218 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 E5BLWbmH+?% diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/instanced-normal.tga b/src/Magnum/Shaders/Test/PhongTestFiles/instanced-normal.tga index 7b2fe00b4106bb2eb3afa16c59e4e62156428fed..b8db63113d0000c2aba941c02b7fd79939c255c2 100644 GIT binary patch literal 10289 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 iCjGw?9ArYw@4Ys literal 9875 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 literal 8962 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-directional-intensity2.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-directional-intensity2.tga new file mode 100644 index 0000000000000000000000000000000000000000..a8299eaa9d3195630e80a612045f3e551f489d4f GIT binary patch literal 850 tcmZQz;9`J*0EPet35N56f`a&PJ5YXqTG}cQJ<1*phmn>B@Z}AV8~|Y``y&7V literal 0 HcmV?d00001 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-directional.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-directional.tga new file mode 100644 index 0000000000000000000000000000000000000000..c313c2cd2c8edade211e457af1f4fb446d993035 GIT binary patch literal 850 tcmZQz;9`J*0EPet35N56f`a&PJ5YYVi%S}a9%YY)!$?a5`0@rw4ge-^*&_e| literal 0 HcmV?d00001 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-none.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-none.tga new file mode 100644 index 0000000000000000000000000000000000000000..d82fb25b8e301763a8a6e85f476afb1ee1605a1d GIT binary patch literal 850 tcmZQz;9`J*0EPet35N56f`a&PJ5YYVl9CdL9%YY)!$?a5`0@rw4gl+?w<7=m literal 0 HcmV?d00001 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-point-attenuated-specular.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-point-attenuated-specular.tga new file mode 100644 index 0000000000000000000000000000000000000000..1352508f9ec5c5db5f8381e17198b1f4b19617aa GIT binary patch literal 7885 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 Y&9k%{*rjcG_5t_yoqLD<{9 literal 0 HcmV?d00001 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/low-light-angle.tga b/src/Magnum/Shaders/Test/PhongTestFiles/low-light-angle.tga index e26497c00add67ef6f410eeb4e258501f5342741..04aa4057f9cbb9e729ad658107942c74b2d74d13 100644 GIT binary patch literal 5746 zcmc(j>2gy?5JqJT2E53YEz1@*1Oj2-_a%f75)!s5UTOMXSy2>4NeEerA}NXo$}8o3 z(^txHB@3KC>8hz#_sn#k`DP?nxl);}4D5O3d1bxQxO3;ur_t`-z57|Td-v{r9_{}9 z`(H$R@ZiCh(Y}iI@ZrO+qkR+Y(W6H}E{7hyaR#nuFE>QC_i*UQ022i)-r0KSQRZ? z6eLYSQ%S)C64d7P>(`xl6xwgXW%gG=U4IqZK?}%uk~x5FK;;!%NmGF?rJ&9_diM_M zte~!4yLJtS4P|zv{TBRfxYGWhhR=hB*ih+sxm>cqS^%~Hl^=jwarpvWo(xKB?imbh z2nr#n;p)|^>y8ZXPLW5Y7PUd$m&~G1CGI{v9{e|C+7GEC6Kpxm9hl|g z84@`Iqyasb{3|p;%@hg@XBXncmpK@w2P(pIlTN) zTsQ%4oIij5!i5VvMfaaO8alcplXM2RA$Si&dBri${Aw!cPBB3QbnV=^b2#k1$iv?a z|FPo>n<7WKU^19<7~8PQE7n=8kh7k0mcH@ZDe9;&0vpbrJ=-WjyVN`peU@K|pWitIDI|>8+Ue7$&zw2q!DM90 zIWi3*^gDl7L?R-Q9r<{_=8oFy@#oq!4^u;J9HQ%#3#EFw9PkN9-v(%x7 zkNN|-#bjV_6>`ffwlS==ly&UwmvBJ^I2=EIeAU679dKtKzLJvQ&hBq*__G}qLpeji z9J)4?@`|OX6^aJ-EvMIxs;Q)|sxu%YNEmofVjIVf9s4920a=Xc_X_S0CDj~?chEBs zyP(Rar~%Z##z2VxXVou$^zNM!9>AOs)Nu6Z(MF2w)H>1*sl{PH8`M3dl#g+VuQq{? zp3avdLWmtWa^%Rz(Fg!enI&?R*_r)n{3(@Qh`(+ZTcTya^?;VQM8p83el!DB0`(Ts zi>6n~2MI{d24pyV_;8RXQ-3cjbtmBJJ`LJFX!1r}M$_+4;NStQxd~h#L58g!I&|ox zXdW|xK@03C@7VVsNhFOSks(!IoOs1Cula&&$>ka)qZduRyOTH-cx#)Rn+Fdb_fllMx(J7P0c3&mf_+fe(z;7aOQBY)sfQJ3 z()qO3&~eZsr$?Wf^0B9SYkr^yHMKvoQZG=~78e&yeoXzWsGn1(52L*5#e8x0LA|)Y zs25qQ)#|v~84MYFb87dfC9hcdakY#(s+Wm(VPQdWRxm54v*etq#r`gJ`9jiOY}(k-@hnU+@^ zTQHxqPFpm^=%~W%>@1m#q1l{OTQusa3SM!{Gq0uW_?Gb-w?|y{*^H`Jv~kMCqo~}ykz{&cugq(2jkVQUAv;^^KVmAQ?E47 dc)@4+zZiW!%fDfC`8TipTSlAD@_+vi;~#jT$g2PV literal 8325 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 Z*zTfMI(P0I+db6MEw|hf+w=d2`fq1-1l|Au diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/shininess-black-specular.tga b/src/Magnum/Shaders/Test/PhongTestFiles/shininess-black-specular.tga index 1a439c90ff489ad8821fba31a31fb5f2fbfbda54..6aae4829c3f272d8a60b58e8049cee1671faa480 100644 GIT binary patch literal 11478 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/shininess0.tga b/src/Magnum/Shaders/Test/PhongTestFiles/shininess0.tga index 704c51993cacadf3d16e888c5a960b10364b43bc..7a907c2834b624d19b9bdffb20054b2e7619539c 100644 GIT binary patch literal 4773 zcma)=_mdP=5XX0CbGY4|O}BfAEJ;KJMGOd-P*j47m=&wUDogx9e=wC*cVswn6i}(M z%sKoY{zu}cyWhN>-8(3*w(E9h-urg?cE6rUB#MdXZ(CwpqLcVH48yow(`U> z=l{spuaT?BSuO>0=3JeaxWKO~$QL4Vb!=>Ubo2nfE+H3@FXigU$i8m(Q+~<%^T;)> zrn=qFJDrc)?Y&$$hnz*e;YOOP!^0o6+wV0RZ*c95lW*mo-q_n}?P)Y#*rysp?hG_;{mxPt}9 zoczwBe53Jtz5Y@dKIa#eO84gTOIUN%$sepMV2%3oY_0Z8r6ORg123B$W7(1T(s~`U zUcfbM$1+=5EZ&*REpSU^`JbQ`RW%-LuU4O`R36i%>x#uy7?4i4S#{X$aI0T5L#x#% zE0srMtCwc8<8HO=_zUb(%m&PTxLjV3#frT&mz$SLu`WF1Jw&9xqM%#bT?ti=ND(QbJ!CE1-D1`{ezyN$Xz1i zty*0utjOnY%VsC=I|!sCSS}QfZ9|Xw?QL6CC@jzA7UF$6-3o$I|2FZeQmf$-!Ic=m zwaCJi`TQ~xlF5vw(~Z8JqEzgxs$(c5Ehv0Yqi1$nJVw&#x|wQf_dAPqv+1l<9#Nh5 zmrC~#`a+ zisn$lJ45;6TyDNbtDQe=KOJ3t0fBoD2IR7f82;-t1ooC*iS1zh{AF zuVgOl13)&5hy`T87)|)i1=4rdY!*~CiQ+{ZL&_BlBahDlUaV0&mcs%{irzsaup^Zk zN+!jT{V_WfgD|Kg8?+kD5okoMz`=MVu%l?c#4)6Gg&GW(OihRPW!Y?YzzK0D4kMj1 z)R6eB!e~iK6jrQRK=EcWmKU=o1I&S#M+&3Nu#nJSXh?*_JR-NSYp#!q5)5mC0T^lS zIA#2p85na)Sf0sr;3+I2M;4odF>8KxFj0IdaN;`<8=Rup%qi*(x`oS4*kq-4TZ*4MC3UM$9{G0?D#QLBT`GT7*QL1|1Z$qV6K&!7N}}okjtlJ7ZE? zYonJwu`B}n?&e_h3InqYj%uO71(@lQcr*r14*cJf3j)GI9l-&PScjCt#mPhV{7Pz`}kX9I3L1cfR;3H2T_2RYVhA zs@;Bnc=$s;Xb{qLIM$;;F_gGKX|tM{U#n<}khh!_^jz^Ymx}xAwSffsfYfXiq&;PT{(kArB&$vWusgDP#fK>vbLl(7sb22zK-bLJUy0 zT9R)R3p#`&RFvmd)Ne~Z9AZQCAQV7Uyv64!WS%;1s<-yLZ$#dxwTO1(GAFB*qxB~r z0V-0G5jE&q)TNk*^9U?J_sr-! z;`xI0&T~3z@0Bq~)Qf6)vJBv{>exI9yT|pb1saXSnuaOOL2JsC;xJUV`gQ#+R>C** z`3y=$p*-^jm<}{9jj0km;|I?%1Qu1qma1B7twM=z1T$^EVfYC5QXF}iIEyyXB+uaE zP?K;03bZ-`y7;0BygMuOBqW8@ujz z=YSOIiN%5^uRa1OiqUl6DWsxbnchL@Dsus$bJ6j=+dU46ZGs`MRs!a9mg2?~VqY0c zWTOtMRKGdpY`7qHuutCCU{jLug%&Z1WLc@lIf}B%SF!mbB5UQX&m`Yvk9l)h?s8S$ c5?$fD{FnDg=lL%G literal 19218 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 literal 19218 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 literal 19218 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-ambient.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-ambient.tga index b67b086f4e920bd4060ea1e796d2ad89816c34e3..fb0215875652a745ba23aff2bd029257dba09d4d 100644 GIT binary patch literal 9728 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 BTr~gy literal 19218 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 literal 19218 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 H;R*a3P14?F diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-diffuse-alpha.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-diffuse-alpha.tga index c541bb420bdd8a0247a0cd308b6b9dee70820252..fc7b0183a0a5326bedd00e1220095b94ec2946d3 100644 GIT binary patch literal 11206 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-diffuse-transformed.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-diffuse-transformed.tga index 201778990f0e193bc4edcc500b788459d72811c9..dc8346477e42bff6b4696f1ecc4402d24c5a959f 100644 GIT binary patch literal 10527 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 UQ+P$k8{rd}({c6}AL;!6013MS%>V!Z literal 19218 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-diffuse.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-diffuse.tga index 1b0ed212b9fdcae1d04ea78a8493dad7c278c0c3..68bfdf5e2c9a748242ea647935e7c989a94abe76 100644 GIT binary patch literal 10965 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 GZ~lMKeHg_6 literal 19218 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 YD$E!?`&C?i^T^FFaPtfN|M>#{2VAr6Z2$lO diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal-left.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal-left.tga index 7bf697376894d53f321c8807a097917ac1fe1e3c..2770024f8d88ab8bdb12fcf61bfd0589dcae550d 100644 GIT binary patch literal 11101 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 Jzg{Q*{TCMd6CMBn diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal.tga index f6d72ad7888216be9ee81f527a8894f4e3829641..d6c1b5f768a2317b65c0c83346e03a169ede0db4 100644 GIT binary patch literal 11121 zcma*tXRuXQ83y1RNJs#MFlx#Kqs%Be{8A@qjEKKsh6yl~peXxU;>Brmvs{1KzkmOhEnAKnH7YABYv# zI(F>n(Zq=pIbeYUz#y12XU_Wd>#c-|zWL^x`t|Fl zeNAvJvU&4nURZnn{Q1d~Czmf@zIX3lxLN4ix9`}oV^Nwqb?Tr&gQicPK5pDN9~oqp zJCJ~}-P18+#*mCm-+lL;mApd>%(ZLRU<0^Wvu41zYSpT4-MZKf8#Zjlj2USp!(2b( z&K6Jy4<3B(+&NnDJ8RY~_6>`Jj$m-KW5*6RTeoiQ)2EM(vuDp9I&`RIt5>haV&TGt z;NilrjWBoX)-Ciji7d@w#?g94&>`dBvjQ$^CK79E4_3K587L6Z2{@ZWAZPTXBfB^##htRU_-Me$=rcB*eVc~`d0@t-`SJ8*3kj!vF zj0%9tEr|t$(3+GA?7BCPAvaQi1C`hT9hdJ_U#LC z`}OMwV$GU0OO+}mZ)BDD+0wIT&#%7vs%g`vq>=g%qD|8PBMHEhaNNNR4;QdemVAV! zFL>+(9qd?$VkIJhBpi*fb1yR}#Rwu4Pe9G5Dp=qSPJ%XX-ds4bG(4ZI)8$OZ{v+!~6-aX2J zi;}@d1mwVh16rJl9`FJHcN;RC0f>d8g# zO=)`T)-4x7Q|!E;7w~XHSOA4x;m8`U2_)3Ph^$P~ojLfiGowt9Vgy=cC8{C}gI&=- z=?-m9JX1<+*^)q<%Ml@ls)!o`vjxgqD%B-Nq_eyC0CkZSq6C}=4i;OWEF_LD`jgbe z5qyt@+Xj=Mxsj0sMvh<-MyG+4IYVmMf{-ME#@QmfkTZGx`gJqr6Nn3|AB1!oM56(? zXE{1nbOlW0q|#M{4I4HjyIobQR&|Vg{q@&K$`pZ$b`@xCQSd?v62OMMWyHL4%`eAX zY*V9DebdlvMk%<7g)k}81l&K?s#VKIkI-P0OA!a1hiOS@)7)zS-X9LO!_**tsp?1Kjn+;}7sqOX~^Z{ME8NQz~kwV0+-T_H#h zlk(@k(f)!Lb}X|IHenD#W#-TqGd6|OBfEeXY(&f`4d7J=oVJ7Kqs9j0rAwErWRPec z`3)xR{bt5TRupKj9!V&Ew zT&fuZ85Ie6`SNAutB(U~P!t1xX~VJ`sS=%yohVaqf99Es!09dIwVw}Y9KI;qKvK-e zqC9=1n{XSRVv<1oV`P*LQ=GBMf+)C=XV8nj`MY=Tn(5{*FKRCEBSHaviwFMYHvH}# zJa2p7aAAivt3L>f0KtuikZT!o)GL=laStwtfQl<;Iz`NQs!Q;eK>R+7QP$R=ExKYU z5zVVkeB5}%T7dAea0q5Ku08|ou^XDf42q>r9c@Lye*gXVXadBpFtG(OtZpO#xG+f~ zkMP5XS4xYo1hR!JwkHt(K@Z`D3Q9Q6GkFq-Rfb$r=K3<%@IYlK9gp0YSCNwB_U+r2 zNmG8+ibr%2QaDvSNG#jMf~U9`3egrHS+G%7ixF`RQlRrrRG-a2Fa&gOf2madTqsO( zLmISIBF@$eE`dz)8X&y0J$?GrdLLEUi4!Me4w=lbOd#8}PVOx*oJ!iZ7uPObx|pP$ z)Nn8p&Mr#vVi(nHq?#RY-qR3X_TOnbwqccWcvK$bOgJQ*s`R*tis#UAzP<7JA zm(+;5C?qhaI`5x|B~I=DK?!2CMbV+gx155`g2#^^%XeQtU%h%oZtD%Ah^}2UdiLxY zuQY{;f{hwA^5wuGLRJK#0ZC*c$^#p{-0&iPM90(K_|_~=-a?&@dK1F95hejTgWr#( zMmB&f$b=5Es7jIpN`8$D0`P-%{es zJ*ZU+uvQu*^%CVR26lK!g{vErjCfzDSFc_Ics_PSKa?QhojZ592M$Da4y%C57R!tx z@Va2;4AmQO(rV41>t1rJBH~C0Z+;>T5GZgX7n(Dw0KCgd7eP_COc9(-ntSPzG-fPT zhwRwyRmzVhzE-Dk4|L6qNu^4awAN^hG?pPs6hZ_(q?3zdL|jP%0dRzbmDC1L?v2QO z?Lq9V0ZRvy+S;zCKZ=(!cQ#{5M%Wqkn8G@=dwcSd$%W9o5#1{SB66m3<;q@s|08+| z{1=odSFT){GG$7XDB)<3lXdFUu|9<-D@)5j#M?%M*^KZI&5iVlV31uez=PmoujQ#x zHSDRhmu@LTSy_ZtGPWD?9CQ?QaZnXMBWO@wYgZleNjM-WU%otSKmz97Jt6z2;)qn~ z(xu@S5wGplrya81f-BHN3pFtHD(8#%x=M%IvsDJ%@j;Fo)DWI_mTmr|pfLZ+ls z&R(c!Xp8OCgU7p$@IlV3#YkCU)ym@wDLl7g%D{S|2(mZz@afb!tFk2HDPF{Nhq(Fd&lu8Czpd%1& zq>3$^@+FP+d6wDKO_Jb2C6_R%xaeW3OwQ{mAvG}82(CuW3q1vhQ!wz7Cu&^P*dEF3 zZ9+Q*TW*9VyjzcpkM>&WQPeML9zm-aIl`TW@{JTCC3*OQjh_6nDT25pz~=(Yq#w^j zKfBIShx=#oUEB*(*m5L#Q;>yX;IYip1)QfqNF5da_?nDXr(OgNz)gl1GYz2{+9YKRuIEu5~~K{sx~~m45|`L5Ed%K zPjtc~JF)UHdMD^8!7U^80GZ(>+xI@H;Jk+0YadDxNN{;faQINHgjq>hpl*DJvVb*{ zESOZR-Y|$OVyG> z^MOg~Stej6#TyrcA53Al7#s|gz4d~p6fI`(JwI2vNPKS;#>%oSn1fU`!f@qsZjB*Hh6sj1RiIE`@hi#-Yohaf407Srs%`bzBlV2M_f*)C-(Pv?k=K>*>^e;t0O^k)`Wrb6C5B?Eqqt`aboh8;niU*a z7h%v%YX8W~+peMbk$aYV$H7|{@m0{jd^=7QZRagGN0~e`kwfOVFcL>84 zE1Y4EjWtGePpuOnRl!PvMseDU8;EKQ4qAHq^p(ax6+{KXVu=%Llxd9AE zH*Y9w738IrZsJu#4hk(*t+!GJn8(G8M+g!Y3{fN_D zdc77wn%gcAsL>ERc8mg19hAbvcYAi-qa?FboQ5K_z)@3H3lDG@7L=kckr!%A%7G~b zY?jF$QG(=#astXuoWxM{B&2{yF><2FrA#Jjf=8j~p72^pa!6?)XYCbgSXt96+1I>e zJHOTdhc^lJ3(L&Y4+rxOKWf1VUK~z@FKC;KVFl|V0*WNjq9T(q;X@WlNHdhQg%8U_ z0ZIuYZ7g7cZ1yH-6enBMwvFDS=*2Qqz!3;^v5*)B6@a$DBpoS*Hq}^=2|9)96A&H+ z6fyIXP>$KC)jPVZS1dwrs5MlXB5UN5jZ#i2(UAo)Lk%OlJc1uhz#t)$;HO#ib4~pc z_bY^5^jM4FBOxJW0UxlU2feVE3l5qAU@QmIccnXIdczmG)a%iu)`$}WpVk2R0*5gb|=OhsmzL4*)2 z+sFvxXtRt0g7#YM-i)WTz)r-_QKdvo5+R~)VGXo&Hx!f@L?UC2okxPf1v`W$Ac8DI zivn>%b}-<<5o=HV3Z*x52MLc+G~yE5Wpo(y zl(6hWtBsHpJ1?^0qLaudt%e#BFB*0%ldpC$?y2beRZCmN0uqr*60rtI*(J54gc{

r*0f;d2e}LvP%!w?!r3Ra;efIW zHoU+VXdcB#Sb1bNqABPGvVI45vKewf+E|<>l6oyE?)Mp)gM#;R-#K8A7=p;MJ^=u0 zA)R?H1k?<6{1T8gUNjpyKr2Hi^#b9r-T+%xAP70{Ftg_OML&M}H4zar1c}V?tD-eR z;OLWVGS*_^<0XP_EE5hOZjkP6|OnUdmgbc*B(KQo>?T-6I9L?IJ~3-2DKn zj=UyBE1;-||9Lsk+ z)D05CC3^1TG=eFDMp1xz`kUtO6ROKf+aZuRw#OOi$Z@0dX`gaLD`LVQCx3jjG8aTHf-S?yqa&w1EpdHUO5w*SEA)%sw~3!$M!TpmvE`N@*zH#q zoH#v{HKRUakhZwmH9w*fP&&kVToo=K@=np{VH$>kz1XKWZcaggTJFdLt%B4@N13MZ J{_lUK{TFEDn92YE literal 11108 zcma*tXRub)6$ao7C~|=?5H&_8aWFqblbK9n#w3H0{9yROFhd;}dKC!0OD~ruy%&+* zn^L6*r6WiQgx-5EB25_J=K1dW!W{A|dxkmZ?6dY-?|Rp}_CDX$jEwvl{~hHs%4hsC zV{efnMgHG^TiND1ckZ0aXa248ufYEO`%j%Zb^7$_vuDq`KYaM`zjMaHg9km17%?Jk zyu|fqyLazCa^%RdW5+gc-hAlLA@@6W>^Oe>xchzk_HEd(VdKV)yLRn5bLLDw9$ikJ zJn6LsUw{4eqD70cv$NCg=D5DPdiCnLbLU>Vbm`WuTi<>6-M@0iKXb;zhYuGlSn$m^ z-|)zTNCJ5O{rBH*-@g68fdd8Ixmf1K)~#Fj?AZg$nl)<%3>YwT=FEu`Ck`7nEFEl; z>u+Tx{8wLnWucqBd-sCK_1d*-SFT(s3@3(H+qP}{_S(;FU zPek;Owjefsp}%alxr40A3!sI{(K3nSh2#h zW!O`iM~@!42S|82vckaA$<;vs7kKI@mA)y3|Js$Qr9E>oKwnv`b-?(u@k{%;}JOa<&`0~py zmn>Pr7&Zh6ZSui`2ly%=TNms??;Q>0EXkfTXAUI*WWErjE?}}|^hM6-)2C0re*I_# z4Y=8~Y18c4vlCzoarETL6FjSw_%ge9@1DtV%C$TNlX$W_Ih>uUAh@nSl{fE))qOHHTFkHqsw?z} z1q>?Ql);VVz-uCm&YCrgF+XfPx|b&B?ri})B%vZgbz?_hGi};53%QlP?1+Fjd{3G* z>Hhuuq=pk2#qJ=YG!1}ZfP_praW5kzNS|l(T)}2ubjty=L^|^28LQD!URiD)EoOL2 zLrv{bFOk~St5@+B*`>NHi@$;}s~}3r%v`AB`t|FSsxG3-(I^Uyixxx&{aC;nO8uwC zl0hPJK}WY4uOLQ*eTr}tUL;sCViFgze@Tq79Wa44gXa$|b}8!D7=kbfg@>!q|_2* zuAnw)iEdQ_Z^0x@5jBh<`@E=+GRP|qnFQKj03i|JI1JYgMLVd+vp*_p?yy%V(t@bF5_ zE8C};1m4V{Lx(CLhZiqiWQiynfkK5|^Mp>w%UPT;aNxjVt}bjwjT!~4{d?@#v4qEi zA%tC-0tEs_6+D^;i3nj(6tBQWtX1R3kJlbnNlLQ1OCdaB%P@({7XiP<8&|QxUbt`p z%_@Z!I|bMTYv`jCn(S<`KsD5%SFc`Xatq+Xv|v_NmW!Bh31U{MH3J~-BM&f(=v5bX zVnw@&h;y zf`9~vhu$$Nru8hNHfoCoDtP+zscP7oEC-oA53+UhoM4aE+IC`N&{wMTBHlub#l;Li z#Og6-cmsXRm@!_da0+gA_Io#P-i$k}*}=gQKWdJl_Z0%Nix zc^@=DF|aX#riS(mxJ)VmGquH%8;o%xO9L)~F=I(|yI1&u6bfYy)SAg&j&pC7DFHdP z2mkTevu7?s+74|7(S~Mhy~6X0NgIqALyp8Eo_m4WkdjFJ%1Un7gBVr{MwcO~C6oaf zSCNdI+3@4|kqJNaAsNtRj+&Qwbg^E+WDj+J|58#;p)P#q&K(zS_^=`A4C~lkyLJs^ z)k6+eHH5^0V*IYX--V9lMINmV{Hq(K(qBFor#Kj43!f}qbaBgoQFdXoMD|}$meNmBI4DaMX z;`UrT8mI(FVPJw%|0xORoSHNcrj~B3^$JfkB1!h5@?#rKgHHW$cokgWRFtw&i%vPn z*5L#Im0QJU>|16a77GS&UxUU4_E38Ya?VLFu#M1JA$#EDU|v~tDxm@doKZOL#8gNw zfYpx_A_C^sg=>o9F4{i0i5_lK2uQOW(2b5>~;3#OIZeisfQ}mH=K@ zZ34IuQonusHoR3dcQ!HbuB#5u8`DhS5C2rJ#u1SU^P43GmXO z1mDJ!3)*n($FF-kr0xcl$5`XhdJ3QiE$<-pbssum1h}iz}Rh!4C}O z>1IouB8Wf-v|JIQ4VM|c*fUI0KUYGdol;u0YE`dZy)@>bu5Xxc(V_)@bS^^is4M_SC2jt_1Yl?0qJG^2sNEVc{Y@8Mt@TvSrJfHEUL@R*ix&icXw!O_rcIeQXRq zUT7wMGkFyi3CE@>=jN{3}kP})+ap)xrdm*Vxw0pLqttM2>^i6ym@otr}hN& zU&*Io!-jUC4jnq^Ww43Lj9PW+(uL&I!3<83OF6iX^AS9*$d&RDM3cBP09LMo>g5t! zGR?^f&8)Su;$T|Bc9X&!yI@7G3gop~Xc{D;)P_Vc;s9>Eh`l(-s*E-m$qN|@;Zdc0 zxJpGS^p<;2kVpRb77?R}1VR)B^2U>dhyjb#!dM=}gHd2uVjV&WXfGb5%QEVqxdjzH zwh-C?TklF(I$DHt*(O*ou4pEC(;>WpjT8z5MjQBXXg`y_(#Z=dNI){|EAVh`xju9+ zv=G1>9I_FV!XdZH*SFls2N*M&RUi#Y9Xgpn^seX@Dy;Se#w(tsgIoS}ZyNa!*N*^e z+_*7@rQp*$2(gu7G8_tl2bF?c3dkorm0@ z0efbY%r^|F$QRB?1VUZRxt-n)%8NCJ@k6<8yz~$?e(^IX{t1jYt zWDrV~4tw)zBqKvyToHyr?r4-3p1Hy>ON8reI>8J}@RZM?iX7O?Fi>3c77FJGMV*QS zKSCtHzlK6$W@coaoY zNK`CrY$8hSUO0&&NfzYBp}Z8tD!}|{nkWpckUad5qhBsONS`G${t;vbelm;?I>gCB zP?%XVBR2|)ol0C;B*6dGcZY_fN8;i~6gwM){D6la^^_eIhdjMvuYGkhdsO3D;=(C1 z48p0rbW}vMq7k3bCHRC~7V5~}asv;tWA82J24e#f^6>~caY2|ne#0ivzk>o?J2>G( zy?cCF8&NsMk?z2k9Gu_4Awt?Jhg`XV@|KdiD4o}` zM~r3kh#La5Erz(g_2?B+70vc!Uq+`7JH%jxUw$Oe&%eR`eGEEFLvEP!o6e!>Jd%c0 zD5u1zjOIZ(QUSHUh;Hau5#fOq3_GTRfMKENcFBkc5;~=4Ejkc{8kDg#i4-!$B2|GDAZi{xjC41-;d7zV-u~t184?__^lT$Q2uMOx ziv8tH?cm}_1XsmuPDo)#FmiMLsEpe3=~3pm6W(I+%%Ff=11sqHd?C7cmJkbDmK)h8 zGRP4BZ`#5I?P|>{_Xeok6RDL-to7ZHu&-Q}?xny+E&>R{HG70;T+1cVx^-)H!EoEQ zZG9DMcLkN7;{j5f`^#yF3g08IzmPwN{}Ubr4Kw~8?!1CAbFdF&9Uc8 zOGc`rPX$V*00sagA7_YKpbJ`(#E*Zs2sV2n0DlII(XaD)h+!3F5*=295;|RS>+`A_8H%cI|xT(!WXg z1wy_q!=YMWDQ3j7R_};qOVAp&ZwE+pxsxGJ91!dhX%wO@7HG9;;?YoD<*Z-7KG8si zU+&xsndM)8lD0xMv8|lW{5D{aAXF{{01o| z)k8a}D<@Wwg?dO*)oCS>MF~~+`^=H0>dNo;nZlcC)~uOCDpjh~v}sdsDJdY@JZO!b&Vd;~@iH{9t3V<%-r9BG(T<$+OvTbRqfwwW&%YFKs-Iwn6FjV;)d?dC3XBjC znyAN6Hpsyi8lhkd8YD_hZPc4v%j3r`#)OlFwTUb;ML{bV@>M5gGsDs_llnuZ3(W%U z&l0u>C_VZ}Dk_eP7sP`+-vL@hL6Ap;AV`HxY{A0Xm^@-sxk<|qnJ>u^413;e&A&MW_ggQlyy+rv` zoRn2chp0;|R}MB&ZY{){S|A)yek|eK_5n1Uz9?9#h@RA+VtHhs3HgyE|1el+IktgB zUosKGkcIO3BOLW=SK-KsbCcT7D%h+dFyY)o<(|4k^kpG;kA~WWmK-}g@FwM`FB@sX z!-fY+0}M`T(aF{#*`v@ZL_G4fJ#k{jIpdK549bBVuh6UN$wY8yyW!RePuI0LCg0aY7=H zu^chRz~6#oEiZ3nok-*Z8>^#535eh3sb$z$#Y{mp8vgBLJgbh9IW_54cfi0uC9|wi zqej)LRV!AkC>ER)<-102>u?NU2_A>JD!|MD$?(*vQ^zWQ9mKFqBM^#EO^2!fp~S_3 zY%jLJUrc?TQL}@BFP+J6I+N6ANr|#$%R=dlat!E}_~v28iCW@I42bn4uGPbUUR19n zqy1uAENcx#B87AossCy1&$4Dfrq<#JUyT|y;>vP>y;5xVlG2|D1;$U-a^=dEFJE5D zsHY)PkQ$wVt%|CGL#yC-!yZ@u(o7ISP$BTut5^^&X>I3KI&qdQ{7+l?xHHVrZq8Siw-OCjxs#~nUcGY z7LmCC^vKvv>{w)obl^bb0ieGA&G4_7z?8*9-MV$%TOL2X{OrMzrq{S;R6-7Vk+5vf zhyaO7&?>a=d-vEEl!W!MY+(~oh3tabl$_1T1>}8ooE8}(7yH_s}zig>CBSK zl`G?@bm`KzXCwgN{}MEh2bRQ&4L7fF?cxO@fUu8wOh;Olilq0cm{Wsye(4eS+|ixF zYJWwD21F~?Vu?oP95pCNJ6!9UhfdAV0xcI%5EtuZ?*+Nq!S$D6J5Y-B%1y4X*!odo T=XLz(MEf9m(gy$gf6x90XTTvO diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal0.0.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal0.0.tga index e5aa174be0778b1f206d7cf48320db6a3876860a..b210cbf26d743a895105314c5432739983d34132 100644 GIT binary patch literal 2723 zcmbuBc~4V86vd1DVKfSqNbqCvl}af~3spp15O+h2VJU^ObOQ=yhqCYcP9PAr5FiA9 z!@NF+*P;cROy9HyL%Q9t|o|__OvpLZb=4?`BWhGM{!^g0*%x88n zELBxiCEB`z^}~jShPt}C+S*!|%T-fTQ+@s8kX1QYE*!6}u2N4V>l z`@`XIOG}H_>uqdotgo+kyWM{Qc?F0=fSjM7@9yp{FE39_ObiSRbar;Owzm3wzC=KZ z0Vxz9mzS6O`}?b_t5Z``kw~PgtE;W8&F}X&H8puW9wH&5+tLvrMS!Fn9v-f*ug}cP z3=Iu+cXx+Ep}Qg+9UX0KY|PHi4i69a^z?ub2n1vdlGT64aD05cxw&}{gqLLD6j{W^ zkYE-%f`Ny`nG^_u$vDrE_?zk=XJ=;!V`*tg3PY+ZL19EeQs8rIYYT~vj*j;A^>uV~ z1cN~&8mn_ne4I*2 zNaWE-1c-03O7zLqTjz zR}H6BV@AYd2ggi25(j$8YjALox|5ohA>G;p-T)=qk$}nvDjkxci0szZ)O=mBz$^t(~16>Xrt?8`FcJ6*@>jzeQz4HY1%}k;9E!&^*CH1#gr|Lt$dU*5cyg z+}s@aG+eaE%fUDzfFlwyToI@FzEg97WRTDj9nZpehB-Mo2|*(xBX9&d2~c)Cso{dS zWQjCxTtGJmhB*0U&=Hwf!wbm0y}h(pz=@t`pq_YS)Q6B!&8_(Fl>{D8MWhc*HX|LA z4T(s^Iw-90DM36^jj^9L5qFt_n~Wm%tX`H{C9-9IYsR*nm|>lr5tF4;I_lY1^#eNxVfzvXbo%52rnl{F z72kaJzi9h~r0Qg^fW5EEo}E1hd*7A4Qr16|bqVVVWnIkrr?PgkW?7lb9S$*AyOg#6 zp0*vVfad!@b^$m+4d<@5daw9D%cJ3xVOL|@n7=UuKf?aS5bq^yH$ya3VS5=)%?@Gb KYIX!$9lrq$PICGH literal 3070 zcma*p`%hF?5C?EJRVrv~P1>YQlm1QqOS{V=A|OavX)z|Xi6|l5K+>s+kJeH7g z(s20j;Sy7m{SfJ*hy7a8V!z_hp+iAmMGD7`9jl$5p8k7g9X)zfoW-k1da9l)c+PXk ziLWKxrZ5fyyM&K+ez&z=h1sdr^H~<$eT)2Gs^3|(XuU)&g@cQ-Z9uy`Aj)7y1 z0_0dYNDF9zbRRfyAZ5&jBV?pRU%7JS=FOXT@7{gz;K8FukG_BW_^}6t$$?`|Tm{U+ z2W$ms(!PKH{xn63fAQi)WbfU(_vFcwSFc{ZfB*i|r%&H~{`}d4^7{4br%#_czH#Hm zrAwF6ESjp8|3phf7p~a!;Q=4PWTPhYx{6{qp5YBbg6Z4YzLHilBUBUs6P1 zMbfoz-@ZUPfYu^y0M4I39}(ZaeG6(SS@7=NJ6+KX>2#VSf>|t3klF&;)YMdhI9FaJ z>EQkQ_ussE18Nzm2Zyn~7!F-UO|d!&B?9FEl`}wd@Nx<2dH(!4gw}wfVmG9~$jGfn z2(gyv66x5xcW**x4o3rn3j$S?`I@FQ(`1OuW)?-b1)!V(`9?v!#Xwk2>R!Bffta?b zR$EdMF*Yx@YtNoNfy8n$M-r*DIF=G1>a|)anyVWrM2r_MdMRm{oSdA6;znez5}9wF z)TSZ26;WazA_N2gU0D$K7^(aRQupD*hp#~*g3u!A+`W5u%EMc#A+GY-vu9Nv^>~=* zSdD&~U8ThI!bNwG(ym>*!k2EQC)m0hb7E+#D0N2o_U+r+s$s^%V5BUB=SevOF;^n} zHzXPvC$|k!9a_k#5>W%IA(4pi5KY>5?%WxOw2@lp?k_FMy9p#rTeZ2yCpI@070Ur) zfmxY>`W9Q9Q(AZK+%d3_S^_P=CcyZ+f|OR|1fxL8J9g|yXwAb}3o-Mmq(dBEsOCV< z{pnRYKgh|BT%-jJSSxAXzI}TFS|=S`6(gWx9}^eg;$FUd33Exn{rK^t2BIF{GTCv! zB!z~VC*2v`1(JRZ4FE%LjcbJpyg(M3HtBo}(r-)lp1?%zQpivuof8uiNd><$JI^M= z(EaGEQoNKV*+lvDS~iN4$5Hy-QBE9*G?g5dEWcMXwVI1O(=Rcb>Qt`>n(T7pH`9EX zJi`IoN`IAb;gG%q*|x;9G-KDwQ-1Jzq`rqZY=Z;*=R$rAcTkEE_6g`VMmzl7-KM>&e2~7pf_K;F#^4 z9>`-nEgOp^+kLbw(H5LWQXU%{OQ`4UnTjN&oy%8-m?Y*YVpkg*z?{X(3tFAQD%ls< z0@o798P4=zU$t%9wve-hG}RgHSwur_Dv%r zBdzqmJd<qCMkX@*rp=o-_s~~*Cg-`~;bCeeW13(}jvF^^+BA~Ub3;Qz zOcfGbnn^oTe?~724i1j8CFi+;fdQs9q&s77W*%ls+=?4FZX9Dv^mclGRbMJiQ-6Q| z2wON0dSSzc4V`Sg8QU_pVYbAl)YsS7#kMA6%dKC(p1Fk#I!e+tGOuJ?UA2Y(xJ_*R zY{BOb(m`KEFWIjlYw2O%M+)oKt?Q}k!}KyeoK;9$bw6oe>h0~#(QO;Z?Em%u0%nEf AL;wH) diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal0.5.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-normal0.5.tga index b85fd7aacd44666f9633311ff2df29da239d9dbc..3038fea2d76b97e197d669954cbb3fed64b8c50d 100644 GIT binary patch literal 10988 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 literal 10855 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured-specular.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured-specular.tga index 70e53bec0480aa5f5383b003443a7ccfd0ac5dbf..98e09278f88de55d5387b454cda397760aabf827 100644 GIT binary patch literal 6593 zcmai(S#wm^6@_)xY5`)hjWLqvd5*!LvAd<7yVb2$Be0MKwy}+em^ii>D{;Bv)VV_o z5E2LwlanHql!uCA@)FxGJmepwDlbXp59BSWyynIE);+i7Ti8i55P-l_sTBS5k*`Xp(txmp>FBA&~zXV%1kqZv*m?{Q!uFY>?NWcXn zVi|KP^5n?K2pRI29VV^n{N^@^>_TcRPqx<>UGgF#u7AjSV;x!51lh9M+ zeEs;<;~#wd!Qo@I18-EG+f%I7a)l!5c;j^$r}19Slg*8hrU>M~>y`J8){ehlKXk12 z+MAW>8D#SDi1dZxqz<$5zfWT~8V3gltxT&Fyumj@Fq$1L){47c*>&*5!PeKUtAD-v z(ceDuPfq^$(D>}$Vy(_|L?53^UCL>^Z***w1Zj%1`-<-z9tVE@%G9~bQ>NAU(K{TC zR}iG+Nm@*t)rT6c@!4meKi!b+F`((E} zH}Tq=rTPSCvnuWVjUaGEBU(^|u1Kb&_HEm?jm(Z6JK|#FcbgtfbD`63Odq*?;?*}pzx;u~+3rgrnG;5Lz`>siG6Sdu7}M|VA!d+Y7;-08;0zkBWvH)g*0 za{Aom=AmPi-P3&RK%&v=(~F34k5(gc5QQ`p29a7R<%(|-YhMIzi5Ah6-u{V=R<#Op-eRSW8`J+Fn zo>`v!^>26m=JQ=kmnM(>v@$cBEtZfO-Jlg1*N99MeJfK^JJ|Ma-MW=vrLJ79eHG~E zbC(%QRT_oaH+LSHfA!QChcDcCfByGJkDq<5vA0pI7f17>(iy&IXSt+4R_RPCo6po5 zV=wG496nxl=V~Vw>p%C$-+r$+Ju_A;@duo45qgYK7*CYp7(&o#MIq70L#br8JoC&m z1beY7cWd7TC?HH_Mhexjo%_aLIWqljYyaU>uN?ev-@b!Wg<1ifsf<3U+|W6^mnFAL zx>(Oo&QzX1P~U&B{_+p2voGZ*cc%0C;gMAIkgYtckg=G(Nh>EN(vaC~rGvnL+EdYt z4Gazpj|`3G(&a|3xwpFKK!YFDR-1+NSb8KaZQRQRd<#nw>1;Y%&K4#L<(=hHvs9?( zvqj#E;i2K^?Ss`$u&S8J!$bl~ut=LOQJ43F&{$ZFAg#u@OdiN^3XQ3Jg`3G1`Dm9i z!#uCyp~3Kpo#L4p6rLn*A~iHJgwWJjDxFJbav2t&2iy8q#I4-gioOJDBr=rgMN$pP z4NpJ)w5_2tF13B5{9(0YV6dM{7)cLxjbykfK2t+nFLo90VJWr4;m;78f&Kwq)ONjJ zdVB`&vQn6U1_mbVTvmu_3v$?!H~2a$3UDY(9~%rJEWASLVopM@v;FDszs3_CkYOf@07A6d@fxeuc9JM3+&9S%yh^J9X!fV4}kv zma$3eY=y#;p|QY7(uajYb$ao+@cQsy(M+QDZZt=aarJ-WVxAk#lmx>h^TZQRbQA5c z_&li=tFv{RF5JT}G0fLmA}DK^uBMZ2IG_?;!qSn8&x>Z6#~**Z8xUJ8K2>BMq(0=A z7^0}X@-9Pq>=3$WhXrGSg-lPzW_4K%B@0{q*kg~~goX=)HGINM2$;0YL`6567{8+q z2)Zp#oGLcevGa7m4uGp4ee}`q;_aD5>@nPD(6Ww9)INOGfan$-c<6U=Q7WZ3GJGqw zC+{&L`P~_MtR52r7|-iyMD3M#p%I-!8{IB0CZ*c!N!Fw=ir6EMJYwW5+fcE1um!L# z!LF!%n?1yVcVm4zPyDtlf5-~TefZ&rlSB;+?~O7Ip)Q8CAV0$pMUTC!8jyCopnM9B?Aurlg7vp!h=(Pc+5_ z-+AAC_t`cBgPJ@LK27I!I->UN2?l7wc6{3u(gD(G^w(}US!6&A;N-pc-b=tpU@GBi z3us$nhOc(^VIGJNSnY0vYg20<=2eF_dCxuf5HQh)1KMpZ=oX+2h@NPmlbZk2rUS^m z2=2n|F-6g(UHKMtr=*^!z4D?p;1YM=eK!G9LLN1(5VH@-fOvpiqV_uS1<1Tu-KQ?n zPz3olhYwzThPr>(U3a+=kMc{xMRny>7fyKP#i4&)`cc2D`ki;)>GbvW5wtXFw<$XeoY4IQle|gCE?~@7{jX$oU1Qk8Ya2zz=rcIkX;yKYpdlS(MCz)!6L2C46hyzp%xQ2#kSp3^=yUiyqL@WV& zm%Zx3Nu*j~kRE-}<4__aEunOw)uqxcx7pkK;`#J52s*6f^ z^)2CHPPKN=x^?Ro)Jt@UAs2OzUg7oip~If7QlUaxLntj~?b@|YPfrhF5l`ABD{7bs zBT{vWL1YoHzTWJl3?E4;)(O<$(kp5M-^n#=)+h#1R9 z81xw3nBcftB}<3Uy+JS0`l7niVg*(lE4EM@Y7p?`~A<`-e{TjfrGjt9w#v&;vVk|B!E$UKAmxeFnNnm6!>KF^nRQCei niY@j82ejttcOcg&De8A8AF)={uUM8@EB*>syJGxTGg|)#c_?{V literal 19218 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 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/textured.tga b/src/Magnum/Shaders/Test/PhongTestFiles/textured.tga index 1c7d6d153f16b85dd019d36f9adf8c6194cb38b8..cbd4f0ea36a8833b3c7926c4487e7048399aeb11 100644 GIT binary patch literal 11090 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 literal 19218 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 Dty$RU diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/vertexColor.tga b/src/Magnum/Shaders/Test/PhongTestFiles/vertexColor.tga index b674db5bad24cdd47ce2fe550b4b1ba6dab427ee..e3699668a9d014c2577efdf421deb04e74c7ec58 100644 GIT binary patch literal 10314 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 literal 10876 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