Floating World Shader Part 5 – Ocean Material

This is the last part of the breakdown of my shaders based on work by Owakita. This will probably be the biggest one of all as we tackle the gersner wave ocean material.

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 2 – Sky Material
Part 3 – Post Processing Material
Part 4 – Gradient Fresnel Material

Gersner Wave Function

The gersner wave function was made based on this video from the Dreams team. Its a fantastic watch, so I’m just going to pop this here in lieu of going through the graph.

The main change that I had to do to get this into unreal was to replace the loop with repeating the wave function over and over, which causes node spaghetti and makes the system far less flexible.

0e39026e32a4895225f348cebd4f1564

blog15

The bitshifting for the psudo random number had to be done in a custom hlsl node, as there is no other way to convert to int and to bitshift.

blog16

I also did the final calculation in a custom node, as it was simpler to read than trying to drag the pins from each variable in. Honestly, its still a mess. I was really missing just writing hlsl at this stage.

blog17

Normals and Light Stylisation

I had some issues with normals appearing incorrect, which was eventually was down to some dodgy order of operations and some calculations being done in meters when they should have been in centimeters. Caught out by a couple things when trying to move between code and nodes.

ezgif-2-858790595a9f

I rounded the normal in order to give a hard edged, toon look to the shader.

9b478778c7b354907dabc39204061d26

Texturing

blog19

To create the smooth line pattern seen in the concept, I created a tiling texture in photoshop with outline on R and color variation on G.

I used the same smoothstep trick as with the gradient to have a color assigned to black, white and midgrey.

blog22

12ca3f35f65b888b285a05037ed23262

To add the outline, I took the black outline on the R channel of the texture and added the outline color to it. I then multiplied this with the lerped color.

blog24

Foam

In order to make the foam appear on top of the waves, I got the dot product of the surface normal and a vector parameter. This vector was used to control the angle of the foam. This was them multiplied with a noise texture to provide the breakup effect and rounded to keep the toon feel.

blog27

blog26

The outline on the foam was created by taking the above and creating an inverted version of it, with a slightly smaller wave. This multiplied by the original created an outline. This then hooked into the texture outline to receive the same color.

blog29

466716526a04d45f0c8e1df1d9eed190

blog28

All together, we get a nice breakup wave effect.

ezgif-2-282099dc540d

Final Shader

Combine all of this and you get the ocean shader from the original gif!

okiawaGif

Floating World Shader Part 4 – Gradient Fresnel Material

Here’s part four of the breakdown of my shaders based on work by Owakita. This is going to cover the gradient material found on the meshes in the scene.

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 2 – Sky Material
Part 3 – Post Processing Material
Part 5 – Ocean Material

Object Space Gradient

I wanted the gradient to run vertically across the object, unaffected by the position of the object in world. I didn’t want to adjust my UV map in order to accommodate this, so decided to do my gradient in object space Z. (Unreal is Z up)

blog12

I used the ObjectLocalBounds node to get the top and bottom of the object bounds in Z (though I did include a mask parameter so the gradient could be used in other directions), then used a smoothstep to produce a 0 – 1 value between the two.

Three Part Gradient

The reference image actually has three colors in its gradient, and I wanted to get as close as possible. To do this, I had to lerp twice, breaking the initial 0 – 1 coming from my object bounds into two parts.

To do this, I smoothstepped between 0 and 0.5, to map the bottom half of the value range to 0 – 1, then smoothstepped between 0.5 and 1 to do the same to the top half. I then used the first value to lerp between two colors, and the second to lerp between the previous lerp and the third color.

blog11

Fresnel

The fresnel effect is very simple, literally just using the fresnel node to lerp between an edge color and the main gradient. This was used to provide the edge highlighting seen in the reference.

1

For context, the fresnel node does a dot product between the input normal (in this case either a normal map converted to world space or the the world space normal of the pixel) and the camera position to determine whether the surface is facing the camera. Facing returns 0, facing away returns 1, so we can use this to assign a color to faces at grazing angles.

blog13

Rock Variation

The rocks also use this shader, but forego the gradient and have a normal map input to the fresnel, as well as a very high fresnel amount, giving a shadowed, two tone look.

blog14

 

 

Floating World Shader Part 3 – Post Processing

Today I’m continuing the breakdown of my shaders based on work by Owakita. Here’s part three!

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 2 – Sky Material
Part 4 – Gradient Fresnel Material
Part 5 – Ocean Material

Post Process Material

The aim of the post process was to create an outline around the objects, provide a grainy look and tint the screen color.

okiawaGif

Different Approaches

There were two approaches I considered for this. One was the kernel based edge detection I used on a project a couple years back, and another was the simpler sampling depth offset technique found in the UE4 stylised rendering example.

Ultimately I went for Epic’s approach, as while it may have been slightly more expensive for the amount of times it sampled depth, it was far simpler to setup and read later down the line. For this project I was really focused on the aesthetic over performance or tech, but I do still like to consider these things.

Determining Line Width

I started off by creating a single line on one side, by by getting the screen uv and offsetting it. I then multiplied this by screen texel size so the offset appears to be the same width, regardless of screen resolution.

width
Node graph for offset UV. 

Subtracting one channel of this value from the scene depth will give a single line edge, but we want an edge on all sides!

blog5
Scene with an outline on a single side.

Creating An Outline On All Sides

I then split this offset into its U and V parts and multiply each by minus one, leaving us with four sets of offset UVs, as seen in the image below. These are then used to sample scene depth, which creates four different samples of the depth, all with a slight offset in one direction.

explaination
Diagram showing how depth sampled with offset UV’s combine to create an outline.

Subtracting these from the initial scene depth then adding them together leaves us with a nice combined outline!

Sample Depths
Node graph for combing offset UV samples.
blog6
The scene with an exaggerated outline.

Depth Based Line and Wireframe Fix

With this approach, we start to get the internal wireframe being outlined at distance. As a fix, we take the scene depth, divide it, then take one minus this (as UE4’s depth is flipped) then clamp it. This is the multiplied with the outline. This lowers the outline amount for these faces.

blog9

Capture

I later added something very similar to the initial outline calculation, where this was multiplied with the result of the texel size multiplier. What this did was take the depth and as the object gets further away, reduces the size of the line. This allowed me to not lose detail at distance and stopped blobby looking outlines.

blog8

Putting It All Together

One this outline is created, it is used as the alpha to lerp between the line color and the scene color. Here I’ve multiplied the scene color with a texture and color to add a bit of grain and color tinting.

color
Node graph for the combined result.

Final Result

result
Sphere showing the final result of the material.
options
Exposed parameters for the material.
blog7
Final result in the scene. 

Floating World Shader Part 2 – Sky Material

As talked about in my last post, I’ve been working on some shaders based on work by Owakita. Here’s part two of the breakdown!

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 3 – Post Processing Material
Part 4 – Gradient Fresnel Material
Part 5 – Ocean Material

Sky Material

9a1e8e847636d86ea7737b20299d1077

The sky material for this project was pretty simple, as I made a copy of the base sky material found in the construction script of BP_Sky_Sphere, and replaced that reference with the copy.

blog1
BP_Sky_Sphere Construction Script

Inside of that copy, I replaced the scrolling clouds texture with my moon, and the stars with my stars. I also added an additional cloud speed parameter so that I could control the speed of the stars and moon separately, for a nice parallax effect.

blog2
Texture samples that need changed in M_Sky.

The most challenging part here was creating the moon texture. As it has such a large area to cover and is projected over a sphere, I had to get the moon shape in the correct area of the texture and bend it appropriately so that it looked correct on the sky sphere mesh. I got there after a lot of trial, error and free transform!

blog3
The star and moon textures I created. 

For the colors, I left the material as is but overrode the light based colouring in the details menu. I then tweaked zenith and horizon color until I got close to the reference image.

blog4
Tickbox for turning off sun position based color and color controls.

That’s all there was to it for the skybox! Next post will look at the post processing effect.

Floating World Shader Part 1 – Initial Plans

Over the bank holiday I worked on a number of shaders in UE4 based on work by Owakita. I love her dreamy, pastel aesthetic and wanted to try it for myself.

I’ve written a number of posts breaking this down, and these can be found here:

Part 2 – Sky Material
Part 3 – Post Processing Material
Part 4 – Gradient Fresnel Material
Part 5 – Ocean Material

okiawaGif
The finished product!
comparison
Comparison between Owakita’s original work and my recreation of it.

Reference Breakdown

Initially looking at the work, I broke my project down into a post process, gradient and gersner ocean material. In future blog posts I’ll be covering how I did each of these stages!

Untitled-1

At this point I listed some features I thought each shader should have, but this did change a fair bit over the course of development.

Nanoreno Week 4 – Finished!

I’ve officially completed NaNoRenO2020! Its a really good feeling since I’m pretty terrible at finishing game projects normally!

You can play the game at https://amesyflo.itch.io/dream-dilemma.

Proofreading

Most of this last week was dedicated to proofreading. This should have been the easiest part of the project really, but having my full dialog script inside of my game code made it quite tough. Spellcheck picked up on a lot of things it shouldn’t and it wasn’t super easy to write in flow when there’s game code dotted about.

It made me think about writing a tool to parse dialog from a text document/spreadsheet  into .rpy files. At the very least I think next project I want to think about a file structure that allows me to keep game code and dialog separate.

Overall Experience

Overall this game jam was a great experience – I finally finished a game! Its led me to have a bunch more VN ideas, so expect to see more of that in the future. First though…I have a shader I want to write…