Skip to content

LinDadaism/ProceduralGraphics-Stylization

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

3D Stylization Shaders - Waterpaint

Watercolor_Turntable.mp4

Project Overview:

In this project, I used some watercolor/ water paint 2D concept art pieces as inspiration to create a 3D Stylized scene in Unity. This gave me the opportunity to explore stylized graphics techniques alongside non-physically-based real-time rendering workflows using the Universal Render Pipeline (URP).

2D Concept Illustration 3D Stylized Scene in Unity

Inspirations/ Concept Art

Below are some linked references of watercolor paintings I found aesthetic and peaceful. More importantly, they have simple scene assembly and clear outlines -- features that ease you in as a start to learn Unity ShaderGraph.

https://www.etsy.com/listing/1459961161/kintsugi-vase-and-poppies-square-art https://pin.it/4Qje7a9 https://www.watercoloraffair.com/watercolor-coffee-painting-a-complete-step-by-step-tutorial/

Watercolor

Interesting Surface Shader

The main catch of my concept art pieces is watercolor so I put a lot of effort into creating a surface shader that heavily utilizes noise-based texture sampling to mimick water paint. Then I move on to add dynamic shadow, also in watercolor style, that is eventually blended with the object's surface color with some fresnel effect. This article on watercolour shader experiments gave me a good guidance on this step.

Watercolor Shader Watercolor Shader with Shadow

Note: I decreased the noise value of the floor material for the second screenshot to better showcase the shadow.

Although there's no distinct/ complex lighting in my concept art, I experimented with multiple lights in the scene using a basic 3-tone shader. Unfortunately the result was not satisfying so I decided to not incorporate multi-lights support in my stylized render.

Outlines

Post-process Shader

The subtle outlines on the 3D objects are achieved by post-processing effects. I mainly relied on Render Features in Unity URP to add customizable full screen render passes to any part of the render pipeline.

I followed these tutorials to learn the use cases of Render Features and the various techniques to outlining 3D objects:

To trace the objects' outlines, we need to get access to the Depth and Normal Buffers of our scene. URP actually already provides us with the option to have a depth buffer, and so obtaining a depth buffer is a very simple/trivial process. However, this is not the case for a Normal Buffer, and thus, we need a render feature to render out the scene's normals into a render texture. I watched this video to learn how to create the depth and normal buffers, and then access/read both once we've created them.

Normal Map Depth Map

Back to outlining 3D objects, the logic behind my post-process shaders is quite straight-forward: detect areas of large depth and normal difference across the screen. I explored different kinds of edge detection methods in HLSL, including Sobel operator and Robert's Cross filters. The following table shows the different approaches after fine-tuning.

No Outlines Sobel
Robert's Cross Sobel + Robert's Cross

I tweaked some outline parameters such as outline thickness, normal and depth sensitivities (i.e. discontinuity threshold) to replicate the subtle wobbly outlines in the concept art. Using only Robert's Cross gives me the most desirable result. In addition, the outlines are dynamically traced based on the view change in terms of camera angle and position.

Vertex Animation

Finally I assembled my scene "A Serene Afternoon" with flower vases and a cup of coffee. To make the scene more lively and organic, I wrote another two special surface shaders that animate a falling dead leaf and the coffee steam by offsetting the vertex positions. Both shaders are based off of this tutorial.

Falling Leaf

I used a ease-out quadratic toolbox function applied to the time variable in the linear interpolation node to create an effect that the leaf first drops quickly and then slows down when landing once it is close to the table.

Coffee Steam

A side note:

It striked me how a simple translation animation can be achieved in so many ways: vertex shader, Unity's animation system, and C# scripting. While I was scraping my head off how to make the leaf fall in ShaderGraph, there was this moment that I realized I was taking a longer route because creating a 2-key key-framing animation would be the fastest/ easiest/ most intuitive approach, attaching a C# script to the leaf object the second. Why in the world I chose vertex shader?? Nevertheless, I thought this is an interesting experiment of modifying vertex attributes in ShaderGraph.

Full Screen Post Process Effect

The last step is to add a watercolor background. I tried to insert a render pass of just a texture sample using my hand-painted watercolor paper (scanned to produce a digital copy) but it was always blocking the opaque objects. As I was running out of time, I chose a work-around, i.e. creating a 6-sided skybox with the same texture flipped in the positive and negative direction of each axis. The output isn't seamless -- as the turn table rotates you can recognize the sharp edges of a cube. Future improvement is to fix the background full screen render pass, or to generate 6 skybox textures to match each side of the 3 axes.

Resources:

In addition to the references mentioned in the descriptions,

  1. Logan Cho's Tutorials on Unity ShaderGraph:
  2. Models:

About

3D waterpaint stylization shaders in Unity

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 87.9%
  • HLSL 9.2%
  • ShaderLab 2.9%