Week 9 Homework

This week’s homework was really tough because I was finding it difficult to convert from GLSL to HLSL but eventually I began to understand it better thanks to Jeremy.

Studio MDHR

Studio MDHR developed cuphead using Unity. The game uses a lot of post processing effects to add atmosphere and polish. An example of this can be seen in the rain and thunder during the Grim Matchstick boss fight. Another example of post processing is the grain and scratches overlaid on the screen throughout the entire game. The game is entirely 2D so I am guessing it uses unlit materials, increasing performance. Several particle elements appear to be created with Unity’s shader graph and have even been attempted to be recreated. The developers excelled at recreating the iconic rubber house cartoon style through art, animation and music. The 2D nature of the game shows off the great artstyle without being overbearing in detail. I think Cuphead would be a drastically different and arguably worse looking game if it included realistic reflections because it would not fit in with the hand drawn style. I’m not sure how a PBR could even be incorporated within a 2D game but it might be an interesting concept.

For some reason I can not upload images larger than 500kb so I’ve linked a google drive folder with screenshots from this week.

https://drive.google.com/drive/folders/11IuMLZDs4eP2S3q0rvQMIjHzjM0KjDh7?usp=sharing

Color wheel Shader from the book of shaders that spins using _Time.y (image 1 in google drive)

<div>
<div>Shader "Custom/week9"</div>
<div>{</div>
<div>    Properties</div>
<div>    {</div>
<div>        _Color ("Color", Color) = (1,1,1,1)</div>
<div>        _MainTex ("Albedo (RGB)", 2D) = "white" {}</div>
<div>        _Glossiness ("Smoothness", Range(0,1)) = 0.5</div>
<div>        _Metallic ("Metallic", Range(0,1)) = 0.0</div>
<div>    }</div>
<div>    SubShader</div>
<div>    {</div>
<div>        Tags { "RenderType"="Opaque" }</div>
<div>        LOD 200</div>
<div>        CGPROGRAM</div>
<div>        // Physically based Standard lighting model, and enable shadows on all light types</div>
<div>        #pragma surface surf Standard fullforwardshadows</div>
<div>        // Use shader model 3.0 target, to get nicer looking lighting</div>
<div>        #pragma target 3.0</div>
<div>        sampler2D _MainTex;</div>
<div>        struct Input</div>
<div>        {</div>
<div>            float2 uv_MainTex;</div>
<div>        };</div>
<div>        half _Glossiness;</div>
<div>        half _Metallic;</div>
<div>        fixed4 _Color;</div>
<div>        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.</div>
<div>        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.</div>
<div>        // #pragma instancing_options assumeuniformscaling</div>
<div>        UNITY_INSTANCING_BUFFER_START(Props)</div>
<div>            // put more per-instance properties here</div>
<div>        UNITY_INSTANCING_BUFFER_END(Props)</div>
<div>        float3 hsb2rgb( in float3 c ){</div>
<div>    float3 rgb = clamp(abs(fmod(c.x*6.0+float3(0.0,4.0,2.0),</div>
<div>                             6.0)-3.0)-1.0,</div>
<div>                     0.0,</div>
<div>                     1.0 );</div>
<div>    rgb = rgb*rgb*(3.0-2.0*rgb);</div>
<div>    return c.z * lerp( float3(1.0,1.0,1.0), rgb, c.y);</div>
<div>}</div>
<div>        void surf (Input IN, inout SurfaceOutputStandard o)</div>
<div>        {</div>
<div></div>
<div>    float3 color = float3(0.0,0.0,0.0);</div>
<div>    float TWO_PI= 6.28318530718;</div>
<div>    // Use polar coordinates instead of cartesian</div>
<div>    float2 center = float2(0.5, 0.5);</div>
<div>    float2 toCenter = IN.uv_MainTex - center;</div>
<div>    float angle = atan2(toCenter.x,toCenter.y);</div>
<div>    float radius = length(toCenter)*2.0;</div>
<div>    // Map the angle (-PI to PI) to the Hue (from 0 to 1)</div>
<div>    // and the Saturation to the radius</div>
<div>    color = hsb2rgb(float3((angle/TWO_PI)+_Time.y,radius,1.0));</div>
<div>    //gl_FragColor = vec4(color,1.0);</div>
<div>            // Albedo comes from a texture tinted by color</div>
<div>            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * float4(color.x,color.y,color.z,1.0);</div>
<div>            o.Albedo = c.rgb;</div>
<div>            // Metallic and smoothness come from slider variables</div>
<div>            o.Metallic = _Metallic;</div>
<div>            o.Smoothness = _Glossiness;</div>
<div>            o.Alpha = c.a;</div>
<div>        }</div>
<div>        ENDCG</div>
<div>    }</div>
<div>    FallBack "Diffuse"</div>
<div>}</div>
</div>

My attempt to recreate my arrow shader from week 2 (sadly I was not able to get this to work)

<div>
<div>Shader "Custom/week9"</div>
<div>{</div>
<div>    Properties</div>
<div>    {</div>
<div>        _Color ("Color", Color) = (1,1,1,1)</div>
<div>        _MainTex ("Albedo (RGB)", 2D) = "white" {}</div>
<div>        _Glossiness ("Smoothness", Range(0,1)) = 0.5</div>
<div>        _Metallic ("Metallic", Range(0,1)) = 0.0</div>
<div>    }</div>
<div>    SubShader</div>
<div>    {</div>
<div>        Tags { "RenderType"="Opaque" }</div>
<div>        LOD 200</div>
<div>        CGPROGRAM</div>
<div>        // Physically based Standard lighting model, and enable shadows on all light types</div>
<div>        #pragma surface surf Standard fullforwardshadows</div>
<div>        // Use shader model 3.0 target, to get nicer looking lighting</div>
<div>        #pragma target 3.0</div>
<div>        sampler2D _MainTex;</div>
<div>        struct Input</div>
<div>        {</div>
<div>            float2 uv_MainTex;</div>
<div>        };</div>
<div>        half _Glossiness;</div>
<div>        half _Metallic;</div>
<div>        fixed4 _Color;</div>
<div>        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.</div>
<div>        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.</div>
<div>        // #pragma instancing_options assumeuniformscaling</div>
<div>        UNITY_INSTANCING_BUFFER_START(Props)</div>
<div>            // put more per-instance properties here</div>
<div>        UNITY_INSTANCING_BUFFER_END(Props)</div>
<div>        float2 brickTile(float2 _st, float _zoom){</div>
<div>    _st *= _zoom;</div>
<div></div>
<div></div>
<div>    return frac(_st);</div>
<div>}</div>
<div>float circle(in float2 _st, in float _radius){</div>
<div>    float2 dist = _st-float2(0.5,0.5);</div>
<div>    return 1.-smoothstep(_radius-(_radius*0.1),</div>
<div>                         _radius+(_radius*0.1),</div>
<div>                         dot(dist,dist));</div>
<div>}</div>
<div>float2 rotate2D (float2 _st, float _angle) {</div>
<div>    _st -= 0.5;</div>
<div>    _st =  float2x2(cos(_angle),-sin(_angle),</div>
<div>                sin(_angle),cos(_angle)) * _st;</div>
<div>    _st += 0.5;</div>
<div>    return _st;</div>
<div>}</div>
<div>float2 tile (float2 _st, float _zoom) {</div>
<div>    _st.x += step(1., fmod(_st.y,2.0)) * 2.;</div>
<div>    _st *= _zoom;</div>
<div></div>
<div>    return frac(_st);</div>
<div>}</div>
<div>float2 rotateTilePattern(float2 _st){</div>
<div>    float PI = 6.28318530718/2;</div>
<div>    //  Scale the coordinate system by 2x2</div>
<div>    _st *=2.0;</div>
<div>    //  Give each cell an index number</div>
<div>    //  according to its position</div>
<div>    float index = 0.0;</div>
<div>    index += step(1., fmod(_st.x,2.0));</div>
<div>    index += step(1., fmod(_st.y,2.0))*2.0;</div>
<div>    //      |</div>
<div>    //  2   |   3</div>
<div>    //      |</div>
<div>    //--------------</div>
<div>    //      |</div>
<div>    //  0   |   1</div>
<div>    //      |</div>
<div>    // Make each cell between 0.0 - 1.0</div>
<div>    _st = frac(_st);</div>
<div>    // Rotate each cell according to the index</div>
<div>    if(index == 1.0){</div>
<div>        //  Rotate cell 1 by 90 degrees</div>
<div>        _st = rotate2D(_st,PI*0.25);</div>
<div>    } else if(index == 2.0){</div>
<div>        //  Rotate cell 2 by -90 degrees</div>
<div>        _st = rotate2D(_st,PI*-1.);</div>
<div>    } else if(index == 3.0){</div>
<div>        //  Rotate cell 3 by 180 degrees</div>
<div>        _st = rotate2D(_st,PI*+0.75);</div>
<div>    }</div>
<div></div>
<div>    return _st*2.;</div>
<div>}</div>
<div>        void surf (Input IN, inout SurfaceOutputStandard o)</div>
<div>        {</div>
<div></div>
<div>    float3 color = float3(0.0,0.0,0.0);</div>
<div>    float PI = 6.28318530718/2;</div>
<div>    float TWO_PI= 6.28318530718;</div>
<div>    // Use polar coordinates instead of cartesian</div>
<div>    float2 _st = float2(0.5, 0.5);</div>
<div>    float2 toCenter = IN.uv_MainTex - _st;</div>
<div>    float angle = atan2(toCenter.x,toCenter.y);</div>
<div>    float radius = length(toCenter)*2.0;</div>
<div></div>
<div></div>
<div>    _st = tile(float2(-_st.y+(frac(_Time.y)),-_st.x),3.0);</div>
<div></div>
<div>    _st = rotateTilePattern(_st);</div>
<div>    float clr= circle(_st-_st.x,(0.5-_st.y));</div>
<div>    color = float3(clr,clr,clr);</div>
<div></div>
<div>    float3 blue=float3(0.003,0.575,1.000);</div>
<div>    color=lerp(color,blue,.9);</div>
<div>            o.Albedo = 1.0;</div>
<div>            // Metallic and smoothness come from slider variables</div>
<div>            o.Metallic = _Metallic;</div>
<div>            o.Smoothness = _Glossiness;</div>
<div>            o.Alpha = 1.0;</div>
<div>        }</div>
<div>        ENDCG</div>
<div>    }</div>
<div>    FallBack "Diffuse"</div>
<div>}</div>
</div>

I also looked at using Unity’s animator to switch between shaders (image 2 in google drive folder)

 

Leave a Reply