From 1eb1eec2713c349bdbafe13da67a699c1a1f9878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 18 Oct 2020 18:30:10 +0200 Subject: [PATCH] Shaders: fix distance attentuation calculation in Phong. Not that either way would be more correct than the other (this is what three.js uses I think), but it was documented everywhere to be 1/(1 + d^2) but the calculation instead did 1/(1 + d)^2 This now also means the analytical test equation works. I should have paid more attention to it not matching before, because that obviously pointed to this problem. Point lights are now significantly brighter than before, the tests were updated to use a larger distance to avoid issues with overflows. Does not affect the (default) directional lights in any way. --- src/Magnum/Shaders/Phong.frag | 4 +- src/Magnum/Shaders/Test/CMakeLists.txt | 2 +- src/Magnum/Shaders/Test/PhongGLTest.cpp | 44 +++++++++--------- .../light-point-attenuated-specular.tga | Bin 7885 -> 9329 bytes .../light-point-intensity10-range0.5.tga | Bin 1619 -> 0 bytes .../light-point-intensity10-range1.0.tga | Bin 0 -> 2376 bytes .../PhongTestFiles/light-point-range1.5.tga | Bin 6810 -> 6539 bytes .../light-point-specular-color.tga | Bin 8130 -> 11867 bytes .../Test/PhongTestFiles/light-point.tga | Bin 8129 -> 11862 bytes .../Test/PhongTestFiles/low-light-angle.tga | Bin 5746 -> 7847 bytes 10 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-point-intensity10-range0.5.tga create mode 100644 src/Magnum/Shaders/Test/PhongTestFiles/light-point-intensity10-range1.0.tga diff --git a/src/Magnum/Shaders/Phong.frag b/src/Magnum/Shaders/Phong.frag index 46109b924..50624b348 100644 --- a/src/Magnum/Shaders/Phong.frag +++ b/src/Magnum/Shaders/Phong.frag @@ -270,8 +270,8 @@ void main() { /* 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 float attenuation = clamp(1.0 - pow(dist/max(lightRanges[i], 0.0001), 4.0), 0.0, 1.0); + attenuation = attenuation*attenuation/(1.0 + dist*dist); highp vec3 normalizedLightDirection = normalize(lightDirections[i].xyz); lowp float intensity = max(0.0, dot(normalizedTransformedNormal, normalizedLightDirection))*attenuation; diff --git a/src/Magnum/Shaders/Test/CMakeLists.txt b/src/Magnum/Shaders/Test/CMakeLists.txt index d1ae4b61d..d23ae7b6a 100644 --- a/src/Magnum/Shaders/Test/CMakeLists.txt +++ b/src/Magnum/Shaders/Test/CMakeLists.txt @@ -244,7 +244,7 @@ if(BUILD_GL_TESTS) PhongTestFiles/light-directional.tga PhongTestFiles/light-none.tga PhongTestFiles/light-point-attenuated-specular.tga - PhongTestFiles/light-point-intensity10-range0.5.tga + PhongTestFiles/light-point-intensity10-range1.0.tga PhongTestFiles/light-point-range1.5.tga PhongTestFiles/light-point-specular-color.tga PhongTestFiles/light-point.tga diff --git a/src/Magnum/Shaders/Test/PhongGLTest.cpp b/src/Magnum/Shaders/Test/PhongGLTest.cpp index 4c2b16cae..f162bd319 100644 --- a/src/Magnum/Shaders/Test/PhongGLTest.cpp +++ b/src/Magnum/Shaders/Test/PhongGLTest.cpp @@ -392,30 +392,30 @@ const struct { {{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}, Color3{1.0f}, Color3{1.0f}, + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, Color3{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)*/}, + {{8, 71}, 0x2c2727_rgb}, + /* Closest to the light */ + {{63, 16}, 0x222222_rgb + 0xff8080_rgb/(1 + 0.75f*0.75f)}, /* Specular highlight */ - {{60, 19}, 0xfefefe_rgb} + {{60, 19}, 0xc47575_rgb} }}}, {"point, specular material color", "light-point-specular-color.tga", - {0.75f, -0.75f, -1.25f, 1.0f}, 0x80ff80_rgbf, Color3{1.0f}, + {0.75f, -0.75f, -0.75f, 1.0f}, 0x80ff80_rgbf, Color3{1.0f}, 1.0f, Constants::inf(), {Containers::InPlaceInit, { /* Colored specular highlight */ - {{60, 19}, 0xf2fcb0_rgb} + {{60, 19}, 0xc27573_rgb} }}}, {"point, specular light color", "light-point-specular-color.tga", - {0.75f, -0.75f, -1.25f, 1.0f}, Color3{1.0f}, 0x80ff80_rgbf, + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, 0x80ff80_rgbf, 1.0f, Constants::inf(), {Containers::InPlaceInit, { /* Colored specular highlight */ - {{60, 19}, 0xf2fcb0_rgb} + {{60, 19}, 0xc27573_rgb} }}}, {"point, attenuated specular", "light-point-attenuated-specular.tga", {1.0f, -1.0f, -0.25f, 1.0f}, Color3{1.0f}, Color3{1.0f}, @@ -423,10 +423,10 @@ const struct { {Containers::InPlaceInit, { /* Specular highlight shouldn't be brighter than the attenuated intensity */ - {{57, 22}, 0x665656_rgb} + {{57, 22}, 0xa68787_rgb} }}}, {"point, range=1.5, specular color", "light-point-range1.5.tga", - {0.75f, -0.75f, -1.25f, 1.0f}, Color3{1.0f}, 0x80ff80_rgbf, + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, 0x80ff80_rgbf, 1.0f, 1.5f, {Containers::InPlaceInit, { /* Color goes back to ambient at distance = 1.5 */ @@ -434,25 +434,25 @@ const struct { {{29, 50}, 0x222222_rgb}, {{19, 14}, 0x222222_rgb}, /* But the center and specular stays ~ the same */ - {{63, 16}, 0xc57474_rgb}, - {{60, 19}, 0xf2fcb0_rgb} + {{63, 16}, 0xb16a6a_rgb}, + {{60, 19}, 0xad6a69_rgb} }}}, - {"point, intensity=10, range=0.5", "light-point-intensity10-range0.5.tga", - {0.75f, -0.75f, -1.25f, 1.0f}, Color3{1.0f}, Color3{1.0f}, - 10.0f, 0.5f, {}}, + {"point, intensity=10, range=1.0", "light-point-intensity10-range1.0.tga", + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, Color3{1.0f}, + 10.0f, 1.0f, {}}, /* Range ends right at the surface, so no contribution */ - {"point, range=0.25", "light-none.tga", - {0.75f, -0.75f, -1.25f, 1.0f}, Color3{1.0f}, Color3{1.0f}, - 1.0f, 0.25f, {}}, + {"point, range=0.75", "light-none.tga", + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, Color3{1.0f}, + 1.0f, 0.75f, {}}, /* 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}, Color3{1.0f}, Color3{1.0f}, + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, Color3{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}, Color3{1.0f}, Color3{1.0f}, + {0.75f, -0.75f, -0.75f, 1.0f}, Color3{1.0f}, Color3{1.0f}, 1.0f, 0.0f, {}} }; @@ -1559,7 +1559,7 @@ void PhongGLTest::renderLightsSetOneByOne() { /* First light is directional, from back, so it shouldn't affect the output at all -- we only want to test that the ID is used properly */ .setLightPosition(0, {-1.0f, 1.5f, -0.5f, 0.0f}) - .setLightPosition(1, {0.75f, -0.75f, -1.25f, 1.0f}) + .setLightPosition(1, {0.75f, -0.75f, -0.75f, 1.0f}) .setLightColor(0, 0x00ffff_rgbf) .setLightColor(1, 0xff8080_rgbf) .setLightSpecularColor(0, 0x0000ff_rgbf) diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-point-attenuated-specular.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-point-attenuated-specular.tga index 1352508f9ec5c5db5f8381e17198b1f4b19617aa..10d7706a71f4b5aedbd8a8aed743c2c743f92d08 100644 GIT binary patch literal 9329 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 aK;(g+d-iM^`20O^M*m;uu+T3e<=H39=F7AI literal 0 HcmV?d00001 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-point-range1.5.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-point-range1.5.tga index 3ab90d057e9b4c30813651851eee24db3df787f5..6b99164f7ba4ce6034b0b7137221b4695a06abe1 100644 GIT binary patch literal 6539 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 B;hz8i literal 6810 zcmd6s*-u>89ml~$NNJxebycOd0)}B7_I=+OU|?Vvw!vTwW-&Y1NfX5-_YTlTh8xX zr=)x>#r_ve38s7}MV zo$vJ)c)f)=IlkQ7qTJk)yu7mf{PKc=%EH2GpRcy4sJ^(kskF4EtgOAFqN}p9r@Feo zwsx?-KHS(i(cC=M);8PGvDn?c+S9WY2s}M7@Z8|w^Py05czADk_?kTShK9_+!JYp8 zXZ!k|^7}Wtx>f+Z#(6qWDDxC(PL2XC&dV#w&j+-kprER-u*T=BD=uy*DFL*#yu72L zqPwc9ucl_8u5P%YVXUd?Tx;uvj*bOMxg7{R6Ab=16xt1kZ;Xz5ZB0w8UN}9{c+RDp2 zrJMmN=LmAPv`n|RU+n5y?&;YK1b&2Os0iZ3#LJVDuTD+ z)~7Vk16*(5`qEh6Fn(L=g+@=?%eAW6SsjySc2d&N%as#)0hxd zo-ZqNJRijKjg8|nKIb|+5p=7+|Cym71B!`>BSZvke*WXd#ZQ-(K3iJ)*}}pn7cYJU zJFqBA6rg@mQZ1Q;_ccv*QdctRG3u8wYGqPO%lY>9c>=Vz_c9K}?}Q^P7cRUzKY#zy zrJt{^{(5cgcWZ0EU0L}RyuhL?VL-?t>*J6fr#;yeoAxT3nq@W-r2gt^D@dD~BCV}6 zGL_bFJsO3>`-JE8^qY7buGQ7wY;62tbMxWm<`?Vh4}e8kv?gYGARg;~A{BXm0;x(T zos=MjbkXl$r!G;HMn-NBp{R!6mzO_ZU;q8q)|cDcf8O5y6R;=?J~2yd5C9aeuYz=_ zzJ5felZ*5wq%$-3<`?d-to(9g zVfNng)~8o?9$dNlaO?6zU{RJZAZAH0ssY}o%s!^~si&vUs6b7PJEQvgu27ZFOQl(s%uRZ1)S z+tkO_7ho7G((oVwMP{8pw3IOV+V~5!a7N${OV?`EF8u$*-#F zl`AQgf2_Hgm2|eVbII@D5J@$(Gk)%1`Rcp-pMMD~$`S^|EK(AllrAEaK$e2;Qq?rl z#O=wkq#n;{7E^i?7E^i?vft@VR8B=yMWxs1?cE+2cy@R+I<(ddG1Sp*W5B5k|m9wBb7jwKFQdp2jzPtot;4Le$1aM4fJHV?n({RfQE@ zi2(wZ?4lGr2^|-f1e9d4CGBWqdV025*IcAdYf6veYE6@@rcRuyUP`&&>7{g4Y5FE* z1Y88RyL*iwz^`N%OsGfN$YY17q%mMAqve8<^}+=z8mW@gHB#jMam%OorbR{8y6*~U?Jr$(LigCh~)Iu@DrNV;D0Uccd-lpH8Ib`*v>3%e3k{BiNPjbCzPVF$Ii*~&4 zkP-m1v?>$zJ#y6wu`F? z{?poe%005KA{Cz1$X{96Yar?QUMkuZ0W8U#{)f@&~frf3gTx7QBZA; z@v|tE?2m0ov6m;mZEtsxJW@)5T2&Q*#pE>j_5}R=iOn>RqoEz*+icsni8Dm5-U$}) zcsR|&BByO9E4~g^b!*m$fjD06MP$^oDGL~ zz~N!Vr}T3Wq3kp{(tI!P0 zrb_7=Od!(v$Q^mqF@kX}D4|oT6e`OA>wB^8(?jbdC?_>7u_PB&P@m9Zef>oup>yaJ9 z$F`Mu>=g-nQLbs+k}2!cEWZ|S`J1P(tSTmYE6Ig@8S&T`2>YA{A5*#MGG@l+^clyP z!Q0Yw=~z9Z#Df}~X)>}bgC;M0uQPR2T$x{-uk#?TxrtZL*PT|`J@eP)C8F3qmrV(u3?Q+ZdZ$?%42I>DK$IE4tD-cjo(I$FRnpclN`)#g9xYqs5PebxeAq>Nnm4#tQ^{ z{5{JE51wg{XKv3m#_ut1m#aPY9cykec9*%idc@e9YHp7`?mcbX9^*JY%;n)X&X^Av z6NOXEb;KC^w;x*f8Jl^i-T#>TyNtiZeS7RD+@pRw-+#gP8)8nb_LwjJk3J{+KPK_F F{{j*f`qcmc diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/light-point-specular-color.tga b/src/Magnum/Shaders/Test/PhongTestFiles/light-point-specular-color.tga index 394a895e3ac3a31ec827eb72f6e8e543f2bf721c..72a6b8aa5b5e23316ca11faa6e00f25e56c7b187 100644 GIT binary patch literal 11867 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 literal 8129 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 Y&9k%{*rjcG_5t_yoqLD<{9 diff --git a/src/Magnum/Shaders/Test/PhongTestFiles/low-light-angle.tga b/src/Magnum/Shaders/Test/PhongTestFiles/low-light-angle.tga index 04aa4057f9cbb9e729ad658107942c74b2d74d13..9f64bc5402d46d33ff5ebd0d881606edfaf659e8 100644 GIT binary patch literal 7847 zcmc(kWp7;D6^0#VW_t|dG|bG*%*@QpoVAa~lZoS-wdQVb^Gfk*0nr-{P^k9r_Y`}d;a|S%a<=-y?XWf_3Jlp z-n@JF?*04sW)?z7lB7^5w70hxi^UHgK9owOj~_pFbaZ_B^r^G6^S5&Q{Q2{jFJHcv z+wbM}t=ztU|86{`A3uJC_|Bj)Z7iI`2DWKG2XP#Sax@ok4VQ5x7jr!#kb)p&Ar6TM zMJ}R|4geU<4>LPWo8| z0-I>vA#kB6gn%4G2?3diMKZ#X4@Ca{{ri|lj~=C+!#Z~k`_s3yW%bUH39JlCCbkeK6yyp805E{b-@bkO&Ye5FK_{%Lkq4GXo~Ke8 zE1givDfvur5ugZO=mIe&jb-)D;W<)?!o{8@a!fkL5RG&IzyKzH=^=Xctpdd);f<&PpS}0%ulfQQD+V$(# zZ{EBqEJYw#o>*0}yzo_~mlq8AOmG2!0&Gbah%uQ{)na{yq_TW@!Z?f)Mp1@05Dx+% z;Iv-3a^>pPtGvM{FvTFN6@xYWm9Bw`M6ZPMn($QP6DXov+M;F1m^79(sD`DBaXS5} zwpD=;Cm`es2mmmE0jcHU#fz6NUFtbprn;+ipo8W=TApkuMtBro0wTnBh8l&S3dSbw z<{NdFF`4|Y3IYTu`E%#aUAS<8x679=*MQ1|B2bk{CZ{=n^e0s#Y3{@Af&Cr+H`4i1N^cu-6@PF2zCN7`xnC8HvFOv-hLMtjs>gd@av zhK$LaW2EbtllZR;mvXhL8Dfys9Sk7glL-IizZkd0iHa%9vn~gfKD%kw}$i5Dx+%;N%Y;Jb38P zA>NK0IU+DvS;uNcq`*i%*t~w!U~|_gIz?#6FM<)U#*i_YlS9(!k|FV$>~2Afl14B{ z6%67*00f-;zJ2@l@85smzyUe}gOzoa(OBs;uFSA0=k$9`fkG|~>Bdt8BgA)xjLDpb zR(B+oZs9A-ErLO+U=R-iAmFs_-o1Ozo;`c_?xiCzInARn_F(;GXzkdCO4IAih-n==@l@7$7aC!YFSZKsPjqsr%J@6!eBv@m}m^79( zcwDhx8Q&8c1sDzx4blMs0~nB+SFc{ZX3d(lYuAcTPWvUF7s*Vz`Okpool&6z$_o%g z8|XI)z!|DyWTMMcB}0N>k$?aQIQbPTR;*mPa@DF;Jz-P6Wx_Ip=f4DsPeBI4v;aba zHHM7IoYKR8Pdwc{NraJ!F!`jC1O!09X49G435N)7uOyxvS>5EDZhw#{PkB9^50Du8Z^TLG-7cE+}c=6&inL92Wk!dnd zIRXy zHf*UFk|59$h#L9%Cr z-@$ett(|uOTULWZ>k$4V~N+ZMn~QoG-8AlJY(-D4!G0g23wV?U0^FBH!zua6qze$I*Kb;dJCj~*T92gXC!xe4n(voG4X zuRI>-q}mdBUJUgW3lV9{hu`Xk$N) zf9J6Q0|t}^4jkCYShTSp$N%8z=-({Sew6Xtpo2gy?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