***More control***: you can precisely tweak all values to get the exact look wanted
***Longer material setup***: more control means more parameters to adjust!
***Easier material setup*** similar to Unity's Standard shader, with additional stylization options
***Less stylization options***: features like sketch or textured threshold are not supported in the PBS shaders
***More Stylization***: e.g. comic-book like visuals using features like halftone or sketch effects
***Less consistency***: you may have to readjust material parameters so that they fit in each environment (although that can be mitigated)
***Works in all lighting settings***: no need to do further tweaks to materials once they're properly configured
***Limited value ranges***: you can't go too much outside the "physical" values and get extreme results (that's actually the whole point of PBS!)
***Better Performance***: that depends on the number of features enabled, but generally speaking the computation is less intense than a PBS shader
***Automatic mobile version***: the best shader optimizations are loaded internally depending on the target platform
***Higher Cost***: the Standard shader generally requires more GPU power than the Hybrid one
***Shader Generator***: more features to choose from, and get the ultimate stripped-down shader with just the code you need
***Stylization in 1 click***: the shader will automatically inherit parameters already defined for a material using Unity's Standard shader
The TL;DR version:
- **Hybrid Shader**:
+ more control
+ more styles possible
- more parameters tweaking
- **Standard PBS**:
+ less parameters tweaking
- less control
- a unique visual style that will always be PBS-ish
The *Hybrid Shader* is the latest default shader included in TCP2, which works with both the *Built-in* and *Universal Render Pipelines*.
That means that the *same shader file* works with both pipeline, and thus your materials will automatically work if you change the render pipeline of your projects, _without you having to change their settings or shader_.
Internally, the file contains two SubShaders: one for each pipeline. If one fails to compile, Unity will simply use the other one.
You might still see differences when using a material with either pipelines, because they have some implementation differences in their architecture, for example:
- Point lights fall-off is calculated differently
- Shadow maps are calculated differently
*Note for users using macOS*
Some users have reported that the Hybrid Shader will *compile indefinitely during a build when using macOS*.
This appear to be a bug in Unity caused by the fact that the shader contains multiple SubShaders.
If you are affected by this bug, you can manually disable the unused ones depending on the render pipeline you are using, and the build should then work normally again.
- Open the files `TCP2 Hybrid Shader.shader` and `TCP2 Hybrid Shader Outline.shader`
- Look for the lines starting with `SubShader`
- Comment out the SubShader block for the pipeline that you are not using (a comment above the line indicates for which pipeline the SubShader is)
- To comment, add a line with `/*` above the `SubShader` keyword, and close the comment with `*/` after the last `}` that closes the `SubShader` block
Feel free to [reach out](#contact) if you need further help in that process.
*PS:* [Shader Stripping](#hybridshader/specificnotes/troubleshooting/3.shaderstrippingwhenbuilding) has been added as of *TCP2 v2.7.3* to try to mitigate this issue. Please [let me know](#contact) if you still encounter this issue though.
## Options Reference
Here is a reference of the available options with screenshots to quickly understand how they work.
### Mobile Mode
The *mobile mode* will change the shader to make it faster for mobile devices, notably:
- it will skip any branching-based code (e.g. `if` conditions in the shader code)
- it will compute certain things in the vertex shader rather than in the pixel shader, at the expense of precision (e.g. the rim lighting calculation)
As such, some of the options in the material inspector will be disabled when mobile mode is enabled.
Note that high-end mobile devices should work fine without the mobile mode enabled.
#### Rendering Mode
Defines whether the material should be opaque or semi-transparent.
If not opaque, the *alpha* value will control opacity, i.e. the *main color alpha* multiplied with the *Albedo alpha*, if any.
Opaque | Alpha has no effect on opacity
Fade | Alpha will control opacity of the full material
Transparent | Alpha will control opacity of the diffuse parts, specular/reflections will still be fully visible to emulate physical semi-transparent materials (e.g. glass)
Example with specular, rim lighting, and alpha set at 0.3: _(note: the difference is clearer in dark mode, see the button at the top-right hander corner)_
Changing the rendering mode will:
- Change the shader's `Blend` factors
- Toggle [[depth write]] accordingly, although that can be changed afterwards
#### Render Face
Defines which faces to render: front, back, both (`Cull Back/Front/Off` in ShaderLab).
This corresponds to the hardware face culling parameter.
Front | Render the front faces, cull the back faces.
Back | Render the back faces, cull the front faces. Rarely used.
Both | Render both front and back faces. Generally used with transparency or [[alpha clipping]], so that the "interior" of a mesh can be seen; or with planar meshes (e.g. a flag).
The **Hybrid Shader** automatically flips the normals for correct lighting calculation on the back faces when they are visible!
#### Depth Write
Toggles depth buffer writing (`ZWrite On/Off` in ShaderLab).
Generally disabled when using transparency to avoid sorting issues for semi-transparent pixels.
It does work with [[alpha clipping]] though, hence why alpha clipping is generally used to draw vegetation as the grass, leaves, etc. need proper sorting.
Depth Writing can also be important for some post-processing effects (e.g. Depth of Field).
#### Alpha Clipping
Toggles binary transparency at the pixel level: a pixel can either be opaque or fully invisible, based on the alpha value and a threshold.
Also knows as *alpha testing*, or *cutout* shaders in Unity.
The *main color*, that will be multiplied with the Albedo texture, if any.
The *main texture*. Although it's named "albedo", the Hybrid Shader is not a physically-based one, thus it doesn't expect textures that are only pure albedo in the physical sense of the term.
#### Highlight Color
This is an *additional color* for the *lit parts* of the material only, based on the [[ramp shading]] settings.
#### Shadow Color
This is an *additional color* for the *unlit parts* of the material only (including cast shadows), based on the [[ramp shading]] settings.
This is an easy way to change the tint of the shadowed parts, as commonly seen in 2D animation for example.
#### Shadow Albedo Texture
This is an *optional texture* that will be used in place of the main albedo one for the *unlit parts* of the material.
The [[shadow color]] is still applied on top of it.
There are multiple workflows possible with the Shadow Albedo Texture, notably:
- Use a **shadow albedo texture** that only changes the **hues** of the main texture, or hides some details, and use the **shadow color** to handle the luminosity
- Use a white **shadow color**, and thus the **shadow albedo texture** will contain the **final color** for shadowed parts of the material
![Shadow Albedo Texture](images/hybrid_colors_shadow_albedo.png)
### Ramp Shading
The *Ramp Shading* defines how the separation between lit and unlit areas will be handled visually.
The *Hybrid Shader* provides multiple options for the *Ramp Type*, to achieve different kind of styles:
#### Ramp Type
Default | Two parameters will define the ramp shading: - *Threshold* will move the line between lit and unlit parts. - *Smoothing* will vary blurring on that line.
Crisp | Same as Default, without the "Smoothing" parameter. - This can be thought as the *Default* type, with a smoothing of 0, but with additional calculation to make sure the line is always anti-aliased.
Bands | Same as Default, but the gradient between the min and max value is quantized, visually resulting in clearly defined bands. The smoothing between each band can be adjusted.
Bands Crisp | Same as Bands, without the "Bands Smoothing" parameter, but having anti-aliased lines between each band instead.
Texture | A 1D ramp texture will define the ramp shading. - This settings gives the most flexibility. If using a ramp generated with the [[Ramp Generator]], you can even tweak the gradient in real time. - You can use RGB colors in the texture. - *Offset* and *Scale* values can be thought as *Threshold* and *Smoothing* values applied to the texture's UVs.
Type | Defines the specular lighting model to use.
└─ GGX | *GGX* is the main technique used in PBR rendering for specular. It is energy conserving, roughly meaning that as the roughness increases, the specular intensity decreases.
└─ Stylized | *Stylized* allows you to directly control the size and smoothing of the specular area.
└─ Crisp | *Crisp* is the same as stylized, with a smoothing of 0 but with anti-aliasing applied.
Color | A color multiplied with the specular area, to tint it or change its intensity.
Specular Map | Enables the use of a specular map: with *GGX*, this will control the *Roughness*, whereas for *Stylized/Crisp* this will control the *Size*.
![Specular GGX ](images/hybrid_specular_ggx.png)
![Specular GGX with map](images/hybrid_specular_ggx_map.png)
![Specular Stylized ](images/hybrid_specular_stylized.png)
![Specular Stylized with map](images/hybrid_specular_stylized_map.png)
![Specular Crisp ](images/hybrid_specular_crisp.png)
![Specular Crisp with map](images/hybrid_specular_crisp_map.png)
### Normal Mapping
Toggles tangent-space *normal mapping*.
Normal Map | The normal map texture in tangent space (the classic blue-ish looking normal maps).
Scale | Controls the strength of the normal map, also allowing you to reverse it by using negative values.
![Checker normal map](images/hybrid_normal.png)
![Scale at -1 The normals appear reversed](images/hybrid_normal_sm1.png)
![Scale at 0.25 ](images/hybrid_normal_sm025.png)
![Normal map with specular and rim lighting](images/hybrid_normal_spec.png)
Toggles *emission*, which essentially represents colors not affected by lighting on top of everything else.
Texture Channel | Enables the emission texture and selects which channel to use for it.
Color | The emission color, multiplied by the emission texture if any.
![Yellow Emission Color](images/hybrid_emission.png)
![Emission with texture mask](images/hybrid_emission_tex.png)
![Emission from RGB texture](images/hybrid_emission_tex_rgb.png)
### Rim Lighting
Adds a fake *rim light* around the model, based on the dot vector between its normals and the view direction.
This is an easy way to emphasize the silhouette of objects.
Color | The color of the rim lighting effect, which also controls its strength since the effect is additive (i.e. black color = invisible rim lighting).
Min | The minimum value of the view-based threshold.
Max | The maximum value of the view-based threshold.
Light-based Mask | Will add one rim effect per light affecting the material, and masked based on the [[ramp shading]] options.
![Default Rim Lighting Min 0.5 / Max 1.0](images/hybrid_rim.png)
![Light-based Mask Min 0.5 / Max 1.0](images/hybrid_rim_lightmask.png)
![Light-based Mask with an orange point light Min 0.5 / Max 1.0](images/hybrid_rim_lightmask_pt.png)
![Close min/max values will result in a crisp looking rim Min 0.7 / Max 0.75](images/hybrid_rim_crisp.png)
![Inverting the values will make an inner glow effect Min 0.65 / Max 0.0](images/hybrid_rim_inverted.png)
Toggles *matcap* shading on top of the regular shading.
"MatCap" is a technique that uses a single small texture to define a view-dependent shading model: for each pixel on the material, its view-space normal will define where to sample the provided matcap texture.
It is a very cheap and effective technique to add some reflectivity to a material.
The word is an abbreviation for *"Material Capture"*.
MatCap Blending | How the MatCap colors will be blended with the rest: *additive* will add the colors, *replace* will replace the albedo color entirely.
Texture | The MatCap texture. Some are included in the Textures/MatCap folder.
Color | An HDR color multiplied with the MatCap colors, that can also increase its brightness if set to values over 1.0.
Enable Mask | An HDR color multiplied with the MatCap colors, that can also increase its brightness if set to values over 1.0.
└─ Texture Channel | An HDR color multiplied with the MatCap colors, that can also increase its brightness if set to values over 1.0.
![MatCap Additive with Mask](images/hybrid_matcap_add_mask.png)
![MatCap Replace with Mask](images/hybrid_matcap_replace_mask.png)
![MatCap applied to another mesh](images/matcap_cat_2.png)
### Global Illumination
Provides parameters to control how *global illumination* affects the material.
There are two main sources for global illumination:
**Indirect Diffuse** | Also called *ambient* or *environment lighting*, physically corresponds to light bouncing around surfaces and thus providing indirect lighting. In Unity, this is generally provided by lightmaps for static objects, and light probes for dynamic/moving objects.
**Indirect Specular** | Corresponds to the *reflections* from the environment around an object. In Unity, this is generally provided by *reflection probes*.
#### Indirect Diffuse
Strength | How much should indirect diffuse affect the material. Set to 0 to disable indirect diffuse entirely.
Single Indirect Color | Use the view vector instead of the normals to sample the indirect diffuse/ambient color, so that it is the same for the whole material.
The *Single Indirect Color* option can help to maintain a flat appearance on objects when using *Skybox* or *Gradient* as the *Environment Lighting Source* in the [Lighting Settings](+https://docs.unity3d.com/Manual/lighting-window.html).
It has no effect when using a single color as the environment lighting source.
![Indirect diffuse Strength set to 1](images/hybrid_ramp_default.png)
![Indirect diffuse Strength set to 0](images/hybrid_gi_id_0.png)
![Indirect diffuse set to 0 with a black [[shadow color]]](images/hybrid_gi_id_0_black.png)
![Env. Lighting set to Skybox Regular](images/hybrid_gi_id_skybox.png)
![Env. Lighting set to Skybox Single Indirect Color](images/hybrid_gi_id_skybox_single.png)
#### Indirect Specular
Color | A color multiplied with the indirect specular colors, which can also be used to decrease its intensity when using values towards black.
Smoothness | Defines how smooth the surface is, and thus how clear should the reflections appear: the lower the value, the blurrier reflections will look.
Reflection Map | Toggles a smoothness map, which will multiply the smoothness value based on the selected texture and relevant color channel.
Fresnel Reflections | Toggles Fresnel reflections, meaning that the edges of the object will be more reflective than its center, based on the view. This is a natural effect in the real world, but the calculation used here is not physically accurate. It is based on the same calculations done for [[rim lighting]], and you can tweak the min/max values.
└─ Fresnel Min | The minimum value of the view-based threshold, similar to the [[rim lighting]] parameters.
└─ Fresnel Max | The maximum value of the view-based threshold, similar to the [[rim lighting]] parameters.
![Indirect Specular Smoothness set to 1 ](images/hybrid_gi_is.png)
![Indirect Specular with Reflection Map ](images/hybrid_gi_is_map.png)
![Indirect Specular with Fresnel Reflections ](images/hybrid_gi_is_fresnel.png)
![Indirect Specular with Fresnel Reflections and Reflection Map](images/hybrid_gi_is_fresnel_map.png)
The *occlusion texture* is meant to control the small shadowing caused by a model onto itself.
This can be thought as a mask for the global illumination (thus it affects indirect diffuse _and_ indirect specular).
Most DCC/3D authoring softwares provide a way to generate an occlusion map, preferably from a high-resolution 3D model.
Strength | Defines the strength of the occlusion. 0 is effectively the same as turning occlusion off.
Texture | The occlusion texture.
Texture Channel | Defines which color channel to use as the occlusion map. Also allows using the [[albedo]] alpha channel as the occlusion source.
![Occlusion Map applied to indirect diffuse](images/hybrid_gi_occlusion_id.png)
![Occlusion Map applied to indirect specular](images/hybrid_gi_occlusion_is.png)
![Occlusion Map applied to both indirect diffuse and specular](images/hybrid_gi_occlusion.png)
Toggles rendering an *outline* for the material.
The technique used is the classic *"inverted hull"* outline, which is based on rendering the object in an *additional shader pass* with front-face culling and then rendering the object regularly on top of it.
Since this is merely an illusion rather than a screen-space outline, some artifacts can show depending on the cases.
One common artifact is the outline mesh appearing broken when using *hard edge shading*. TCP2 provides the [[Smoothed Normals Utility]] to solve that particular problem.
Color | The main color of the outline, which will be multiplied with the rest.
Texture | Toggles sampling the [[albedo]] texture for the outline color: - **Vertex Shader**: will sample the texture at the vertex level, faster but loses a lot of precision (dependending on the vertex count) - **Pixel Shader**: will sample the texture for each pixel, which can show all the texture's details depending on the *Texture LOD* value.
└─ Texture LOD | Defines the mip level at which to sample the texture. Useful if you want the outline color to vaguely look like the [[albedo]] texture without showing all its details.
Width | Defines the base size of the outline.
Pixel Size | Defines how the outline size should behave in screen-space: - **Disabled**: don't apply any correction - **Constant**: the outline will always have the defined *width* in pixels on the screen - **Minimum**: the outline will have a minimum pixel size on screen. This ensures that it will always encompass the object even when viewed from far away See the video below for a visual example. - **Min Max**: the outline will have a minimum and maximum pixel size on screen
Outline Normals Source | Defines which data to use as normals when expanding the outline mesh. Should be set according to the settings used in the [[Smoothed Normals Utility]].
└─ UV Data Type | Defines how the normal data is encoded when using an UV channel as the normals source. Should be set according to the settings used in the [[Smoothed Normals Utility]].
Lighting | Enables lighting on the outline: - **Main Directional Light**: outline will be lit by the main directional light and the indirect diffuse from [[global illumination]] - **All Lights**: outline will be lit by all real-time lights and the indirect diffuse _(Universal Render Pipeline only)_ - **Indirect Only**: the outline will only receive lighting from indirect diffuse
└─ Direct Strength | Defines the intensity from direct lighting.
└─ Indirect Strength | Defines the intensity from indirect lighting (ambient/indirect diffuse from [[global illumination]]).
Because the outline is an illusion using front-face culling in another shader pass, the lighting received might not look like what you would expect from a 2D drawing.
![Simple black outline ](images/hybrid_outline.png)
![Vertex Texture enabled ](images/hybrid_outline_tex_vertex.png)
![Pixel Texture enabled ](images/hybrid_outline_tex_pixel.png)
![Lighting enabled with Main Directional Light](images/hybrid_outline_lighting.png)
#### Pixel Size examples:
![Comparison of the different pixel size values Outline width is set at **4** Minimum width is set at **1** for the right Sphere](images/outline_pixel_size.mp4)
![Same comparison without the video artifacts](images/outline_pixel_size.png)
Receive Shadows | Defines whether this material will receive shadows from shadow maps or not. Note that this option also exists on the *Renderer component*.
Render Queue | Defines when to render this material. See [Unity's documentation](+https://docs.unity3d.com/Manual/SL-SubShaderTags.html) for more information about the render queue.
Enable GPU Instancing | As its name implies, enables [GPU instancing](+https://docs.unity3d.com/Manual/GPUInstancing.html) support.
## Specific notes / Troubleshooting
### 1. Main texture and color variables
The main texture and color variables are named *_BaseMap* and *_BaseColor* as in URP, instead of being named *_MainTex* and *_Color* as it historically was the case for Unity shaders.
This means that C# APIs like [material.mainTexture](https://docs.unity3d.com/2019.2/Documentation/ScriptReference/Material-mainTexture.html) will not work properly when using *Unity 2019.2 or lower* (a fix was introduced for that in *2019.3+*).
### 2. Outline in URP
The Universal Render Pipeline requires an additional step to render the outline, when enabled in the material, because URP - by design - won't render additional passes within a same shader file.
Simply edit the *URP Renderer Asset* that is linked to your main *URP Asset*:
- add a new *Renderer Feature*.
- in the *Filters* section, add a *Shader Pass* named "*Outline*"
I recommend setting the *Event* to "*After Rendering Opaques*", although other values might suit your situation better.
You can also easily change which objects will use an outline by using the *Layer Mask* setting and placing GameObjects in the appropriate layer(s).
### 3. Shader Stripping when Building
The Hybrid Shader contains code for both the Built-in and Universal render pipelines. When building your project, a script will handle stripping the unused variants corresponding to the pipeline that is not used, to decrease the build time and final size.
Standard PBS Shader
The *Standrad PBS* shader is based on Unity's *Standard shader*, with additional *stylization options*.
The Standard Properties are the same that you will find on the Standard shader:
- Rendering Mode (opaque, transparent, cutout)
- Albedo Map & Color
- Metallic/Specular Maps (depending on workflow)
- Reflection (using Reflection Probes)
- Normal Map (enables Bump Mapping)
- Height Map (enables Parallax mapping)
- Occlusion Map
- Emission Map & Color
- Secondary Maps (Albedo + Normal)
Please refer to the [Unity manual](+https://docs.unity3d.com/Manual/StandardShaderMaterialParameters.html) for more information about the Standard Properties.
Toony Colors Pro 2 adds the following *stylization properties*:
- [[Highlight/Shadow Color]]
- [[Ramp Style]]
- [[Main and Additional Lights Ramp Control]]
- [[Stylized Specular]]
- [[Stylized Fresnel]]
## Options Reference
Here is a reference of the available options with screenshots to quickly understand how they work.
All examples have two additional point lights (blue and orange) to better highlight how some settings affect each light.
### Base Properties
#### Highlight/Shadow Color
Additional color tints for the *lit* and *unlit* parts of the material respectively.
![Highlight Color ](images/pbs_colors_highlight.png)
![Shadow Color ](images/pbs_colors_shadow.png)
![Shadow Color without additional lights](images/pbs_colors_shadow_main.png)
For historical reasons (read: I wasn't doing things properly years ago), you will notice that when additional lights are active, the shadow color will also affect lit parts of the model!
#### Ramp Style
The *Ramp Shading* defines how the separation between lit and unlit areas will be handled visually.
The *Standard PBS* shader uses a threshold/smoothing based ramp by default, or you can toggle the texture ramp option.
Disable Wrapped Lighting | Disables light wrapping, i.e. light that encompass the whole model rather than stopping at a 90° angle between the light and normal vectors. This setting exists for historical and backward compatibility reasons. _I recommend leaving it on and using the *threshold* setting to change how lights wraps around the model instead._
Use Ramp Texture | Enables the texture ramp to calculate the ramp shading.
![Sliders Ramp ](images/pbs_ramp_default.png)
![Texture Ramp ](images/pbs_ramp_texture_m.png)
![Wrapped Lighting Enabled](images/pbs_wrapped_on.png)
![Wrapped Lighting Disabled (recommended)](images/pbs_wrapped_off.png)
#### Main and Additional Lights Ramp Control
When not using a ramp texture, you have an additional setting to define a separate smoothing for the additional lights.
Threshold | Defines the separation between shadows and highlights.
Main Light Smoothing | Smoothing of the separation between shadows and highlights for the main directional light.
Other Lights Smoothing | Smoothing of the separation between shadows and highlights for additional lights.
![Main Light = 0.1 Additional Lights = 0.1](images/pbs_ramp_default.png)
![Main Light = 1.0 Additional Lights = 0.1](images/pbs_ramp_smooth_main.png)
![Main Light = 0.1 Additional Lights = 1.0](images/pbs_ramp_smooth_other.png)
### Stylization Options
#### Stylized Specular
Will add a smoothing value allowing to get a crisper specular term. You can also blend between the regular and the stylized specular to get an hybrid look.
Specular Smoothing | Defines how crisp the specular highlights should look.
Specular Blend | Blending value between the Standard and Stylized specular visuals.
![Stylized Specular disabled](images/pbs_specular_off.png)
![Stylized Specular enabled](images/pbs_specular_on.png)
![Stylized Specular with 0.5 blending](images/pbs_specular_blend.png)
#### Stylized Fresnel
Will add an enhanced Fresnel effect linked to lights around the model.
Fresnel Strength | Defines how visible is the enhanced Fresnel effect (note that the strength is also dependent on the Smoothness of the material)
Fresnel Min/Max | Defines the threshold values for the Fresnel effect (similar to the Rim effect)
![Stylized Fresnel disabled](images/pbs_fresnel_off.png)
![Stylized Fresnel enabled](images/pbs_fresnel_on.png)
Enables the additional shader pass to render an outline.
See the Hybrid Shader [[outline]] section to learn more about the technique used and its caveats.
![Black Outline ](images/pbs_outline.png)
![Blended Outline with 50% opacity](images/pbs_outline_blended.png)
Outline Color | The main outline color.
Outline Width | The outline size.
Textured Outline | Toggles sampling the [[albedo]] texture for the outline color, in the vertex shader.
└─ Texture LOD | Defines the mip level at which to sample the texture.
Constant Screen Size | Scales the outline's width based on the distance from camera, so that it always appears at the same size on the screen.
Z Smooth | Provides parameters to slightly change the Z position of the vertices to try and correct outline artifacts that could appear.
Blended Outline | Enables blending for the outline pass, so that it can be blended with the scene. It might cause sorting issues though.
Outline Normals | Defines which data to use as normals when expanding the outline mesh. Should be set according to the settings used in the [[Smoothed Normals Utility]].
Shader Generator 2
The *Shader Generator 2* is the most complex and powerful tool included with *TCP2*.
It allows you to *generate your own stylized shaders*, using exactly the features you need.
It provides many more options than the *Hybrid* or *Standard PBS* shaders, and allows further customization (e.g. optimizing and re-arranging your data texture to not waste GPU memory, applying UV scrolling to any texture used, etc.).
There are a lot of features available, and its customization system using the *Shader Properties* is quite deep, so there is a dedicated documentation for it:
**See the [Shader Generator 2 Documentation](shader_generator_2.html).**
You can also take a look at the [tutorials page](tutorials.html) to see what it can achieve.
The **Shader Generator 2** doesn't have feature parity with the old Shader Generator 1 yet, e.g. the PBS template is missing.
You can still use and read the [Shader Generator 1 documentation here](+https://jeanmoreno.com/unity/toonycolorspro/Documentation/#shader_generator).
Smoothed Normals Utility
![Hard edges break the outline effect](images/smoothed_normals_hard.png)
![Smoothed normals stored in UV2 (hard edge shading is preserved)](images/smoothed_normals_smoothed.png)
### How it works
The outlining technique is based on the mesh normals. When a vertex has multiple normals (aka *hard edge shading*), it can break the outline as shown above.
The *Smoothed Normals Utility* will calculate the *average normals* for each vertex of your mesh, and assign them to an unused part of your mesh data (vertex colors, tangents, or other UV coordinates).
By enabling the corresponding option in the *Outline Normals Source property* in the material inspector of your TCP2 shader, the shader will take this data as the new normals to draw the outline.
This way you get a correctly outlined mesh with hard edge shading preserved, as pictured above.
Open the utility via the menu:
Tools > Toony Colors Pro 2 > Smoothed Normals Utility
In Unity, select:
- meshes or models assets from the Project view
- GameObjects with a *MeshFilter* or *SkinnedMeshRenderer* attached
The list of meshes ready to be processed should then appear in the Smoothed Normals Utility window.
Select the vertex data target to stored the smoothed normals:
- *Vertex Colors*
If using UV data, you can select how to store the smoothed normals:
- *Full XYZ*: will store the data as-is
- *Compressed XY*: will store the data compressed into the XY channels
- *Compressed ZW*: will store the data compressed into the ZW channels
Using compressed types loses precision, but it can be handy to optimize storage.
For example, you could keep the regular texture coordinates in UV1.xy, and store smoothed normals in UV1.zw, and thus not need any extra TEXCOORD in the vertex data (or keep them free for other usages).
Click on `Generate Smoothed Mesh` to generate a copy of the mesh with smoothed normals in the selected mesh data.
The new mesh will automatically be assigned if you had MeshFilters or SkinnedMeshRenderers selected.
You will then have to select the correct option in the *Outline Normals Source* of the *Material Inspector* so that the shader knows where and how to interpret the outline normal data.
Smoothed Normals will only be stored in **tangents** for **skinned meshes**.
This is because normals need to be affected by bones, and in the 3 options available only tangents are affected by bones (vertex colors and UV data are not).
This means that smoothed normals can't work with normal map, anisotropic specular, or other features requiring tangent data on skinned meshes.
If a copy of the mesh has already been made, it will be overwritten with the new settings defined.
You can recognize the generated meshes with the **[TCP2 Smoothed]** suffix, and they are all stored in the 'Smoothed Meshes' folder by default.
You can customize the suffix in the tool.
The *Ramp Generator* allows you to create a ramp texture (to be used with the [texture ramp](#hybridshader/optionsreference/rampshading) feature) very easily from a gradient.
Simply edit the gradient and set a texture width size. The texture height will always be 4 pixels tall.
The Ramp Generator can also *edit ramps* generated with it, allowing you to edit the gradient and *see the results in real-time* on your models/materials.
You can edit a gradient ramp either by:
- Loading a texture in the Ramp Generator directly
- Clicking on `Edit Gradient` in a TCP2 material that uses ramp textures
![Ramp Editor for a ramp texture used in a material](images/ramp_generator_edit.mp4)
If your ramp is grayscale, then it is useless to set a width higher than 256, because an 8-bit image can only represent at most 256 shades of gray.
Render Pipelines Information
*TCP2* supports the *Built-in* and *Universal* render pipelines.
Here are the supported shaders/tools for each pipeline:
- **Built-in Render Pipeline**
- *Hybrid Shader*
- *Standard PBS*
- *Shader Generator 2* with the [Default Template](shader_generator_2.html#templates/default)
- *Legacy Desktop / Mobile* shaders
- *Shader Generator 1* (legacy)
- **Universal Render Pipeline**
- *Hybrid Shader*
- *Shader Generator 2* with the [URP Template](shader_generator_2.html#templates/lwrp/urp)
The Universal Render Pipeline support is currently being developped with *URP v7.5.1* and *Unity 2019.4*.
Please let me know if you see bugs or issues, even if it's with a newer version.
*TCP2* supports a few third-party plugins, using the [Shader Generator 2](shader_generator_2.html):
- [Curved World](+https://assetstore.unity.com/packages/vfx/shaders/curved-world-26165)
You just have to enable the relevant options in the *THIRD PARTY PLUGINS* section of the [Shader Generator 2](shader_generator_2.html).
When using either plugin with the **Built-in render pipeline**, make sure to also enable **Add Shadow/Depth Pass** in the **OPTIONS** for the shadow maps to work properly!
If you have questions, bug reports or suggestions please contact me by email at: firstname.lastname@example.org
I'll do my best to answer as quickly as possible.