æéã®çµéãšãšãã«ãã²ãŒã ã®å€èгã¯ã©ãã©ãè¯ããªããŸãã èŠäºãªã°ã©ãã£ãã¯ã¹ã®æä»£ã§ã¯ãèªåã®ã²ãŒã ãä»ã®ã²ãŒã ããéç«ãããããšã¯å°é£ã§ãã ã²ãŒã ãã°ã©ãã£ã«ã«ã«ããã«ãŠããŒã¯ã«ãã1ã€ã®æ¹æ³ã¯ãéåå®çãªã¬ã³ããªã³ã°ã䜿çšããããšã§ãã
éåå®çãªã¬ã³ããªã³ã°ã«ã¯ãå€ãã®ã¬ã³ããªã³ã°ææ³ãå«ãŸããŸãã ãããã«ã¯ãã»ã«ã·ã§ãŒãã£ã³ã°ã挫ç»ã®èŒªéãããã³ãããã³ã°ãå«ãŸããŸãã ã²ãŒã ãçµµã®ããã«èŠããããšãã§ããŸãïŒ ãã®å¹æãå®çŸãã1ã€ã®æ¹æ³ã¯ãå·åãã£ã«ã¿ããŒããããšã§ãã
Kawaharaãã£ã«ã¿ãªã³ã°ãå®è£
ããããã«ã次ã®ããšãåŠã³ãŸãã
- è€æ°ã®ã³ã¢ã®å¹³åãšåæ£ãèšç®ãã
- æå°åæ£ã®ã«ãŒãã«ã®å¹³åãåºåããŸã
- SobelæŒç®åã䜿çšããŠããã¯ã»ã«ã®ããŒã«ã«æ¹åãèŠã€ããŸã
- ããŒã«ã«ãã¯ã»ã«ã®æ¹åã«åºã¥ããŠãµã³ããªã³ã°ã³ã¢ãå転ããã
泚ïŒãã®ãã¥ãŒããªã¢ã«ã§ã¯ãUnreal Engineã®åºæ¬ããã§ã«çè§£ããŠããããšãåæãšããŠããŸãã ã¢ã³ãªã¢ã«ãšã³ãžã³ãåŠãã§ããã ããªããåå¿è
åãã® 10éšæ§æã®ã¢ã³ãªã¢ã«ãšã³ãžã³ãã¥ãŒããªã¢ã«ã·ãªãŒãºãã芧ãã ããã
ãã®ãã¥ãŒããªã¢ã«ã§ã¯HLSLã䜿çšãããããCïŒãªã©ã®ããã«äŒŒãèšèªã«ç²ŸéããŠããå¿
èŠããããŸãã
泚ïŒãã®ãã¥ãŒããªã¢ã«ã¯ãã·ã§ãŒããŒã«é¢ããäžé£ã®ãã¥ãŒããªã¢ã«ã®ç¬¬4éšã§ãã
ä»äºãå§ãã
ãã¥ãŒããªã¢ã«
è³æãããŠã³ããŒãããããšããå§ããŸãã ããããè§£åãã
PaintFilterStarterã«ç§»åããŠ
PaintFilter.uprojectãéã
ãŸã ã æ¬¡ã®ã·ãŒã³ã衚瀺ãããŸãã
æéãç¯çŽããããã«ãã·ãŒã³ã«ã¯ãã§ã«
PP_Kuwaharaã®ãã¹ãããã»ã¹ããªã¥ãŒã ã
ãããŸãã ããã¯ã倿Žãããããªã¢ã«ïŒããã³ã·ã§ãŒããŒãã¡ã€ã«ïŒã§ãã
ãŸããKawaharaãã£ã«ã¿ãŒãšã¯äœãããããŠã©ã®ããã«æ©èœããããçè§£ããŸãããã
å·åãã£ã«ã¿ãŒ
åçãæ®ããšããç»åã«ãããããã質æãããããšã«æ°ä»ãã§ãããã ããã¯ç§ãã¡ã絶察ã«å¿
èŠãšããªã
ãã€ãºã§ãã
éåžžããã€ãºã¯ããŒãããªã©ã®ããŒãã¹ãã£ã«ã¿ãŒã䜿çšããŠé€å»ãããŸãã 以äžã¯ãååŸ5ã®ããã¯ã¹ãã©ãŒãé©çšããåŸã®ãã€ãºã®å€ãç»åã§ãã
ã»ãšãã©ã®ãã€ãºã¯æ¶ããŸãããããã¹ãŠã®å¢çç·ã¯ã·ã£ãŒããã倱ããŸããã ç»å
ãæ»ããã«ããŠãªããžã§ã¯ãã®å¢çãä¿åã§ãããã£ã«ã¿ãŒãããã°ããã®ã«ïŒ
ãæ³åã®ãšãããã«ã¯ãã©ãã£ã«ã¿ãŒã¯ãããã®èŠä»¶ããã¹ãŠæºãããŠããŸãã ä»çµã¿ãèŠãŠã¿ãŸãããã
å·åãã£ã«ã¿ãªã³ã°ã®ä»çµã¿
ç³ã¿èŸŒã¿ã®ããã«ãã«ã¯ãã©ãã£ã«ã¿ãŒã¯ã³ã¢ã䜿çšããŸããã1ã€ã§ã¯ãªã4ã€ã䜿çšãããŸãã ã³ã¢ã¯ã1ã€ã®ãã¯ã»ã«ã§ïŒçŸåšã®ïŒãªãŒããŒã©ããããããã«é
眮ãããŸãã 以äžã¯ãKawaharaãã£ã«ã¿ãŒã®ã³ã¢ã®äŸã§ãã
ãŸããåã³ã¢ã®
å¹³å ïŒå¹³åè²ïŒãèšç®ããŸãã ãã®ãããã³ã¢ããŒãããã€ãŸããã€ãºãæ»ããã«ããŸãã
ãŸããåã³ã¢ã«ã€ããŠã
忣ãèšç®ããŸãã å®éãããã¯ã³ã¢ã®è²ãã©ãã ãå€åãããã®å°ºåºŠã§ãã ããšãã°ãåç³»è²ã®ã³ã¢ã®åæ£ã¯
äœããªããŸãã è²ãç°ãªãå Žåãã³ã¢ã®åæ£ã¯
é«ããªããŸãã
泚ïŒåæ£ã®æŠå¿µã«ç²ŸéããŠããªãå ŽåããŸãã¯ãã®èšç®æ¹æ³ãããããªãå Žåã¯ããæ°åŠã®æšæºåå·®ãšåæ£ã¯æ¥œããããšããèšäºããèªã¿ãã ããã
æåŸã«ã忣ãæå°ã®ã³ã¢ãèŠã€ãããã®å¹³åå€ãå°ãåºããŸãã 忣ã«åºã¥ããéžæã®ãããã§ãKawaharaãã£ã«ã¿ãŒã¯å¢çãç¶æã§ããŸãã ããã€ãã®äŸãèŠãŠã¿ãŸãããã
å·åãéã®äŸ
以äžã¯ã10x10ã®ã°ã¬ãŒã¹ã±ãŒã«ç»åã§ãã å·Šäžããå³äžã®è§ã«åãã£ãŠãå¢çç·ãããããšãããããŸãã ãŸããç»åã®äžéšã®é åã«ãã€ãºãååšããããšã«æ°ä»ããããããŸããã
æåã«ãã¯ã»ã«ãéžæããã©ã®ã³ã¢ã®åæ£ãæå°ãã倿ããŸãã å¢çç·ãšãã®é¢é£ã«ãŒãã«ã®é£ã®ãã¯ã»ã«ã¯æ¬¡ã®ãšããã§ãã
ã芧ã®ãšãããå¢çã«ããæ žã®è²ã¯å€§ããç°ãªããŸãã ããã¯é«åæ£ã«ã€ããŠæããŠããããã£ã«ã¿ãŒãããããéžæããªãããšãæå³ããŸãã å¢çç·äžã«ããã³ã¢ã®éžæãåé¿ããããšã«ããããã£ã«ã¿ãŒã¯ãŒãããå¢çç·ã®åé¡ãæé€ããŸãã
ãã®ãã¯ã»ã«ã®å Žåããã£ã«ã¿ãŒã¯æãåäžã§ãããããç·è²ã®ã³ã¢ãéžæããŸãã åºåå€ã¯ãç·ã®ã³ã¢ã®å¹³åå€ãã€ãŸãé»ã«è¿ãè²ã«ãªããŸãã
å¢çç·ãšãã®ã³ã¢ã®ãã1ã€ã®ãã¯ã»ã«ã次ã«ç€ºããŸãã
ä»åã¯ãé»è²ã®ã³ã¢ã®åæ£ãæå°ã«ãªããŸããããã¯ãå¢çã«ãªãå¯äžã®ã³ã¢ã ããã§ãã ãããã£ãŠãåºåå€ã¯é»è²ã®ã³ã¢ã®å¹³åãã€ãŸãçœã«è¿ãè²ã«ãªããŸãã
以äžã¯ãããã¯ã¹ãã©ãŒãšååŸ5ã®å·åãã£ã«ã¿ãªã³ã°ã®æ¯èŒã§ãã
ã芧ã®ãšãããå·åãã£ã«ã¿ãªã³ã°ã¯ãå¢çç·ãæ»ããã«ããŠç¶æãããšããçŽ æŽãããä»äºãããŠããŸãã ç§ãã¡ã®å Žåããã£ã«ã¿ãŒã¯å¢çç·ãããã«ã·ã£ãŒãã«ããŸããïŒ
å¶ç¶ã«ããå¢çç·ãä¿æãããã®ã¢ã³ããšã€ãªã¢ã·ã³ã°æ©èœã¯ãç»åã«ãã€ã³ããããç»åã®å€èгãäžããããšãã§ããŸãã ãã©ã·ã¹ãããŒã¯ã¯éåžžãã·ã£ãŒããªå¢çç·ãšäœãã€ãºãçæãããããã«ã¯ãã©ãã£ã«ã¿ãŒã¯çŸå®çãªç»åãèžè¡çãªã¹ã¿ã€ã«ã«å€æããã®ã«äŸ¿å©ãªéžæè¢ã§ãã
å¯å€ãµã€ãºã®å·åãã£ã«ã¿ãªã³ã°åçã®çµæã¯æ¬¡ã®ãšããã§ãã
ããªããããã§ããã Kawaharaãã£ã«ã¿ãŒã®äœæãå§ããŸãããã
Kawaharaãã£ã«ã¿ãŒã®äœæ
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ããã£ã«ã¿ãŒã¯
Global.usfãš
Kuwahara.usfã® 2ã€ã®ã·ã§ãŒããŒãã¡ã€ã«ã«åå²ãããŠããŸãã æåã®ãã¡ã€ã«ã«ã¯ãã«ãŒãã«ã®å¹³åå€ãšåæ£ãèšç®ããæ©èœãå«ãŸããŸãã 2çªç®ã®ãã¡ã€ã«ã¯ãã£ã«ã¿ãŒãšã³ããªãã€ã³ãã§ãåã³ã¢ã«å¯ŸããŠäžèšã®é¢æ°ãåŒã³åºããŸãã
æåã«ãå¹³åãšåæ£ãèšç®ãã颿°ãäœæããŸãã OSã§ãããžã§ã¯ããã©ã«ããŒãéãã
Shadersãã©ã«ããŒã«ç§»åããŸãã æ¬¡ã«
Global.usfãéã
ãŸã ã å
éšã«ã¯ã
GetKernelMeanAndVariance()
颿°ããããŸãã
颿°ã®äœæãéå§ããåã«ã远å ã®ãã©ã¡ãŒã¿ãŒãå¿
èŠã§ãã 颿°ã®ã·ã°ããã£ã次ã®ããã«å€æŽããŸãã
float4 GetKernelMeanAndVariance(float2 UV, float4 Range)
ã¡ãã·ã¥ããµã³ããªã³ã°ããã«ã¯ã2ã€ã®
for
ãå¿
èŠã§ãã1ã€ã¯æ°Žå¹³ãªãã»ããã§ãã 2ã€ç®ã¯åçŽæ¹åã®ãã®ã§ãã æåã®2ã€ã®
Rangeãã£ãã«ã«ã¯ãæ°Žå¹³ã«ãŒãã®å¢çãå«ãŸããŸãã 2çªç®ã®2ã€ã«ã¯ãåçŽãµã€ã¯ã«ã®å¢çãå«ãŸããŸãã ããšãã°ãå·Šäžã®ã³ã¢ããµã³ããªã³ã°ãããã£ã«ã¿ãŒã®ååŸã
2ã®å Žåã
Rangeã®å€ã¯æ¬¡ã®ããã«ãªããŸãã
Range = float4(-2, 0, -2, 0);
ä»ãããµã³ããªã³ã°ãéå§ããæã§ãã
ãã¯ã»ã«ãµã³ããªã³ã°
ãŸãã2ã€ã®
for
ãäœæããå¿
èŠããã
for
ã
GetKernelMeanAndVariance()
ïŒå€æ°ã®äž
GetKernelMeanAndVariance()
次ã®ã³ãŒãã远å ããŸãã
for (int x = Range.x; x <= Range.y; x++) { for (int y = Range.z; y <= Range.w; y++) { } }
ããã«ããããã¹ãŠã®ã³ã¢ãªãã»ãããåŸãããŸãã ããšãã°ãå·Šäžã®ã³ã¢ããµã³ããªã³ã°ãããã£ã«ã¿ãŒã®ååŸã
2ã®å Žåããªãã»ããã¯
ïŒ0ã0ïŒãã
ïŒ-2ã-2ïŒã®ç¯å²ã«ãªããŸãã
次ã«ããµã³ãã«ãã¯ã»ã«ã®è²ãååŸããå¿
èŠããããŸãã æ¬¡ã®ã³ãŒããå
åŽã®
for
ã«ãŒãã«è¿œå
for
ãŸãã
float2 Offset = float2(x, y) * TexelSize; float3 PixelColor = SceneTextureLookup(UV + Offset, 14, false).rgb;
æåã®è¡ã¯ããµã³ãã«ãã¯ã»ã«ã®ãªãã»ãããååŸããUV空éã«å€æããŸãã 2è¡ç®ã¯ããªãã»ããã䜿çšããŠãµã³ãã«ãã¯ã»ã«ã®è²ãååŸããŸãã
次ã«ãå¹³åãšåæ£ãèšç®ããå¿
èŠããããŸãã
å¹³åãšåæ£ã®èšç®
å¹³åã®èšç®ã¯éåžžã«ç°¡åãªã¿ã¹ã¯ã§ãã ãã¹ãŠã®è²ãåçŽã«èŠçŽãããµã³ãã«å
ã®ãã¯ã»ã«æ°ã§å²ãã ãã§ãã 忣ã«ã€ããŠã¯ã次ã®åŒã䜿çšããŸããããã§ã
xã¯ãµã³ãã«ãã¯ã»ã«ã®è²ã§ãã
æåã«è¡ãå¿
èŠãããã®ã¯ãéé¡ã®èšç®ã§ãã å¹³åãååŸããã«ã¯ã倿°
Meanã«è²ã远å ããã ãã§ãã 忣ãååŸããã«ã¯ãè²ã2ä¹ããŠãã
Varianceã«è¿œå ããå¿
èŠããããŸãã åã®ã³ãŒãã®äžã«æ¬¡ã®ã³ãŒãã远å ããŸãã
Mean += PixelColor; Variance += PixelColor * PixelColor; Samples++;
次ã«ã
for
ã«ãŒãã®åŸã«æ¬¡ã远å
for
ãŸãã
Mean /= Samples; Variance = Variance / Samples - Mean * Mean; float TotalVariance = Variance.r + Variance.g + Variance.b; return float4(Mean.r, Mean.g, Mean.b, TotalVariance);
æåã®2è¡ã¯ãå¹³åãšåæ£ãèšç®ããŸãã ãã ããåé¡ãçºçããŸãã忣ã
RGBãã£ãã«éã§åæ£ãããŸãã ããã解決ããããã«ã3è¡ç®ã§ãã£ãã«ããŸãšããŠ
åèšåæ£ãååŸããŸãã
æåŸã«ã颿°ã¯å¹³åãšåæ£ã
float4ãšããŠè¿ããŸãã å¹³åå€ã¯
RGBãã£ã³ãã«ã«ããã忣ã¯ãã£ã³ãã«
Aã«ãããŸã
ãå¹³åãšåæ£ãèšç®ãã颿°ãã§ããã®ã§ãã³ã¢ããšã«ãããåŒã³åºãå¿
èŠããããŸãã
Shadersãã©ã«ããŒã«æ»ãã
Kuwahara.usfãéããŸãã ãŸããããã€ãã®å€æ°ãäœæããå¿
èŠããããŸãã å
éšã®ã³ãŒããæ¬¡ã®ãã®ã«çœ®ãæããŸãã
float2 UV = GetDefaultSceneTextureUV(Parameters, 14); float4 MeanAndVariance[4]; float4 Range;
å倿°ã®çšéã¯æ¬¡ã®ãšããã§ãã
- UVïŒçŸåšã®ãã¯ã»ã«ã®UV座æš
- MeanAndVarianceïŒåã³ã¢ã®å¹³åãšåæ£ãä¿åããé
å
- ç¯å²ïŒçŸåšã®ã«ãŒãã«ã®
for
ã«ãŒãã®å¢çãæ ŒçŽããããã«äœ¿çš
次ã«ãã³ã¢ããšã«
GetKernelMeanAndVariance()
ãåŒã³åºãå¿
èŠããããŸãã ãããè¡ãã«ã¯ã次ã远å ããŸãã
Range = float4(-XRadius, 0, -YRadius, 0); MeanAndVariance[0] = GetKernelMeanAndVariance(UV, Range); Range = float4(0, XRadius, -YRadius, 0); MeanAndVariance[1] = GetKernelMeanAndVariance(UV, Range); Range = float4(-XRadius, 0, 0, YRadius); MeanAndVariance[2] = GetKernelMeanAndVariance(UV, Range); Range = float4(0, XRadius, 0, YRadius); MeanAndVariance[3] = GetKernelMeanAndVariance(UV, Range);
ãããã£ãŠãåã³ã¢ã®å¹³åãšåæ£ã次ã®é åºã§ååŸããŸãïŒå·Šäžãå³äžãå·Šäžãå³äžã
次ã«ã忣ãæå°ã®ã³ã¢ãéžæãããã®å¹³åå€ãå°åºããå¿
èŠããããŸãã
æå°åæ£ã«ãŒãã«ã®éžæ
忣ãæå°ã®ã«ãŒãã«ãéžæããã«ã¯ã次ã®ã³ãŒãã远å ããŸãã
åéšåã®æ©èœã¯æ¬¡ã®ãšããã§ãã
- æçµçãªè²ãšæå°ã®åæ£ãä¿æãã2ã€ã®å€æ°ãäœæããŸãã æåã®ã³ã¢ã®å¹³åå€ãšåæ£å€ã§ãããã®äž¡æ¹ãåæåããŸãã
- æ®ãã®3ã€ã®ã³ã¢ãã«ãŒãããŸãã çŸåšã®ã³ã¢ã®åæ£ãæå°ã®ãã®ãããäœãå Žåããã®å¹³åãšåæ£ã¯æ°ããFinalColorãšMinimumVarianceã«ãªããŸãã ãµã€ã¯ã«ãå®äºãããšã FinalColorã衚瀺ãããŸããããã¯ã忣ãæå°ã®ã«ãŒãã«ã®å¹³åå€ã«ãªããŸãã
Unrealã«æ»ãã
Materials \ PostProcessã«ç§»åããŸãã
PP_Kuwaharaãéãã
圱é¿ã®ãªã倿Žãå ããŠã[
é©çš ]ãã¯ãªãã¯ããŸãã ã¡ã€ã³ãšãã£ã¿ãŒã«æ»ããçµæã確èªããŸãã
ããªãè¯ãããã«èŠããŸãããããèŠããšãç»åã«å¥åŠãªãããã¯é åãããããšãããããŸãã ãããã®ããã€ãã匷調ããŸããã
ããã¯ãè»žãšæŽåããã«ãŒãã«ã䜿çšããããšã®å¯äœçšã§ãã æ¹è¯ãããããŒãžã§ã³ã®ãã£ã«ã¿ãŒãé©çšããããšã§ããã®å¹æãæžããããšãã§ã
ãŸã ãããã
Kawahara Directional FilterãšåŒã³
ãŸã ã
å·åæ¹åæ§ãã£ã«ã¿ãŒ
ãã®ãã£ã«ã¿ãŒã¯å
ã®ãã£ã«ã¿ãŒãšäŒŒãŠããŸãããã«ãŒãã«ã¯ããŒã«ã«ãã¯ã»ã«ã®æ¹åã«æããããŸãã Kawaharaæ¹åãã£ã«ã¿ãŒã®ã«ãŒãã«ã®äŸã次ã«ç€ºããŸãã
泚ïŒã³ã¢ããããªãã¯ã¹ãšããŠè¡šçŸã§ãããããéåžžã®å¹
xé«ãã§ã¯ãªãé«ãxå¹
ã®åœ¢åŒã§æž¬å®å€ãèšé²ããŸãã ãããªãã¯ã¹ã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
ããã§ããã£ã«ã¿ãŒã¯å¢çç·ã«æ²¿ã£ãŠé
眮ãããããã«ãã¯ã»ã«ã®æ¹åãæ±ºå®ããŸãã ãã®åŸãã³ã¢å
šäœãé©å®å転ãããããšãã§ããŸãã
ããŒã«ã«æ¹åãèšç®ããããã«ããã£ã«ã¿ãŒ
ã¯SobelæŒç®åã䜿çš
ããŠç³ã¿èŸŒã¿ãæž¡ããŸãã ããœãã«æŒç®åããšããçšèªãããªãã¿ã®ããã«èãããã®ã¯ãå¢çãèªèããããã®äžè¬çãªææ³ã ããã§ãã ãããããããå¢çèªèæè¡ã§ããå ŽåãããŒã«ã«ãªãªãšã³ããŒã·ã§ã³ãååŸããããã«ã©ã®ããã«äœ¿çšã§ããŸããïŒ ãã®è³ªåã«çããã«ã¯ãSobelæŒç®åã®ä»çµã¿ãçè§£ããå¿
èŠããããŸãã
Sobelãªãã¬ãŒã¿ãŒã®ä»çµã¿
1ã€ã®ã³ã¢ã®ä»£ããã«ãSobelãªãã¬ãŒã¿ãŒã¯2ã€ã®ã³ã¢ã䜿çšããŸãã
Gxã¯
æ°Žå¹³æ¹åã®
åŸé
ãäžããŸãã
Gyã¯
åçŽæ¹åã«åŸé
ãäžããŸãã ãã®ãããª3Ã3ã°ã¬ãŒã¹ã±ãŒã«ç»åãäŸãšããŠäœ¿çšããŠã¿ãŸãããã
æåã«ãåã³ã¢ã®å¹³åãã¯ã»ã«ãç³ã¿èŸŒã¿ãŸãã
åå€ã2Då¹³é¢ã«é
眮ãããšãçµæã®ãã¯ãã«ãå¢çãšåãæ¹åãæãããšãããããŸãã
ãã¯ãã«ãšX軞ã®éã®è§åºŠãèŠã€ããããã«ãåŸé
ã®å€ãã¢ãŒã¯ã¿ã³ãžã§ã³ã颿°ïŒatanïŒã«ä»£å
¥ããŸãã æ¬¡ã«ãçµæã®è§åºŠã䜿çšããŠã³ã¢ãå転ã§ããŸãã
ããããSobelæŒç®åã䜿çšããŠãã¯ã»ã«ã®ããŒã«ã«æ¹åãååŸããæ¹æ³ã§ãã ãã£ãŠã¿ããã
ããŒã«ã«ãªãªãšã³ããŒã·ã§ã³ãèŠã€ãã
Global.usfãéãã
GetPixelAngle()
å
ã«æ¬¡ã®ã³ãŒãã远å ããŸãã
float GradientX = 0; float GradientY = 0; float SobelX[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; float SobelY[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; int i = 0;
æ³šïŒ GetPixelAngle()
æåŸã®ãã©ã±ãã
GetPixelAngle()
æ¬ èœããŠããããšã«æ³šæããŠãã ããã ããã¯æå³çã«è¡ãããŸãïŒ ãããè¡ãçç±ãç¥ãããå Žåã¯
ãHLSLã·ã§ãŒããŒã«é¢ãããã¥ãŒããªã¢ã«ãåç
§
ããŠãã ããã
å倿°ã®çšéã¯æ¬¡ã®ãšããã§ãã
- GradientXïŒæ°Žå¹³æ¹åã®åŸé
ãä¿åããŸã
- GradientYïŒåçŽæ¹åã®åŸé
ãä¿åããŸã
- SobelXïŒé
åãšããŠã®æ°Žå¹³SobelæŒç®åã®äžæ ž
- SobelYïŒé
åãšããŠã®åçŽSobelæŒç®åã®ã³ã¢
- iïŒ SobelXããã³SobelYã®åã¢ã€ãã ã«ã¢ã¯ã»ã¹ããããã«äœ¿çš
次ã«ã
SobelXããã³
SobelYã³ã¢ã䜿çšããŠç³ã¿èŸŒã¿ãè¡ãå¿
èŠããããŸãã æ¬¡ã®ã³ãŒãã远å ããŸãã
for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) {
åéšåã§äœãèµ·ããããæ¬¡ã«ç€ºããŸãã
- æåã®2è¡ã¯ããµã³ãã«ãã¯ã»ã«ã®è²ãååŸããŸãã 3è¡ç®ã¯ã圩床ãäžããã°ã¬ãŒã®æ¿æ·¡ã®å€ã«å€æããŸãã ããã«ãããåã«ã©ãŒãã£ãã«ã®åŸé
ãååŸãã代ããã«ãç»åå
šäœã®åŸé
ã®èšç®ãç°¡åã«ãªããŸãã
- äž¡æ¹ã®ã³ã¢ã«ã€ããŠãã°ã¬ãŒã®æ¿æ·¡ã®ãã¯ã»ã«å€ã«å¯Ÿå¿ããã«ãŒãã«èŠçŽ ãæããŸãã æ¬¡ã«ãçµæã察å¿ããåŸé
倿°ã«è¿œå ããŸãã æ¬¡ã«ãã«ãŒãã«ã®æ¬¡ã®èŠçŽ ã®ã€ã³ããã¯ã¹ãå«ãŸããããã«ãå¢åiãçºçããŸãã
è§åºŠãååŸããã«ã¯ã
atan()
颿°ã䜿çšããŠãåŸé
å€ã眮ãæããŸãã
for
ã«ãŒãã®äžã«ã次ã®ã³ãŒãã远å ããŸãã
return atan(GradientY / GradientX);
ãã¯ã»ã«ã®è§åºŠãååŸãã颿°ãã§ããã®ã§ãã«ãŒãã«ãå転ãããããã«äœããã®æ¹æ³ã§ãããé©çšããå¿
èŠããããŸãã
ãããªãã¯ã¹ã䜿çšããŠãããè¡ãããšãã§ããŸãã
ãããªãã¯ã¹ãšã¯äœã§ããïŒ
ãããªãã¯ã¹ã¯ãæ°å€ã®2次å
é
åã§ãã ããšãã°ã次ã®2Ã3ãããªãã¯ã¹ïŒ2è¡3åïŒã§ãã
ãããªãã¯ã¹èªäœã¯ç¹ã«é¢çœããããŸããã ããããè¡åããã¯ãã«ã§ä¹ç®ãããšãè¡åã®çã®åãçŸããŸãã ããã«ãããïŒãããªãã¯ã¹ã®ã¿ã€ãã«å¿ããŠïŒå転ãã¹ã±ãŒãªã³ã°ãªã©ã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãã ããããå転ã®ããã®ãããªãã¯ã¹ãã©ã®ããã«äœæããŸããïŒ
座æšç³»ã§ã¯ã忬¡å
ã®ãã¯ãã«ããããŸãã ãããã¯ãè»žã®æ£ã®æ¹åãæ±ºå®ãã
åºæ¬ãã¯ãã«ã§ãã
以äžã¯ã2次å
座æšç³»ã®ããŸããŸãªåºåºãã¯ãã«ã®ããã€ãã®äŸã§ãã èµ€ãç¢å°ã¯Xã®æ£ã®æ¹åã瀺ããŸããç·ã®ç¢å°ã¯Yã®æ£ã®æ¹åã瀺ããŸãã
ãã¯ãã«ãå転ãããã«ã¯ããããã®åºåºãã¯ãã«ã䜿çšã
ãŠå転è¡åãäœæããŸãã ããã¯
ãå転
åŸã®åºåºãã¯ãã«ã®äœçœ®ãå«ãåçŽãªè¡åã§ãã ããšãã°ã座æš
ïŒ1ã1 ïŒã«ãã¯ãã«ïŒãªã¬ã³ãžè²ã®ç¢å°ïŒããããšããŸãã
æèšåãã«90床å転ãããããšããŸãã ãŸããåºåºãã¯ãã«ãåãéã ãå転ãããŸãã
次ã«ãåºåºãã¯ãã«ã®æ°ããäœçœ®ã䜿çšããŠ2Ã2è¡åãäœæããŸãã æåã®åã¯èµ€ãç¢å°ã®äœçœ®ã§ã2çªç®ã®åã¯ç·ã®ç¢å°ã®äœçœ®ã§ãã ãããå転è¡åã§ãã
æåŸã«ããªã¬ã³ãžè²ã®ãã¯ãã«ãšå転è¡åã䜿çšããŠè¡åä¹ç®ãå®è¡ããŸãã çµæã¯ããªã¬ã³ãžè²ã®ãã¯ãã«ã®æ°ããäœçœ®ã«ãªããŸãã
æ³šïŒ HLSLã«ã¯ãã®ããã®çµã¿èŸŒã¿é¢æ°ããããããè¡åä¹ç®ã®å®è¡æ¹æ³ãç¥ãå¿
èŠã¯ãããŸããã ããããç¥ãããå Žåã¯ãMath is Funã®ã è¡åãä¹ç®ããæ¹æ³ãã®èšäºãåç
§ããŠãã ããã
ããã¯çŽ æŽãããããšã§ã¯ãããŸãããïŒ ããããããã«è¯ãã®ã¯ãäžèšã®ãããªãã¯ã¹ã䜿çšããŠã2Dãã¯ãã«ãæèšåãã«90床å転ã§ããããšã§ãã ãã£ã«ã¿ãŒã«ã€ããŠèšãã°ãããã¯ãåãã¯ã»ã«ã®å転è¡åãäžåºŠäœæãããããã³ã¢å
šäœã«äœ¿çšããã®ã«ååã§ããããšãæå³ããŸãã
次ã«ãå転è¡åã䜿çšããŠã«ãŒãã«ãå転ãããŸãã
ã³ã¢å転
ãŸãã
GetKernelMeanAndVariance()
ã倿ŽããŠã2Ã2ãããªãã¯ã¹ã
GetKernelMeanAndVariance()
ããå¿
èŠããããŸãã ããã¯ã
Kuwahara.usfã§å転è¡åãäœæããŠè»¢éããããã«å¿
èŠã§ãã
GetKernelMeanAndVariance()
眲åãæ¬¡ã®ããã«å€æŽããŸãã
float4 GetKernelMeanAndVariance(float2 UV, float4 Range, float2x2 RotationMatrix)
次ã«ãå
åŽã®
for
ã«ãŒãã®æåã®è¡ã次ã®ã³ãŒãã«çœ®ãæããŸãã
float2 Offset = mul(float2(x, y) * TexelSize, RotationMatrix);
mul()
ã¯ãoffsetãš
RotationMatrixã䜿çšããŠè¡åä¹ç®ãè¡ããŸãã ãããã£ãŠãçŸåšã®ãã¯ã»ã«ãäžå¿ã«ãªãã»ãããå転ãããŸãã
次ã«ãå転è¡åãäœæããå¿
èŠããããŸãã
å転è¡åãäœæãã
å転è¡åãäœæããã«ã¯ã次ã®ããã«æ£åŒŠé¢æ°ãšäœåŒŠé¢æ°ãé©çšããŸãã
Global.usfãéãã
Kuwahara.usfãéããŸãã æ¬¡ã«ã倿°ã®ãªã¹ãã®äžã«æ¬¡ã远å ããŸãã
float Angle = GetPixelAngle(UV); float2x2 RotationMatrix = float2x2(cos(Angle), -sin(Angle), sin(Angle), cos(Angle));
æåã®è¡ã¯ãçŸåšã®ãã¯ã»ã«ã®è§åºŠãèšç®ããŸãã 2è¡ç®ã¯ãè§åºŠã䜿çšããŠå転è¡åãäœæããŸãã
æåŸã«ãã³ã¢
RotationMatrixããšã«è»¢éããå¿
èŠããããŸãã
GetKernelMeanAndVariance()
ååŒã³åºããæ¬¡ã®ããã«å€æŽããŸãã
GetKernelMeanAndVariance(UV, Range, RotationMatrix)
ãããŠãããã§å·åæ¹åæ§ãã£ã«ã¿ãŒã®äœæãå®äºããŸããïŒ
Kuwahara.usfãéããŠ
PP_Kuwaharaã«æ»ããŸãã äœã«ã圱é¿ããªã倿Žãå ããã«ã¯ã[
é©çš ]ãã¯ãªãã¯ããŠéããŸãã
以äžã®ç»åã¯ãåŸæ¥ã®ã«ã¯ãã©ãã£ã«ã¿ãŒãšæåæ§ã«ã¯ãã©ãã£ã«ã¿ãŒã®æ¯èŒã瀺ããŠããŸãã æ¹åæ§ãã£ã«ã¿ãŒã¯ããããã³ã°ãäœæããªãããšã«æ³šæããŠãã ããã
æ³šïŒ PPI_Kuwaharaã䜿çšããŠããã£ã«ã¿ãŒã®ãµã€ãºã倿Žã§ããŸãã Xã«æ²¿ã£ãååŸãYã«æ²¿ã£ãååŸããã倧ãããªãããã«ãã£ã«ã¿ãŒã®ãµã€ãºã倿Žããããšããå§ãããŸãã ããã«ãããå¢çã«æ²¿ã£ãŠã³ã¢ã®ãµã€ãºã倧ãããªããæåæ§ã®äœæã«åœ¹ç«ã¡ãŸãã
次ã¯ã©ããžè¡ããŸããïŒ
宿ãããããžã§ã¯ãã¯
ãã¡ãããããŠã³ããŒãã§ããŸãã
Kawaharaãã£ã«ã¿ãŒã«ã€ããŠè©³ããç¥ãããå Žåã¯ã
ç°æ¹æ§Kawaharaãã£ã«ã¿ãŒã«é¢ããèšäºãåç
§ããŠãã ããã å®éãå·åæ¹åæ§ãã£ã«ã¿ãŒã¯ããã®èšäºã§ç޹ä»ãããã£ã«ã¿ãŒã®ç°¡æããŒãžã§ã³ã§ãã
ãããªãã¯ã¹ã䜿ã£ãŠæ°ãããšãã§ã¯ããäœæã§ããããã«ããããªãã¯ã¹ãå®éšããããšããå§ãããŸãã ããšãã°ãå転è¡åãšãŒããè¡åã®çµã¿åããã䜿çšããŠãæŸå°ç¶ãŸãã¯å圢ã®ãŒãããäœæã§ããŸãã ãããªãã¯ã¹ãšãã®ä»çµã¿ã®è©³çްã«ã€ããŠã¯ã3Blue1Brown
Essence of Linear Algebraã®ãããªã·ãªãŒãºãã芧ãã ããã