{"id":42618,"date":"2018-05-01T06:00:38","date_gmt":"2018-05-01T10:00:38","guid":{"rendered":"http:\/\/shamusyoung.com\/twentysidedtale\/?p=42618"},"modified":"2018-05-01T06:21:24","modified_gmt":"2018-05-01T10:21:24","slug":"pixel-city-redux-4-i-didnt-know-i-didnt-know-that","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=42618","title":{"rendered":"Pixel City Redux #4: I Didn&#8217;t Know I Didn&#8217;t Know That"},"content":{"rendered":"<p>In the last entry I hacked together a solution that let me draw my scene without using a framebuffer object. But now I&#8217;m realizing that even though I got lighting working, I still don&#8217;t have the features I need to make this work.<\/p>\n<h3>The Loss of Framebuffer Effects<\/h3>\n<p>One of my goals at the start of this project was to mess around with goofy color reduction and dithering effects. I don&#8217;t know why, really. It was just something I wanted to see in action. <\/p>\n<p>The idea I had for dithering would squash the image down to just 16 colors, which would produce something like this:<\/p>\n<p><!--more--><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_fx1.jpg' width=100% alt='I strongly suspect this effect won&apos;t do much unless you apply it to a near-photoreal scene, but I still want to run the experiment.' title='I strongly suspect this effect won&apos;t do much unless you apply it to a near-photoreal scene, but I still want to run the experiment.'\/><\/div><div class='mouseover-alt'>I strongly suspect this effect won&apos;t do much unless you apply it to a near-photoreal scene, but I still want to run the experiment.<\/div><\/p>\n<p>With lots of colored lighting, stark shadows, and the right surface textures, that might look really interesting. Like pixel art in motion? The other idea was to simply reduce the resolution of the individual color channels to make something like this:<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_fx2.jpg' width=100% alt='It doesn&apos;t look very interesting here, but in on old OpenGL project I got some semi-interesting results out of this.' title='It doesn&apos;t look very interesting here, but in on old OpenGL project I got some semi-interesting results out of this.'\/><\/div><div class='mouseover-alt'>It doesn&apos;t look very interesting here, but in on old OpenGL project I got some semi-interesting results out of this.<\/div><\/p>\n<p>Again, there might be some combination of lighting, shadows, bloom FX, and surface textures that would make something unique. (As opposed to just &#8220;pixelated&#8221;.) <\/p>\n<p>I really enjoy this sort of crazy mixing of technology levels. Like, &#8220;What would it look like if you were doing modern-day 3D rendering on the EGA displays of the late 1980s?&#8221; Maybe it would yield a distinctive look, or maybe it would just result in something confusing and dull. The only way to be sure would be to do the experiment and see how it looks.<\/p>\n<p>Sadly, I have to abandon this idea. These effects require the use of a framebuffer. You need to be able to render the entire screen into a framebuffer, and then copy it into the viewport using some sort of special effects shader. No framebuffer means no full-screen effects. <\/p>\n<p>This also means no bloom lighting, which is another thing I wanted to experiment with. I wondered what it would look like if you only applied bloom to certain color channels. Like, blue light blooms, but red light doesn&#8217;t. It might look something like this:<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_fx3.jpg' width=100% alt='I know bloom lighting gets a lot of hate, but I think it&apos;s a bit like CGI. People only notice it when it&apos;s done poorly.' title='I know bloom lighting gets a lot of hate, but I think it&apos;s a bit like CGI. People only notice it when it&apos;s done poorly.'\/><\/div><div class='mouseover-alt'>I know bloom lighting gets a lot of hate, but I think it&apos;s a bit like CGI. People only notice it when it&apos;s done poorly.<\/div><\/p>\n<p>I know this is somehow possible in Unity, because <a href=\"?p=42010\">Nightdive Studios did something like this in the System Shock Remake<\/a> demo, and that was written in Unity:<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/sshock2016_unity1.jpg' width=100% alt='Can we call this... bluem lighting?' title='Can we call this... bluem lighting?'\/><\/div><div class='mouseover-alt'>Can we call this... bluem lighting?<\/div><\/p>\n<p>I&#8217;m guessing the &#8220;dreamy&#8221; look of this image comes from bloom lighting with the blue channel boosted, and I really wanted to try that out on my city.<\/p>\n<p>But to do all this I&#8217;d need to figure out how to gain access to framebuffer effects in Unity, and:<\/p>\n<p>1) The documentation on this rendering path is so sketchy it borders on classified.<br \/>\n2) What little I can find out about it indicates it&#8217;s built around rendering the scene with normal maps, with the assumption that you&#8217;re going for modern-day rendering conventions. So even if I did gather enough information on how to use Unity&#8217;s deferred render path, I&#8217;d still need to perform extensive modifications to adopt it to my gonzo rendering style. (And it might not even be possible to do so.)<\/p>\n<div class=\"dmnotes\">A few days after writing this I found the post-processing effects. It would have allowed me to do all of the stuff above, but none of the search terms I came up with took me to the secret chamber on knowledge I needed to proceed. I found a post-processing effect that does bloom lighting, but it&#8217;s a black box and I can&#8217;t figure out how to get the source. (I&#8217;m sure I&#8217;ve got the source SOMEWHERE on my machine in the \/Unity install folder, but with no indication of what it&#8217;s called or how to set it up, I&#8217;d have to re-write and re-implement the entire thing. <\/p>\n<p>It&#8217;s a shame, because I&#8217;m sure I could do the blue bloom lighting by changing a single line of code, but I can&#8217;t get the info on where that one line of code would go.<\/p><\/div>\n<p>Using Unity is really odd. Sometimes huge, complex tasks can be automated in just a couple of lines of code, and sometimes seemly-obvious things become unreasonably complex. For the last five days I&#8217;ve been saying, &#8220;Everything in Unity is either trivial or impossible!&#8221; That&#8217;s not really true, but it feels true.<\/p>\n<p>Enough whining. Let&#8217;s get back to work.<\/p>\n<h3>Streets<\/h3>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_buildings1.jpg' width=100% alt='Bah. Close enough. Ship it.' title='Bah. Close enough. Ship it.'\/><\/div><div class='mouseover-alt'>Bah. Close enough. Ship it.<\/div><\/p>\n<p>In previous entries you might have spotted some streets with traffic lines and proper intersections. In this write-up I&#8217;m listing features in order and talking about them in isolation because that makes it easier to follow, but the truth is that I bounced around and worked on a lot of different things. If I got stuck on one thing, I&#8217;d switch over to another task until I got an idea of how to solve the first problem.<\/p>\n<p>So let&#8217;s go back and talk about how I made those streets, because I ran into an amusing situation.<\/p>\n<p>Like I said in <a href=\"?p=42400\">part 1<\/a>, I scribbled some random lines down to use as streets. That would form something like this:<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_streets1.jpg' width=100% alt='Finally, a nice easy problem for a change.' title='Finally, a nice easy problem for a change.'\/><\/div><div class='mouseover-alt'>Finally, a nice easy problem for a change.<\/div><\/p>\n<p>Then I just need to see where the lines cross each other. I can split them at those points and insert intersections. That will leave me with something like this:<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_streets2.jpg' width=100% alt='So simple a child could do it! Sadly, there aren&apos;t any kids around at the moment and I&apos;m stumped.' title='So simple a child could do it! Sadly, there aren&apos;t any kids around at the moment and I&apos;m stumped.'\/><\/div><div class='mouseover-alt'>So simple a child could do it! Sadly, there aren&apos;t any kids around at the moment and I&apos;m stumped.<\/div><\/p>\n<p>Okay, so I just need to take two arbitrary line segments and derive their intersection point. (Assuming they have one.) To do that I&#8217;ll need to&#8230;<\/p>\n<p>Um.<\/p>\n<h3>This Should Be Easy, Right?<\/h3>\n<p>Hang on. Why can&#8217;t I figure this out? I really expected this would be easy, but now that I&#8217;m about to type the code I suddenly realize <i>I have no idea how to do this<\/i>. And it seems like it should be simple, right? &#8220;Where do two lines intersect?&#8221; That sounds like a simple operation. It certainly seems simple compared to fancy stuff like surface normals and reflection vectors and transformation matricies. <\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_streets3.jpg' width=100% alt='I mean, it&apos;s RIGHT THERE.' title='I mean, it&apos;s RIGHT THERE.'\/><\/div><div class='mouseover-alt'>I mean, it&apos;s RIGHT THERE.<\/div><\/p>\n<p>Oh right, I can look at the point and see how far it is from the ends and that will tell me&#8230;<\/p>\n<p>No, that will tell me if the point falls within the line, but first I need to find the point. <\/p>\n<p>(Moments of confusion and embarrassment pass. I feel like some kid who&#8217;s been asked to write a word on the chalkboard, and it&#8217;s not until I&#8217;m holding the chalk in my hand that I realize I no longer speak English. Why am I having so much trouble?)<\/p>\n<p>This is silly. I can do this. What if&#8230;<\/p>\n<p>Okay, what if I connect two of the endpoints? This will form two of the corners of a triangle. It should be easy to get the inside angles of those two corners, and I can use those to somehow derive&#8230;<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_streets4.jpg' width=100% alt='I worked out a formula to solve this, but it only works on left triangles.' title='I worked out a formula to solve this, but it only works on left triangles.'\/><\/div><div class='mouseover-alt'>I worked out a formula to solve this, but it only works on left triangles.<\/div><\/p>\n<p>Huh. I actually have no idea how to do this. I guess this is the sort of predicament you find yourself in when you&#8217;re self-taught. I&#8217;m not surprised I have gaps like this in my knowledge, but I am surprised I didn&#8217;t know that I didn&#8217;t know this until I tried to do it. That&#8217;s funny. <\/p>\n<p>Anyway, I search around and I find a code snippet that does the job for me. I have to convert it into C#, but it works:<\/p>\n<pre lang=\"C\" line=\"1\">\r\npublic bool Intersects (LineSegment other, ref Vector2 intersection_position) \r\n{\r\n\t\/\/First let's try to avoid the heavy math with simple bounding checks.\r\n\tBbox2\tbox1 = new Bbox2();\r\n\tBbox2   box2 = new Bbox2();\r\n\r\n\tbox1.Contain (start);\r\n\tbox1.Contain (end);\r\n\tbox2.Contain (other.start);\r\n\tbox2.Contain (other.end);\r\n\tif (!box1.Intersect (box2))\r\n\t\treturn false;\r\n\r\n\tfloat\t\ta1 = end.y - start.y;\r\n\tfloat\t\tb1 = start.x - end.x;\r\n\tfloat\t\tc1 = a1 * start.x + b1 * start.y;\r\n\r\n\tfloat\t\ta2 = other.end.y - other.start.y;\r\n\tfloat\t\tb2 = other.start.x - other.end.x;\r\n\tfloat\t\tc2 = a2 * other.start.x + b2 * other.start.y;\r\n\r\n\tfloat det = a1*b2 - a2*b1;\r\n\tif (det == 0)\r\n\t\treturn false;\r\n\tintersection_position.x = (b2*c1 - b1*c2) \/ det;\r\n\tintersection_position.y = (a1 * c2 - a2*c1) \/ det;\r\n\t\/\/The above checks can figure out WHERE the intersection takes place, but that \r\n\t\/\/point might only be reachable by continuing one of the segments.\r\n\t\/\/Now make sure this point falls WITHIN the segments.\r\n\tfloat\tto_intersection;\r\n\tfloat\tmy_length = Length ();\r\n\tfloat\tother_length = other.Length ();\r\n\tto_intersection = (start - intersection_position).magnitude;\r\n\tif (to_intersection > my_length)\r\n\t\treturn false;\r\n\tto_intersection = (end - intersection_position).magnitude;\r\n\tif (to_intersection > my_length)\r\n\t\treturn false;\r\n\tto_intersection = (other.start - intersection_position).magnitude;\r\n\tif (to_intersection > other_length)\r\n\t\treturn false;\r\n\tto_intersection = (other.end - intersection_position).magnitude;\r\n\tif (to_intersection > other_length)\r\n\t\treturn false;\r\n\t\/\/All tests pass. The point must be good.\r\n\treturn true;\r\n}\r\n<\/pre>\n<p>It works, so whatever.<\/p>\n<h3>Getting Rid of a Bad Idea<\/h3>\n<p>Remember in part one I put down all these little &#8220;sidewalk marker&#8221; objects? At the time, I was envisioning this system where sidewalks would be very organic. Roads would crisscross and form little traffic islands and such. Stuff like this:<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_gta5_islands.jpg' width=100% alt='These aren&apos;t just traffic islands. This is an archipelago.' title='These aren&apos;t just traffic islands. This is an archipelago.'\/><\/div><div class='mouseover-alt'>These aren&apos;t just traffic islands. This is an archipelago.<\/div><\/p>\n<p>But now that I&#8217;m working on this, I&#8217;m not really interested in messing around with organically-grown traffic islands. They&#8217;re interesting, but they&#8217;re not the kind of feature you need. The scene won&#8217;t look incomplete without them.<\/p>\n<p>Also, having the program chew through thousands of these stupid sidewalk points is slow to the point of annoyance. If I&#8217;m not using them to do anything sophisticated, then there&#8217;s no reason to have a sophisticated system. <\/p>\n<p>Highlight code. Press delete.<\/p>\n<p>Now we can build blocks a much simpler way. <\/p>\n<p>We take all our streets, cut them up where they intersect, and put intersection objects at the split location. This intersection will mediate the connections between all the roads that feed into it. <\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_streets5.jpg' width=100% alt='Damn it, THAT&apos;S why I couldn&apos;t find the intersection points. They were hiding behind these big black dots!' title='Damn it, THAT&apos;S why I couldn&apos;t find the intersection points. They were hiding behind these big black dots!'\/><\/div><div class='mouseover-alt'>Damn it, THAT&apos;S why I couldn&apos;t find the intersection points. They were hiding behind these big black dots!<\/div><\/p>\n<p>Once all the streets are plugged into their respective intersections, we go around and look for hanging dead-end streets. We throw these away.<\/p>\n<p><div class='imagefull'><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/pixelcity2_streets6.jpg' width=100% alt='Great. Ship it.' title='Great. Ship it.'\/><\/div><div class='mouseover-alt'>Great. Ship it.<\/div><\/p>\n<p>The block builder will grab one side of the street and just keep making right turns until it gets back to where it started. When it&#8217;s done, it&#8217;s formed a block.<\/p>\n<p>This is still a very primitive system. I&#8217;ll need to add a way to have streets of varying widths, and maybe more variation in the spacing. But I plan on adding a &#8220;region&#8221; system later where different parts of the city will have different streets \/ buildings. Until then, I think this is good enough. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last entry I hacked together a solution that let me draw my scene without using a framebuffer object. But now I&#8217;m realizing that even though I got lighting working, I still don&#8217;t have the features I need to make this work. The Loss of Framebuffer Effects One of my goals at the start [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66],"tags":[],"class_list":["post-42618","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/42618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=42618"}],"version-history":[{"count":17,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/42618\/revisions"}],"predecessor-version":[{"id":42677,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/42618\/revisions\/42677"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=42618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=42618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=42618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}