{"id":156,"date":"2020-08-27T09:12:24","date_gmt":"2020-08-27T09:12:24","guid":{"rendered":"http:\/\/half4.xyz\/?p=156"},"modified":"2024-02-05T18:50:09","modified_gmt":"2024-02-05T18:50:09","slug":"part-4-skin-shader","status":"publish","type":"post","link":"https:\/\/half4.xyz\/index.php\/2020\/08\/27\/part-4-skin-shader\/","title":{"rendered":"Part 4: Skin Shader"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Now we need to bring out LUT into a skin shader. For this tutorial, we\u2019ll be using the Bust_Outdoors level from the Digital Human content pack, which you get through the Epic Games Launcher (via Unreal Engine -&gt; Learn).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"563\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-64-1024x563.png\" alt=\"\" class=\"wp-image-354\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-64-1024x563.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-64-300x165.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-64-768x422.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-64-1536x844.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-64-2048x1125.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once you\u2019re there, we\u2019ll move on to some quick theory:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When recolouring the skin, what we want is the ability to change <em>just<\/em> the underlying skin tone. In an ideal world, we also want to be able to texture the skin in the normal workflow way \u2013 so we texture an albedo map. This makes it easier to author, and will work with existing assets you may have.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But how do we do this? If we use a Hue\/Saturation\/Lightness adjustment to the skin, we may end up changing the colour of the lips or other scars and blemishes, too \u2013 which is not what we want. All we want to change is the chromophore contribution to the skin tone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The solution is to divide the albedo texture by the original chromophore contribution, then multiply it by the new chromorphore contribution:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u03b1= (\u03b1\/ \u03b2)\u03b3<br><em>Where \u03b1 is the albedo, \u03b2 is the underlying chromophore contribution, and \u03b3 is the new target chromophore contirbution.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By dividing, we remove the chromophore contribution from the albedo, leaving only the remaining color contribution from blemishes, lips, etc. We can then add in a new color by multiplying it in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, we need to get the chromophore contribution in the head texture. To do this,:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the Albedo in Photoshop<\/li>\n\n\n\n<li>Select an area of skin that doesn\u2019t have too many blemishes and is fairly even in skin tone<\/li>\n\n\n\n<li>Go Filter -&gt; Blur -&gt; Average<\/li>\n\n\n\n<li>Use the color picker to get the Hex value for this new skin color<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" width=\"1024\" height=\"977\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-48-1024x977.png\" alt=\"\" class=\"wp-image-321\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-48-1024x977.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-48-300x286.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-48-768x733.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-48.png 1210w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" width=\"870\" height=\"553\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-49.png\" alt=\"\" class=\"wp-image-322\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-49.png 870w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-49-300x191.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-49-768x488.png 768w\" sizes=\"(max-width: 870px) 100vw, 870px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next we need to import our LUT correctly. Import the PNG we output from our Monte Carlo simulation, then double click the uasset, and change its settings to the following, then save:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"385\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-50-1024x385.png\" alt=\"\" class=\"wp-image-323\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-50-1024x385.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-50-300x113.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-50-768x289.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-50-1536x578.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-50.png 1827w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">These are required so we keep defined edges between our 3 LUT areas \u2013 using a different filter will cause blurry edges. Clamping the texture prevents large or negative values in the shader looping back around \u2013 it just makes it less prone to user-error.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we shall head into UE4 and create a new Material Function called MF_SkinLUT. Open it up and construct the following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"317\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-51-1024x317.png\" alt=\"\" class=\"wp-image-324\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-51-1024x317.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-51-300x93.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-51-768x238.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-51-1536x475.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-51-2048x634.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">What\u2019s going on here?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We have 3 areas of our LUT for different melanin blends. We need to sample <em>two<\/em> of these areas and blend between them. For example, if we had a blend value of 0.25, we need to sample a pixel from the first LUT area (0.01 blend) and one from the second LUT area (0.5 blend), and then pick a value that is halfway between those sampled colors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will select which pixel we sample based on melanin fraction (our \u201cx-axis\u201d in each area, and hemoglobin fraction is our \u201cy-axis\u201d)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now open up the M_Skin_Bust from the character in our scene, it contains the head skin material in this scene:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"713\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-52-1024x713.png\" alt=\"\" class=\"wp-image-325\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-52-1024x713.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-52-300x209.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-52-768x535.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-52.png 1210w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now, drag in you MF_SkinLUT material function. Add in three scalar inputs, like so:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"704\" height=\"358\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-53.png\" alt=\"\" class=\"wp-image-326\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-53.png 704w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-53-300x153.png 300w\" sizes=\"(max-width: 704px) 100vw, 704px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Apply the following settings to them:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"464\" height=\"291\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-54.png\" alt=\"\" class=\"wp-image-327\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-54.png 464w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-54-300x188.png 300w\" sizes=\"(max-width: 464px) 100vw, 464px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"441\" height=\"289\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-55.png\" alt=\"\" class=\"wp-image-328\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-55.png 441w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-55-300x197.png 300w\" sizes=\"(max-width: 441px) 100vw, 441px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"442\" height=\"225\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-56.png\" alt=\"\" class=\"wp-image-329\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-56.png 442w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-56-300x153.png 300w\" sizes=\"(max-width: 442px) 100vw, 442px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next, create a Vector Parameter and set the sRGB Hex value we extracted from Photoshop:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"464\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-57-1024x464.png\" alt=\"\" class=\"wp-image-330\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-57-1024x464.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-57-300x136.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-57-768x348.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-57.png 1287w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now, divide the Albedo RGB node by this amount, then multiply that output by the output of your Material Function, just like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"691\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-58-1024x691.png\" alt=\"\" class=\"wp-image-331\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-58-1024x691.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-58-300x203.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-58-768x518.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-58-1536x1037.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-58.png 1828w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now, create a Material Instance of this Material and apply it back to your head. We do this so we can change out skin chromophore values without having to recompile shaders. You should end up with the following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"448\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-59-1024x448.png\" alt=\"\" class=\"wp-image-332\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-59-1024x448.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-59-300x131.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-59-768x336.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-59-1536x672.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-59-2048x895.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now we can start changing the skin tones!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"489\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-60-1024x489.png\" alt=\"\" class=\"wp-image-333\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-60-1024x489.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-60-300x143.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-60-768x367.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-60-1536x734.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-60.png 1911w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As an extension task, you can completely remove the Material Function and just multiply in any colour you like for some fantasy-genre skin tones:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, we maintain pinkness in the lips (that is more evident in lighter tones)<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"452\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-61-1024x452.png\" alt=\"\" class=\"wp-image-334\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-61-1024x452.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-61-300x132.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-61-768x339.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-61-1536x678.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-61-2048x904.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Appendix: Unity<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you\u2019re using Unity, you can use the following Shader Graph setup:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"355\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-69-1024x355.png\" alt=\"\" class=\"wp-image-376\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-69-1024x355.png 1024w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-69-300x104.png 300w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-69-768x266.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-69-1536x533.png 1536w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/image-69-2048x710.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The process is identical \u2013 clamp the LUT, nearest pixel filter. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here it in on the Digital Human from The Heretic project which you can grab from the Asset Store in Unity:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"804\" height=\"1024\" src=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/Examples_Unity_Melanin-804x1024.png\" alt=\"\" class=\"wp-image-369\" srcset=\"https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/Examples_Unity_Melanin-804x1024.png 804w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/Examples_Unity_Melanin-236x300.png 236w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/Examples_Unity_Melanin-768x978.png 768w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/Examples_Unity_Melanin-1206x1536.png 1206w, https:\/\/half4.xyz\/wp-content\/uploads\/2020\/07\/Examples_Unity_Melanin-1608x2048.png 1608w\" sizes=\"(max-width: 804px) 100vw, 804px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Now we need to bring out LUT into a skin shader. For this tutorial, we\u2019ll be using the Bust_Outdoors level from the Digital Human content pack, which you get through the Epic Games Launcher (via Unreal Engine -&gt; Learn). Once you\u2019re there, we\u2019ll move on to some quick theory: When recolouring the skin, what we want is the ability to change just the underlying skin tone. In an ideal world, we also want to be able to texture the skin in the normal workflow way \u2013 so we texture an albedo map. This makes it easier to author, and will work with existing assets you may have. But how do we do this? If we use a Hue\/Saturation\/Lightness adjustment to the skin, we may end up changing the colour of the lips or other scars and blemishes, too \u2013 which is not what we want. All we want to change is the chromophore contribution to the skin tone. The solution is to divide the albedo texture by the original chromophore contribution, then multiply it by the new chromorphore contribution: \u03b1= (\u03b1\/ \u03b2)\u03b3Where \u03b1 is the albedo, \u03b2 is the underlying chromophore contribution, and \u03b3 is the new target chromophore contirbution. By dividing, we remove the chromophore contribution from the albedo, leaving only the remaining color contribution from blemishes, lips, etc. We can then add in a new color by multiplying it in. First, we need to get the chromophore contribution in the head texture. To do this,: Next we need to import our LUT correctly. Import the PNG we output from our Monte Carlo simulation, then double click the uasset, and change its settings to the following, then save: These are required so we keep defined edges between our 3 LUT areas \u2013 using a different filter will cause blurry edges. Clamping the texture prevents large or negative values in the shader looping back around \u2013 it just makes it less prone to user-error. Next, we shall head into UE4 and create a new Material Function called MF_SkinLUT. Open it up and construct the following: What\u2019s going on here? We have 3 areas of our LUT for different melanin blends. We need to sample two of these areas and blend between them. For example, if we had a blend value of 0.25, we need to sample a pixel from the first LUT area (0.01 blend) and one from the second LUT area (0.5 blend), and then pick a value that is halfway between those sampled colors. We will select which pixel we sample based on melanin fraction (our \u201cx-axis\u201d in each area, and hemoglobin fraction is our \u201cy-axis\u201d) Now open up the M_Skin_Bust from the character in our scene, it contains the head skin material in this scene: Now, drag in you MF_SkinLUT material function. Add in three scalar inputs, like so: Apply the following settings to them: Next, create a Vector Parameter and set the sRGB Hex value we extracted from Photoshop: Now, divide the Albedo RGB node by this amount, then multiply that output by the output of your Material Function, just like this: Now, create a Material Instance of this Material and apply it back to your head. We do this so we can change out skin chromophore values without having to recompile shaders. You should end up with the following: Now we can start changing the skin tones! As an extension task, you can completely remove the Material Function and just multiply in any colour you like for some fantasy-genre skin tones: As you can see, we maintain pinkness in the lips (that is more evident in lighter tones) Appendix: Unity If you\u2019re using Unity, you can use the following Shader Graph setup: The process is identical \u2013 clamp the LUT, nearest pixel filter. Here it in on the Digital Human from The Heretic project which you can grab from the Asset Store in Unity:<\/p>\n","protected":false},"author":1,"featured_media":321,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[8,7],"class_list":["post-156","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-lut","tag-skin"],"_links":{"self":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts\/156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=156"}],"version-history":[{"count":14,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts\/156\/revisions"}],"predecessor-version":[{"id":1297,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/posts\/156\/revisions\/1297"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/media\/321"}],"wp:attachment":[{"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/half4.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}