[Project] Semblance (previously, Squeeze Me)

Comments

  • Thanks for unpacking your thoughts more! :)

    Totally agree about your analysis of how purple is usually read!

    "The point I'm getting at is purple terrain doesn't contrast the green in terms of the green being corruption and the purple being healthy."


    I think you're spot on about purple vs. green not contrasting each other strongly enough in terms of corruption vs. healthy. I think we rely quite strongly on silhouette and shape to achieve this contrast, and we get away with it barely, but not as easily as I would like.

    It's obviously idea if both your color and your silhouette cohere in communicating the object's function and tone. Think we miss a beat a bit there. We have had some feedback from another reliable source saying the green crystals read too much as being part of the world, and not sticking out and being dangerous enough. Which aligns with your points. We're probably going to stick with the current color palette, but emphasize the corruption of the green crystal stuff in other ways (and admittedly, more obtuse). This is a conscious choice based on timelines, unfortunately.

    Great thoughts on spookiness! I think almost all players of the game read it as more cute than spooky, although it could be cute in the spooky fashion of Tim Burton, you suggest. I think players searching for further spooky elements will be disappointed! I think we're going to be focusing a lot more on adding cuteness/playfulness to the game, which considering the general exclamations of cuteness when viewing the game, is a good choice.

    Your points on spooky vs. cute are super valuable though, I think we are currently trying to hit a sort of minimalist spooky cuteness in the same fashion as a Hotel Transylvania and definitely more of a Cloudy with a Chance of Meatballs.

    image
    image

    These aren't actual references we've used up until this point, I'm just retroactively trying to think of the balance we're trying to hit. I think on the spectrum of spooky vs. cute, with Tim Burton being spooky leaning, we're trying to be a bit more cute leaning. I can see now your point, at least currently from the screenshots, how we're not hitting that cute leaning yet! Definitely more spooky leaning. This is something I am hoping to jam pack with going forward.

    This is definitely a great insight that I, at least, wasn't hyper aware of, and is something to be aware of going forward. Thanks so much for taking the time to point it out :)
    Cheespider-Sam-Sparks-Cloudy-Chance-of-Meatballs-2.jpg
    570 x 300 - 87K
    hoteltrans20002.jpg
    1280 x 692 - 96K
    Thanked by 1EvanGreenwood
  • Let’s chat shaders

    Here’s the process I went through to create a shader to cure / de infect the environment. To simulate the infection pealing off trees, plants, etc.

    image

    Why make a shader? Frame by frame animation would be tedious and sprite specific.

    The basic theory was to have a the base sprite and an infection texture that’s blended together based on a noise texture mask and a threshold. Here’s where I started. Replace the main texture pixel with secondary texture based on the mask and threshold

    // just replace color based on mask
    fixed4 frag (v2f i) : SV_Target
    {
    	fixed4 main = tex2D(_MainTex, i.texcoord); // background texture
    	fixed4 mask = tex2D(_TransitionMask, i.texcoord); // masking texture
    	fixed4 sec = tex2D(_SecondaryTex, i.texcoord); // foreground texture
    
    	if((mask.r + mask.g + mask.b) * 0.33333 < _Threshold)
    	{
        		sec.rgb *= sec.a;
        		return sec;
    	}
        else
        {
        	main *= i.color;
        	main.rgb *= main.a;
        	return main;
        }
    }


    How the masking with the noise texture works.

    - Add the rgb values which would give us a number between 0 and 3
    - Multiply by 0.33333 giving a number between 0 - 1, to get the whiteness of the pixel
    - 0 - black and 1 white
    - the threshold is between 0 - 1
    - thus if the pixel in the mask texture less than the threshold. the background (main) gets replaced with the foreground (infection) texture

    image

    but if the foreground texture has holes, you get the holes as well.

    image

    Now, I’d like to show the back texture through those holes. So we need to evaluate the alpha channel against some cutoff value and voila we skip the pixels that have an alpha less than the cutoff value.

    // check if the sec.a is greater than a cutoff
    
    if((mask.r + mask.g + mask.b) * 0.33333 < _Threshold && sec.a > 0.01)
    {
        	sec.rgb *= sec.a;
        	return sec;
    }


    image

    hold up, let’s take a closer look

    image

    because of the antialiasing on the secondary texturing. There’s weird artefacts around the edges that become transparent. So, I’ll add a slider for the cutoff value to find just the right

    image

    // check if the sec.a is greater than a cutoff 
    
    if((mask.r + mask.g + mask.b) * 0.33333 < _Threshold && sec.a > _Alphacutoff)
    {
        	sec.rgb *= sec.a;
        	return sec;
    }


    That kinda works and the the minute changes in alpha are taken care of but now you’ve got really hard edges. I decided to blend the two textures instead of picking one or the other. Hence, I don’t need some cutoff value.

    // blend the two textures instead of replace one with the other
    fixed4 frag (v2f i) : SV_Target
    {
    	fixed4 main = tex2D(_MainTex, i.texcoord); // background texture
    	fixed4 mask = tex2D(_TransitionMask, i.texcoord); // masking texture
    	fixed4 sec = tex2D(_SecondaryTex, i.texcoord); // foreground texture
    
    	main.rgb *= main.a;
    	main *= i.color;
    
    	if((mask.r + mask.g + mask.b) * 0.33333 < _Threshold)
    	{
        	// blend main and sec
    		fixed4 col = fixed4(0, 0, 0, 0);
    		col.a = 1 - (1 - sec.a) * (1 - main.a);
    
    		if (col.a < 0.00001)
    			return col;
    
    		col.r = sec.r * sec.a / col.a + main.r * main.a * (1 - sec.a) / col.a;
    		col.g = sec.g * sec.a / col.a + main.g * main.a * (1 - sec.a) / col.a;
    		col.b = sec.b * sec.a / col.a + main.b * main.a * (1 - sec.a) / col.a;
    		return col;
    	}
        else
        {
        	return main;
        }
    }


    image

    Good to go, right. Nope. I thought so too. Then I threw in some of the actual sprites that we’re using for the game and then this happened. :O

    image

    Turns out there’s more to the sprite that meets the eye. It’s about how the SpriteRenderer in Unity creates the mesh.

    image

    To stop secondary texture going over the obviously transparent part of the sprite. I used the same technique as before and just had a alpha check on the main texture before I do the blending of the two textures. Voila!

    // added alpha cutoff to remove "transparent" shit
    fixed4 frag (v2f i) : SV_Target
    {
    	fixed4 main = tex2D(_MainTex, i.texcoord); // background texture
    	fixed4 mask = tex2D(_TransitionMask, i.texcoord); // masking texture
    	fixed4 sec = tex2D(_SecondaryTex, i.texcoord); // foreground texture
    
    	main.rgb *= main.a;
    	main *= i.color;
    
    	if((mask.r + mask.g + mask.b) * 0.33333 < _Threshold && main.a > _AlphaCutoff)
    	{
        	// blend main and sec
    		fixed4 col = fixed4(0, 0, 0, 0);
    		col.a = 1 - (1 - sec.a) * (1 - main.a);
    
    		if (col.a < 0.00001)
    			return col;
    
    		col.r = sec.r * sec.a / col.a + main.r * main.a * (1 - sec.a) / col.a;
    		col.g = sec.g * sec.a / col.a + main.g * main.a * (1 - sec.a) / col.a;
    		col.b = sec.b * sec.a / col.a + main.b * main.a * (1 - sec.a) / col.a;
    		return col;
    	}
        else
        {
        	return main;
        }
    }


    The shader can be used with different textures and masks to give a different feeling. Try it for yourself, here's the code.

    Throw me any questions or suggestions. We all learning here. :)
    Thanked by 2shanemarks roguecode
Sign In or Register to comment.