{"id":1942,"date":"2019-07-27T16:57:43","date_gmt":"2019-07-27T14:57:43","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1942"},"modified":"2019-07-27T19:32:54","modified_gmt":"2019-07-27T17:32:54","slug":"headless-render-of-voronoi-shadertoy-via-d3d11-and-media-foundation","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1942","title":{"rendered":"Headless render of Voronoi shadertoy via D3D11 and Media Foundation"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Fancy stuff goes first:<\/p>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Shadertoy D3D11 headless render\" width=\"1040\" height=\"780\" src=\"https:\/\/www.youtube.com\/embed\/2-x4NyvzazM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is an application that renders <a href=\"https:\/\/www.shadertoy.com\/view\/WtXXWS\">this shadertoy by Taron<\/a> into a video file with requested metrics. Why?<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>it looks great<\/li><li>it is a source of content used for various development and testing purposes<\/li><\/ol>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Video is rendered on GPU (Radeon RX 570 Series in this particular case, Intel(R) UHD Graphics 630 does the job great too), compressed with the help of GPU hardware and the steps are also connected one to the other through Media Foundation without leaving GPU, and in this sense it is worth mentioning that intensive render process happens with CPU load near idle levels:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"546\" height=\"600\" src=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/Clipbrd1-546x600.png\" alt=\"\" class=\"wp-image-1943\" srcset=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/Clipbrd1-546x600.png 546w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/Clipbrd1-291x320.png 291w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/Clipbrd1-768x844.png 768w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/Clipbrd1-600x659.png 600w, https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/Clipbrd1.png 1291w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A run to produce a 2160&#215;1440@60 video file with duration of 300 second (above on YouTube) took 209.56 seconds, that is the process runs 30+ percent faster compared to real-time, and according to task manager charts above it&#8217;s the encoder limitation: 3D part alone runs faster than this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\>RenderMfSw -re 2160 1440 -ra 60 -d 300 -b 8000000 Output.mp4\nElapsed Time: 209.56 seconds<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Video frames are rendered into <code>DXGI_FORMAT_B8G8R8A8_UNORM<\/code> (<code>MFVideoFormat_ARGB32<\/code>) textures, so there is an implicit RGB to YUV conversion, which at this time happened on AMD MFT side and presumably loads GPU compute queue with the conversion task.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Have fun generating your own content: it is possible to define resolution, frame rate, duration and bitrate of interest.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\>RenderMfSw\nSyntax: RenderMfSw [options] &lt;output-path>\n\nOptions:\n  -DisableDebugOutput - Disable forward of debug output to console output in debug mode (should appear before -Debug)\n  -Debug[:&lt;Normal|Full|&lt;Value>>] - Enable self-debugging capability with specific minidump type\n  -EnumerateAdapters - Enumerate DXGI adapters and exit\n  -AdapterIndex &lt;index> - Specify DXGI adapter index (default is 0)\n  -Resolution &lt;width> &lt;height> - Specify resolution of generated video (default is 1920x1080)\n  -Rate &lt;frame-rate-numerator>[\/&lt;frame-rate-denominator>] - Specify frame rate of generated video (default is 60)\n  -Duration &lt;duration> - Specify duration of generated video in seconds (default is 60)\n  -Bitrate &lt;bitrate> - Specify bitrate of generated video in seconds (default is 10 MBps)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The HLSL source code for the shaders is embedded as an <code>RCDATA<\/code> resource into the executable in source code, so it is possible to extract and even update if needed (for the most curious).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Download links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Binaries: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>64-bit: <a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2019\/07\/RenderMfSw.7z\">RenderMfSw.exe<\/a> (in .7z archive)<\/li><li>License: This software is free to use<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Fancy stuff goes first: This is an application that renders this shadertoy by Taron into a video file with requested metrics. Why? it looks great it is a source of content used for various development and testing purposes<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[550,379,572,424,426,132,486],"class_list":["post-1942","post","type-post","status-publish","format-standard","hentry","category-video","tag-d3d11","tag-h-264","tag-hlsl","tag-media-foundation","tag-mft","tag-utility","tag-video"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1942"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1942\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}