{"id":53,"date":"2022-11-11T05:07:05","date_gmt":"2022-11-11T05:07:05","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/steelemeg\/?p=53"},"modified":"2022-11-11T05:08:07","modified_gmt":"2022-11-11T05:08:07","slug":"building-a-cloud-planet","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/steelemeg\/2022\/11\/11\/building-a-cloud-planet\/","title":{"rendered":"Building a cloud planet"},"content":{"rendered":"\n<p>Today I&#8217;ve been working on a project for CS450, and thought it might be fun to document my process, including the mistakes I made along the way! <\/p>\n\n\n\n<p>The assignment requires us to make a 3d object, and apply vertex and fragment shaders to change its shape and draw a pattern on it. We&#8217;re also required to apply per-fragment lighting, but that&#8217;s a project for tomorrow. <\/p>\n\n\n\n<p>I wanted to do something vaguely cloudy, and went hunting for reference images.<a href=\"https:\/\/elias-wick.com\/portfolio\/substance-designer\/page-1\"> This portfolio<\/a> has some amazing stuff, and I particularly like the picture of the arctic snow material. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/arctic-1021x1024.png\" alt=\"\" class=\"wp-image-55\" width=\"252\" height=\"252\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/arctic-1021x1024.png 1021w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/arctic-300x300.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/arctic-150x150.png 150w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/arctic-768x770.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/arctic.png 1029w\" sizes=\"auto, (max-width: 252px) 100vw, 252px\" \/><figcaption>https:\/\/elias-wick.com\/img\/portfolio\/substance-designer\/f-arctic-snow.jpg<\/figcaption><\/figure><\/div>\n\n\n\n<p>First step: draw a sphere using the shader pipeline as oppose to the OpenGL color pipeline! Simple in theory. <\/p>\n\n\n\n<p>I ran into some early obstacles getting my visual environment configured. My first attempts didn&#8217;t call the shader pipeline correctly, so I rendered a LOT of thrillingly blank backgrounds. I admit I shouted at the computer after about the fifth time seeing this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/blank.png\" alt=\"\" class=\"wp-image-56\" width=\"190\" height=\"207\" \/><figcaption>So blank! So empty! So frustrating!<\/figcaption><\/figure><\/div>\n\n\n\n<p>After finally rearranging to suit, I wrote the simplest possible vertex and fragment shaders: the vertex shader didn&#8217;t change anything, and the fragment shader made everything white. Exciting stuff!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/starting_labeled.png\" alt=\"\" class=\"wp-image-57\" width=\"377\" height=\"287\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/starting_labeled.png 551w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/starting_labeled-300x229.png 300w\" sizes=\"auto, (max-width: 377px) 100vw, 377px\" \/><figcaption>Boring spheres! Much better.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Bolstered by my boring spheres, I added a black stripe to my fragment shader, just so I could see what was going on. On to the vertex shader! One simple way to distort a sphere is to apply a wobble along one or more axes. I started with a wobble along the x axis, based on the program&#8217;s time counter. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/wobble.png\" alt=\"\" class=\"wp-image-58\" width=\"328\" height=\"325\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/wobble.png 591w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/wobble-300x297.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/wobble-150x150.png 150w\" sizes=\"auto, (max-width: 328px) 100vw, 328px\" \/><figcaption>Crazy little wobble<\/figcaption><\/figure><\/div>\n\n\n\n<p>I felt like I was getting somewhere at this point! The wobbly sphere was oddly soothing. I added more wobble along the y and z axes just to make it more interesting. But it was getting hard to see what was happening without more color variation, so it&#8217;s time to revisit the fragment shader. I know I want to do something that shows the waves in the sphere. Based on my reference image, I want to vary the color from white to a deep cloudy blue. I opted to base each fragment&#8217;s color off of the z coordinate and the amount of vertex distortion from the original spherical shape.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/wobbly-1.gif\" alt=\"\" class=\"wp-image-61\" width=\"327\" height=\"339\" \/><figcaption>And there were wobbly stripes!<\/figcaption><\/figure><\/div>\n\n\n\n<p>I thought it might be cool to add some random noise to the vertex shader to mix it up a little more. I regretted this decision pretty much instantly. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/tooMuchNoise.png\" alt=\"\" class=\"wp-image-60\" width=\"333\" height=\"300\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/tooMuchNoise.png 570w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/tooMuchNoise-300x271.png 300w\" sizes=\"auto, (max-width: 333px) 100vw, 333px\" \/><figcaption>When animated, this was pretty terrifying<\/figcaption><\/figure><\/div>\n\n\n\n<p>After hastily throwing the noise code away, I thought it might be less wild to distort the color over time. So I&#8217;m adding a second color wave pattern, and finally mixing the two together. The final call to mix is time-dependent, so the fragment shader will change independent of the vertex shader. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/stripier.png\" alt=\"\" class=\"wp-image-62\" width=\"361\" height=\"370\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/stripier.png 571w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/stripier-293x300.png 293w\" sizes=\"auto, (max-width: 361px) 100vw, 361px\" \/><figcaption>Much more soothing.<\/figcaption><\/figure><\/div>\n\n\n\n<p>The renderings are getting a little hypnotic! The next step of the project requirements are to draw a shape using the fragment shader. I&#8217;m not sure if my stripes count, and at any rate I want to add some lightning-like visuals to my cloud planet. But baby steps first&#8211;let&#8217;s draw a sphere. (In this case it&#8217;s distorted by the vertex shader, but I&#8217;m not too fussed about that.)<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/first_shape.png\" alt=\"\" class=\"wp-image-63\" width=\"368\" height=\"374\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/first_shape.png 592w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/first_shape-296x300.png 296w\" sizes=\"auto, (max-width: 368px) 100vw, 368px\" \/><figcaption>Took some trial and error, but finally got a lovely squashed circle.<\/figcaption><\/figure><\/div>\n\n\n\n<p>Using more sine\/cosine functions to turn the sphere into distorted rings that move as a function of time. These aren&#8217;t quite as lightning-like as I had in mind, so I may revisit them later.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/rings.png\" alt=\"\" class=\"wp-image-64\" width=\"380\" height=\"383\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/rings.png 595w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/rings-298x300.png 298w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/rings-150x150.png 150w\" sizes=\"auto, (max-width: 380px) 100vw, 380px\" \/><figcaption>Moving circular patterns<\/figcaption><\/figure><\/div>\n\n\n\n<p>The shapes are looking nice, but the colors are a little stark. I want the centers of the shapes to be gold, and blend into the cloud patterns on the edges. I played around with smoothstep to blend the edges of the lightning into the clouds, and was pretty pleased with the result. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/blended.png\" alt=\"\" class=\"wp-image-65\" width=\"388\" height=\"350\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/blended.png 653w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/blended-300x271.png 300w\" sizes=\"auto, (max-width: 388px) 100vw, 388px\" \/><figcaption>Now with 50% more glow!<\/figcaption><\/figure><\/div>\n\n\n\n<p>I&#8217;m pretty happy with the result at this point. It&#8217;s reasonably close to what I envisioned at the start, and I think it&#8217;s a good level of visual variety for a single fragment shader. I&#8217;d like to adjust the lightning a bit, as I&#8217;m not entirely thrilled with the behavior at the boundaries, but I have a few days to fine tune it. Tomorrow I&#8217;ll be working on per-fragment lighting, which should make help emphasize the distortions in the shape. For tonight, I&#8217;m making everyone who wanders near my computer look at my cloud planet!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5905\/files\/2022\/11\/cloudy.gif\" alt=\"\" class=\"wp-image-66\" width=\"494\" height=\"491\" \/><\/figure><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Today I&#8217;ve been working on a project for CS450, and thought it might be fun to document my process, including the mistakes I made along the way! The assignment requires us to make a 3d object, and apply vertex and fragment shaders to change its shape and draw a pattern on it. We&#8217;re also required [&hellip;]<\/p>\n","protected":false},"author":12660,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-53","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/users\/12660"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":3,"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"predecessor-version":[{"id":69,"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/posts\/53\/revisions\/69"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/steelemeg\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}