**Toony Colors Pro 2** **Shader Generator 2 - Documentation** v2.7.3 - June 2021 ([See changelog](changelog)) © 2021 Jean Moreno jean.moreno.public+unity@gmail.com [Main Documentation](documentation.html) ================================================================================================================================ Shader Generator 2 ================== The *Shader Generator 2* is now available to be used in *Toony Colors Pro 2*! The Shader Generator allows you to generate your own shader files for your project, with just the features you need. It has *many more features* than TCP2's default shaders, and can help you create *a wide variety of visual styles*. This new version of the Shader Generator tool improves the flexibility and control that you have over the generated shaders. The goal is to offer an *easy-to-use* tool with features *already implemented* (unlike a node-based tool for example), but where you still have *flexibility* over the generated code, for example choosing what source to use to fetch a color (single color, texture, vertex colors, constant color, etc.). Just toggle the features you want and select their options in the *Features* tab, and tweak the properties further if you need more control in the *Shader Properties* tab. If you are looking for the [main documentation, please find it here](documentation.html). Getting Started =============== Open the tool through the top menu: !!! Tools > Toony Colors Pro 2 > Shader Generator 2 Interface --------- Move your mouse on the different elements to learn about the interface:
Load a shader template here, e.g. Default, URP, ...
This is the current shader being edited, or 'None' if it's a new one.
You can click on this property to highlight the file in the Project view.
This is the name of the shader as it will appear in Unity's shader menu, in the material inspector.
In the **Features** tab, you can select the features that you want to add for your shader, along with their options.
In the **Shader Properties** tab, you can view most of the properties that will be used in your shader, and modify how they are fetched/calculated.
You can click on this help button to open this documentation in your browser pointing to the relevant feature.
The label for the feature; most of the times you can hover with the mouse to reveal a help tooltip about the feature.
The current value of the feature. If different than the default value, its label will be highlighted.
Features are organized in categories for easier navigation.
Global [[options]] for the Shader Generator 2.
First Steps ----------- First, you might want to load a shader template: - the *Default* template is a **non-?[PBS]((PBS means 'Physically Based Shading' and describes a lighting model that mimics the real world, where the shader will calculate most of its colors based on the lighting and a few parameters describing the physical aspects of the materials. The goal is to have a material that will always look good with all lighting environments, vs. a model where you have to tweak material parameters for each lighting conditions. The drawback is that you generally have less control over the final colors, should you want more stylistic visuals.))** general purpose template with a lot of features - the *URP* template is a the equivalent of the *Default* one for the *Universal Render Pipeline (URP)* Then, change the *Shader Name*: this will be the name you see in the shader selection menu, in the material inspector. !L[Loading a template and changing the name](images/sg2_main_2.png) Finally, look at the various features and enable the ones you want for your shader. Once you're done, click on `Generate Shader` and the file will be created. You will then be able to use your generated shader by selecting it in a material. !!! INFO Once you click on `Generate Shader`, the generated shader will automatically be loaded in the Shader Generator 2. You can assign it to a material, and then easily test the various features by enabling/disabling them and clicking on `Update Shader` in the Shader Generator: the material will update along with the shader. This is a good way to preview the different features on your own models. !!! INFO You can easily open a generated shader back in the Shader Generator by clicking on the cog icon in the top-right hand corner of the material inspector: ![](images/sg2_material_inspector_cog.png) Once you feel comfortable enough with the *[Features](#featuresreference)* tab, you can look into the [[Shader Properties]] tab for more control. Options ------- Option | Description --------------------------------|-------------------------------------- Select Generated Shader | Once a shader is generated or updated, it will automatically be selected in the Project view. Always overwrite shaders | Do not prompt when you are about to overwrite an existing shader. _This doesn't apply to shaders that have been modified manually, you will always be prompted before overwriting those!_ Reload Shaders from all Project | By default, the tool will only look for generated shaders in the default output directory (`JMO Assets/Toony Colors Pro/Shaders Generated`). When enabled, this makes it search through all the project assets. Automatic Filename | Automatically generate the filename for the output shader, based on its UI name. Automatic sub-directories | Automatically generate sub-directories for the output shader, based on its UI name. Show disabled fields | Show all fields in the UI, even if they are disabled. Can be useful to see all the options available for each feature. Show contextual help | Display contextual blue help boxes in the UI. Dockable Window | Makes the Shader Generator 2 window look like any other Unity window that can be docked anywhere, instead of a separate OS window. You will have to close and open the tool again to see the change. Templates ========= A template will be the basis to generate your shader from. Here is a quick description of each template and what they are made for. Make sure to also look at the demo scenes to see actual examples. Default ------- The Default template is a general purpose one, that works with the [Built-in Render Pipeline](+https://docs.unity3d.com/Manual/SL-RenderPipeline.html), in *Forward Rendering*. This is the one to use to create shaders for characters, environments, and everything that doesn't require special shader effects. URP ---- The URP template is the same as the [[Default]] one but working with the [Universal Render Pipeline](+https://unity.com/srp/universal-render-pipeline). Because the pipelines don't work the same internally, some features might render differently between the Built-in and Universal Render Pipelines. ### Outline and Silhouette passes in URP Additional passes, such as the Outline or Silhouette effects, work differently in URP. While URP does allow up to one additional pass that can be automatically executed on top of the main pass, this is not the recommended way to do it. Instead you should manually add a *"Renderer Feature"* in your URP Renderer asset, and use the relevant *"Shader Passes"* (or *"LightMode Tags"* in newer versions) names to enable them ("Outline" and/or "Silhouette" depending on which you need): ![User Interface in URP  ](images/urp_renderer_features.png) ![User Interface in newer versions of URP](images/urp_renderer_features_2.png) !!! WARNING Make sure that you enable the *URP Renderer Feature* option for both *Outline* and *Silhouette* effects in the Shader Generator 2, so that those passes are effectively disabled in the main rendering loop. Shader Properties ================= About ----- The *Shader Properties* is a powerful and flexible system used to further customize your shaders. A Shader Property is a property that will be used in the generated shader. They generally correspond to the properties you will see in the material inspector, although that's not always the case. This interface allows you to change their behavior, change how they are fetched and/or calculated, or do advanced combinations such as applying a mask, and reference properties between each other. For example, the `Albedo` property is always available: it corresponds to the main texture. You could change this texture's options to remove the tiling/offset values, or apply UV scrolling to it. The `Albedo` property is a color, meaning that you can change how it is fetched and use something else than a texture: a single color, the mesh's vertex colors, or even a constant color if you don't plan on changing that value: the shader will be better optimized that way. Reading the [tutorials](#shaderpropertiestutorials) from the most simple to the most advanced is a good way to progressively understand how the system works. ================================================================================================================================ Structure --------- A *Shader Property* works with *Implementations*: it has at least one, and can chain more implementations, with an *operator* describing how to combine them: - Shader Property - Implementation 1 - Operator 2 - Implementation 2 - Operator 3 - Implementation 3 - ... In the shader code, the property will generate a variable that will be calculated once at the beginning of its function (`Vertex` or `Fragment`), and then be used in the relevant part(s) of the code. The code will look like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [variable_type] __propertyName = [implementation_1] [operator_2] [implementation_2] [operator_3] [implementation_3] ... ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For example, the default implementations for `Albedo`, `Main Color` and `Alpha` look like this in the shader code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ shader float4 __albedo = ( tex2D(_MainTex, (input.texcoord0)).rgba ); float4 __mainColor = ( _Color.rgba ); float __alpha = ( __albedo.a * __mainColor.a ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Note that some "Special" implementations are sampled when the variable `__variableName` is _used_ in the code rather than when it is _declared_. This should generally not be of any concern though. ================================================================================================================================ Interface --------- Move your mouse on the different elements to learn about the Shader Properties interface:
View the available properties by clicking on this tab.
The name of the property, generally describing its usage.
The property type, can be `color`, `color (rgba)`, `float`, `float2`, `float3`, `float4`, or `fixed function`.
When available, shows a tooltip that gives some insight on the property's usage.
Where is the property used in the shader code: `Vertex` or `Fragment` program.
Useful to know which properties you can cross-reference, using the `Other Shader Property` implementation.
Shows the implementation menu, where you can copy/paste, import/export, or reset the implementations for this property.
You can also access it by right-clicking on the property name.
This is the current implementation for this property.
See the [[Implementations Reference]] to learn about the different implementations possible.
Use these buttons to add a new implementation, or remove this implementation.
This is one of the parameters of this implementation. It will be highlighted if its value is different than the default one.
Shader Properties are organized in categories, generally themed by the features they are related to.
**Custom Material Properties** allow you to define your own material properties that will show in the inspector, and then use them for any shader properties you want.
The name of the custom property, as it will appear in the material inspector.
The type of the custom property (float/range, vector, color or texture)
The name of the variable of the custom property in the shader code.
This is the name to use if you want to change the value with a script, for example using [`material.SetTexture("_TextureName", myTexture);`](+https://docs.unity3d.com/ScriptReference/Material.SetTexture.html) for a texture.
Use these buttons to add/remove Custom Material Properties.
================================================================================================================================ Interface with multiple implementations --------------------------------------- You can add as many implementations as you want for each property. Here is how the interface looks when there are two implementations for a property:
Drag this handle to reorder the different implementations of a property.
How this implementation will be blended with the previous one:
multiply `×`, divide `÷`, add `+` or subtract `-`
Here we have added a `Custom Material Property` implementation, linked to the "My Specular Mask" property that has been added in the **Custom Material Properties** section below.
The swizzle has been modified to only use the red channel: in this case, its effect is that the red channel of "My Specular Mask" will become a mask for the specular color.
This means that specular will appear on red areas, and be invisible on black areas of the texture.
Note that in this case, you could use a [Single Channel texture](+https://docs.unity3d.com/Manual/TextureTypes.html#SingleChannel) with the Red channel to optimize the memory used by the specular mask.
This section will indicate all the Shader Properties that are referencing this Custom Material Property.
================================================================================================================================ Custom Material Properties -------------------------- Those are material properties that you can define and then easily reference across multiple implementations. A good example would be a mask texture where each R,G,B,A channels are used to mask different features ================================================================================================================================ Implementations Reference ------------------------- -------------------------------------------------------------------------------------------------------------------------------- ### Constant Value The simplest implementation: just use a constant value for the property. Use it when you know that the value doesn't need to change, making the shader faster than if it were a material property for example. Parameter | Description -----------|----------------------- Value | The constant value. Precision | The [type of variable](+https://docs.unity3d.com/Manual/SL-DataTypesAndPrecision.html) to use.
Generally useful for optimization with mobile GPUs. -------------------------------------------------------------------------------------------------------------------------------- ### Material Property / ... Will add a material property, i.e. a value that you will be able to modify in the [material inspector](+https://docs.unity3d.com/Manual/Materials.html). These are common parameters for all Material Property implementations: Parameter | Description -------------------|---------------------------------------------------------------------- Label | The name of the material property as it will appear in the inspector. Variable | The name of the variable for this property in the shader code. This is the name to use if you want to change the material property with a script, using [`material.SetFloat,SetVector,SetTexture,...`](+https://docs.unity3d.com/ScriptReference/Material.html) Property Drawers | Add any [material property drawer](+https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html) here. Note that the Shader Generator will already add its own for the user interface in the inspector (headers, separators, etc.). GPU Instanced | Allow this material property to be per-instance when using [GPU instancing](+https://docs.unity3d.com/Manual/GPUInstancing.html). This will declare the variable in the `UNITY_INSTANCING_BUFFER_START()` constant buffer. #### Material Property / Float A single float property, that can be used for any kind of shader property type. Parameter | Description -----------|----------------------------------------------------------------------- Default | The default value when the shader is first assigned to a new material. #### Material Property / Range A single float property, displayed as a slider with min/max values. Parameter | Description -----------|----------------------------------------------------------------------- Min | The minimum value for the range. Max | The maximum value for the range. Default | The default value when the shader is first assigned to a new material. #### Material Property / Vector A Vector4 property (`float4` in shader terms). You are not forced to use _all_ of its channels though. Parameter | Description -----------|----------------------------------------------------------------------- Default | The default value when the shader is first assigned to a new material. Swizzle | How/which channels of the vector are used for the shader property. #### Material Property / Color A Color property. Parameter | Description -----------|----------------------------------------------------------------------- Default | The default value when the shader is first assigned to a new material. HDR Color | Allows the color to go over the [0-1] range. Swizzle | How/which channels of the color are used for the shader property. #### Material Property / Texture A Texture property. Parameter | Description -----------------------|------------------------------------------------------------------------ Default | The default value when the shader is first assigned to a new material. Swizzle | How/which channels of the color are used for the shader property. UV | Which UV channel to use from the model, or a special type:
- ?[Screen Space]((Screen Space UV are a special type of UV coordinates that will align the texture to the screen instead of using the model's UV channels.))
- ?[World Position]((World Position UV will simply map any two of the three X,Y,Z position channels as UVs. Useful when using multiple planar meshes that you want to combine together and get seamless UVs between them.))
- ?[Triplanar]((Triplanar UV is a procedural form of UVs calculated based on the model's position and normals, either in world or object space. UVs will be calculated for each X,Y and Z axis and will be blended where they intersect.)) └─ Object Space | _With **Triplanar UV** enabled_: calculate the triplanar in object space rather than in world space, so the UVs follow the model with its transform. └─ Vertex SSUV | _With **Screen Space UV** enabled_: calculate the screen space UV in the vertex shader. Faster, but can appear distorted. └─ Obj Offset SSUV | _With **Screen Space UV** enabled_: offset the UV with the object's position, to prevent the texture from "sliding" through the object (also called "shower door" effect). Tiling/Offset | Enable tiling/offset values for this texture. └─ Global | Makes the tiling/offset values global for the selected UV channel.
This also means that the tiling/offset values will be calculated in the vertex shader, rather than in the fragment shader. └─ Variable | Which variable to use for the tiling/offset values.
Change it if you want this texture to inherit from the tiling/offset values of **another texture implementation**. └─ Scale by Texel Size | Scale the texture tiling according to the texel size (i.e. the texture resolution in pixels).
Mostly useful when you use screen space UV and want the pixels of the texture to exactly match the pixels on the screen. UV Animation | Enable different kinds of UV animations: └─ Scrolling | Basic scrolling across the U and V axis. Can be **Global** or linked to another shader property **Variable**, just like the tiling/offset values. └─ Random Offset | Will apply a random offset on the UV, with a material property to define the speed.
Originally designed for the sketch effect, to make the sketch texture move randomly.
Can be **Global** to the selected UV channel. └─ Sine Distortion | Will apply a sine-based animation on the UV, with a material property to define the parameters (speed, amplitude, frequency, offset).
Originally designed for the water effects to simulate liquid-like movement using the UVs only. No Tile | Apply a special algorithm to prevent texture repetition.
It's a bit slower: the texture will be sampled twice, and a small cache-friendly noise texture will be sampled once.
Based on [an algorithm from Inigo Quilez](+http://www.iquilezles.org/www/articles/texturerepetition/texturerepetition.htm) (Technique 3, MIT License). ###### No Tile Details The texture needs to have some randomness to it for the effect to work nicely: ![Regular texture tiling](images/texture_notile_rocks_off.png) ![With "No Tile" enabled](images/texture_notile_rocks_on.png) A texture with a regular pattern won't work so well: ![ ](images/texture_notile_checker_off.png) ![ ](images/texture_notile_checker_on.png) -------------------------------------------------------------------------------------------------------------------------------- ### Vertex Color Returns the vertex color of the model. You could use the color directly, or use one of the RGBA channels as a cheap mask for any shader property. Parameter | Description -----------|-------------------------------------------------- Swizzle | Which channel(s) to fetch from the vertex colors. -------------------------------------------------------------------------------------------------------------------------------- ### Other Shader Property Use the value of *another shader property* for this property. Depending on the type, you can also select the swizzle, i.e. only use specific channels of the other property. Some properties might be unavailable: in this case, the reason is stated between parenthesis at the end of the other property's name. For example, you can't reference `Fragment` properties in a `Vertex` property, or you can't have cyclic references (two properties referencing each other). Parameter | Description -----------|---------------------------------------------------------- Swizzle | Which channel(s) to fetch from the other shader property. -------------------------------------------------------------------------------------------------------------------------------- ### Custom Material Property Use a property that you have defined in the *Custom Material Properties* section. This allows you to easily reuse the same custom properties for multiple shader properties. -------------------------------------------------------------------------------------------------------------------------------- ### Special / HSV HSV is a *hue, saturation, value* modifier that is applied to the current state of a `color` property. The relevant material properties will be automatically created. Parameter | Description -----------|------------ HSV Mode | Hue | In *Colorize* mode, enable the *hue* material property. Saturation | In *Colorize* mode, enable the *saturation* material property. Value | In *Colorize* mode, enable the *value* material property. -------------------------------------------------------------------------------------------------------------------------------- ### Special / Custom Code Custom Code allows you to add any kind of shader code to the property. It is suggested to use this when you need to add small modifications, rather than modifying the resulting shader, in case you want to update that shader later with different features or options (in which case you'd lose all manual modifications in the .shader file). The code is inserted right after the previous implementation, if any, and *doesn't have any blending operator* : it's up to you to determine how the code will interact with the previous property. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Prepend Type | Enable prepended code, i.e. arbitrary code that will be inserted before sampling this Shader Property. This allows more complex code to be inserted in custom shaders. └─ Embedded | Write the prepended code directly in the provided text input.     └─ Prepend Code | The self-contained code written directly here. You can use the *`{n}` notation* to reference other implementations. └─ External File | Link an external .cginc or .hlslinc file that will provided the prepended code. You can use the *`{n}` notation* to reference other implementations.
See [below](#shaderproperties/implementationsreference/special/customcode/prependedcode:externalfile) for more information.     └─ Block Name | The name of the block snippet, as defined by the special comments in the linked file.
Available names will be automatically parsed from the file.     └─ variable (type) | When custom variables are defined in the block, they will appear here and you can enter the text, optionally using the *`{n}` notation*. Code | The custom shader code to insert for the Shader Property #### Prepended Code One of the challenges with the Shader Generator is that sometimes you want to *manually modify the output shader file*, but if you go back and update that shader with the Shader Generator to enable new features, then any handwritten code would be *overwritten and lost*. The *Custom Code* implementation and its *Prepend Code* options aim at fixing this shortcoming: you can write your custom code directly in the Shader Generator, so that it is never lost whenever you update the shader later on. Prepended Code is inserted just before sampling the Shader Property, so you can do any calculation (possibly using previous properties/variables) and then use the result in the Shader Property through the `code` parameter. #### Prepended Code: Embedded Embedded prepend code is directly written in the Shader Generator UI. You can use the *`{n}` notation* to reference other implementations, e.g. to easily change some variables of your custom code (make them a constant or a material property for example). #### Prepended Code: External File The external file prepend code allows you to link a *.cginc* or *.hlslinc* file, and extract snippets from it using a specific comment syntax. The advantages over the embedded code are: - reuse snippets of code across multiple shaders - use your shader IDE with all the editing advantages like syntax highlighting - easier to change the code later on (but still requires the shader to be updated with the Shader Generator)
External File Syntax
Use special comments prefixed with *`//#`* to define the properties of a prepended block. Mouse your move on the keywords to see their meaning.
//#
BLOCK_NAME
Defines a new block, named `BLOCK_NAME`.
:
//#
type
Declares a new variable used by that block.
Type can be `float`, `float2`, `float3`, `float4`
In the Shader Generator, you will be able to write your own value, or use the *`{n}` notation* to reference other implementations (e.g. a material property)
variable_name
The name of the variable, as used in the code block.
default_value
The default value for this variable, can be any text (e.g. `1.5`, `float3(1,2,3)` or `sin(_Time.y * 4) + 1`)

//# !
Defines a comment that will show in the Shader Generator UI. Can be useful to hint at the output variable name for example.
Comment to show in the UI
float _output_ = sin(variable_name) * 4;
///
Comments in the code with three `///` will be excluded in the final generated shader.
Comment that is exclusive to the prepend file
// Comment that will be included in the shader
//# NEW_BLOCK:
A new block or the end of the file will define the end of the previous block.

...
`_variableName_` notation If your code block is meant to be used multiple times in the same shader, using fixed variable names will prevent the shader from compiling because of duplicated variable declaration. For those cases, you can use the `_variableName_` notation and the Shader Generator will automatically replace them with unique names in the code to avoid those compilation errors. For example, this code in the prepend file: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ shader float4 _myCustomColor_ = float4(1.0, 0.5, 1.0, 1.0); output.Albedo = lerp(_myCustomColor_.rgb, output.Albedo, (_Time.z + 1) / 2.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ will become like this in the final shader: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ shader float4 myCustomColor_100 = float4(1.0, 0.5, 1.0, 1.0); output.Albedo = lerp(myCustomColor_100.rgb, output.Albedo, (_Time.z + 1) / 2.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! INFO Variables declared in the special comments using `//# type variable_name defaultValue` will automatically be parsed to have a unique name in the output code. There is no need to add the `_name_` notation there. #### `{n}` Notation You can reference other implementations of the Shader Property for both *Custom Code* and *Prepend Code*. This allows you to have easily modifiable parameters within your custom code, that you can change to any other implementation later on (e.g. a constant, a float material property, or sampling a texture). Referenced implementations will be prefixed by `CC` in the UI (meaning `Custom Code`), and will be excluded from the automatic calculation of the Shader Property. It is up to you to write the swizzle (e.g. `.rgb`) in your custom code. -------------------------------------------------------------------------------------------------------------------------------- ### Special / ... Some special implementations provide you with specific values calculated at different points in the shader code. As such, their availability depend on the context of the Shader Property. For example, the ?[N·L]((Dot product between the model's normals and light direction.
This is the basis for direct lighting shading, giving a value of 1 when a triangle is directly facing the light, and 0 when it points away from the light. Also called Lambert shading.)) value will be available for properties that are used after its calculation, but unavailable for properties that are used before. #### Special Implementations Reference Special Implementation | Description | Available in the template(s) | Screenshot ----------------------------------- |------------------------------------------------------------------------------------------------------------------------|-------------------------------------|--------------- ***N·L*** | The N·L raw value, i.e. how much is the pixel facing the light direction. | ((Default)) ((URP)) | ![](images/_special_impl_ndl.png) ***N·L Ramp
(Black and White)*** | The N·L value with the shading ramp applied (without highlight/shadow colors). | ((Default)) ((URP)) | ![](images/_special_impl_ndl_ramp.png) ***N·V*** | Dot product between the view direction and the surface normal. This is the basis used to calculate [rim lighting](#featuresreference/lighting/rimeffects). | ((Default)) ((URP)) | ![](images/_special_impl_ndv.png) ***VFACE*** | The `VFACE` shader semantic, which will return whether the current triangle is facing the view (returns 1) or away from the view (returns -1).
Mostly useful when used in combination with culling off (to view both front- and back-face triangles) in the [[Shader States]]. | ((Default)) ((URP)) | !!! INFO Some special implementations are not referenced here, as their description is self-explanatory (e.g. Light Color). Features Reference ================== The Features Reference is not complete yet, but eventually you will find the description and screenshots here for them. In the meantime you can refer to the [old documentation](+https://www.jeanmoreno.com/unity/toonycolorspro/Documentation/#shader_generator) for screenshots, and you also have tooltips for most of the features in the Shader Generator 2 window directly in Unity. !!! INFO Some features have a 'Make Optional' option: this will make the feature an option in the shader, with a checkbox to enable/disable it. Internally it will translate that to a shader keyword using the `#pragma shader_feature` directive. See [Unity documentation on shader program variants](+https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html) to know more. -------------------------------------------------------------------------------------------------------------------------------- ## Lighting -------------------------------------------------------------------------------------------------------------------------------- ### Ramp Style ((Default)) ((URP)) The ramp style determines how the soft ?[N·L]((Dot product between the model's normals and light direction.
This is the basis for direct lighting shading, giving a value of 1 when a triangle is directly facing the light, and 0 when it points away from the light. Also called Lambert shading.)) value will be converted into a "stylized" look. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Slider Ramp | The material will have two values, ramp threshold and ramp smoothness, to define the position and softness of the ?[terminator]((The terminator is the line at the edge of light and shadow in direct lighting:
)) line. RGB Slider Ramp | Same as slider ramp, but separating the threshold and smoothness values for the red, blue, green channels.
This allows you to define a colored ?[terminator]((The terminator is the line at the edge of light and shadow in direct lighting:
)), e.g. to simulate subsurface scattering (for skin, cloths, ...). Texture Ramp | Use a texture to define the ramp look. Some ramps are included in TCP2, and you can use the [Ramp Generator](+documentation.html#tools/rampgenerator) to easily create your own. Texture Ramp
└ Offset/Size | Add offset/size controls for the ramp texture, similar to the threshold/smoothness sliders. Texture Ramp
└ 2D Texture | Use a 2D ramp texture instead of a 1D texture. You can control how to sample the V texture axis with the `2D Ramp Lerp` value in the [[Shader Properties]]. Crisp Ramp | Same as Sliders Ramp, but with a smoothness value of 0. This version is faster than manually setting the smoothness to 0, because it uses the `step()` function rather than `smoothstep()`. Crisp Ramp
(Anti-aliased) | Anti-aliased version of the crisp ramp.
Note that this is different than setting a low smoothness with Slider Ramp value because it's screen-space based, and hence ensures that the line is always a few pixels wide (whereas using a low smoothness value will show width inconsistencies depending on the model polygons).
See the `Ramp Crisp Smoothing` property in the [[Shader Properties]] to define the anti-aliasing smoothness. Bands | Show visually distinct bands throughout the shading. The bands count and the smoothing between each band can be adjusted. Bands Crisp | Same as Bands, but having crisp lines between each band rather than a smoothing parameter. Bands Crisp
(Anti-aliased) | Anti-aliased version of the bands crisp ramp.
See the `Ramp Crisp Smoothing` property in the [[Shader Properties]] to define the anti-aliasing smoothness. No Ramp | Effectively disable ramp shading, and use the raw N·L value. Unlit | Disable shading for the main light. Additional lights will still be taken into account, but you can disable them in the [Options](#featuresreference/options). ![Slider Ramp Varying smoothness  ](images/desktop_ramp_smoothness.webm) ![Slider Ramp Varying threshold  ](images/desktop_ramp_threshold.webm) ![Slider Ramp Threshold 0.5 Smoothness 0.1](images/ramp_style_sliders_1.png) ![Slider Ramp Threshold 0.6 Smoothness 0.7](images/ramp_style_sliders_2.png) ![RGB Slider Ramp with blue threshold value    ](images/ramp_style_rgb_sliders_1.png) ![RGB Slider Ramp with red threshold value to simulate skin subsurface](images/ramp_style_rgb_sliders_skin.png) ![Same example with regular Slider Ramp, notice how the terminator looks duller  ](images/ramp_style_rgb_sliders_skin_off.png) ![Texture Ramp](images/ramp_style_texture_1.png) ![Texture Ramp](images/ramp_style_texture_2.png) ![Crisp Ramp](images/ramp_style_crisp.png) ![Crisp Ramp (anti-aliased)](images/ramp_style_crisp_aa.png) ![Bands Ramp](images/ramp_style_bands.png) ![Bands Crisp Ramp](images/ramp_style_bands_crisp.png) ![Bands Crisp Ramp (anti-aliased)](images/ramp_style_bands_crisp_aa.png) ![No Ramp](images/ramp_style_noramp.png) !!! INFO When using the *RGB Slider Ramp* option, by default each channel can be tweaked using a *slider*. You can change these to *color properties* instead through the [[Shader Properties]] if you want a more intuitive way of tweaking these values: ![](images/sg2_rgb_sliders_properties.png) -------------------------------------------------------------------------------------------------------------------------------- ### Ramp Control ((Default)) ((URP)) Define ramp shading properties to be global, for the main vs other lights, or for each light type (((Default)) template only). This could allow you to have a solid ramp for the main directional light, but make all other lights smooth. ![Global All lights use the same threshold/smoothness values](images/ramp_control_global.png) ![Main + Other Lights Crisp main light Smooth point lights](images/ramp_control_main_other.png) ![Main + Other Lights Varying smoothnesses  ](images/desktop_ramp_mixed.webm) -------------------------------------------------------------------------------------------------------------------------------- ### Wrapped Lighting ((Default)) ((URP)) Wraps the N·L calculation allowing the received light to go beyond 90° on faces, where they should physically not receive lighting. It will effectively push back the ?[terminator]((The terminator is the line at the edge of light and shadow in direct lighting:
)). This can give more flexibility when changing the threshold parameter if used in the [[Ramp Style]]. Note that if used along with received shadows, it can show artefacts that are inherent to shadow maps but are noramlly hidden beyond the terminator. ![Regular](images/ramp_style_sliders_3_regular.png) ![Wrapped](images/ramp_style_sliders_3_wrapped.png) -------------------------------------------------------------------------------------------------------------------------------- ### Shadow Color Shading ((URP)) Defines how the shadow color is applied to the material. This setting will affect the final rendering a lot, especially when multiple lights are used. The Main Light setting will give the same results as the built-in rendering pipeline. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Clamp Light Intensities | Ensure that the color received by all lights or additional lights never exceed a value (1 by default). In the following examples, a **main directional light** is used along with **two point lights** (a blue and a white one); the material is using a **red shadow color**. - The "**All Lights**" option ensures that the shadow color is not visible wherever the model is lit - The "**All Lights Clamped**" option ensures that the amount of light received from all lights never exceeds 1 - The "**Main Light**" option will apply the shadow color to the shadowed areas of the main directional light, and will then add the point lights on top of that result (notice that the point lights illuminate the red shadowed areas) ![All Lights](images/urp_shadow_color_shading_all.png) ![All Lights Clamped](images/urp_shadow_color_shading_all_clamp.png) ![Main Directional Light](images/urp_shadow_color_shading_main_light.png) !!! INFO When using the *All Lights* option and when no light is active, by default the material will show the Shadow Color. If you want the material to be black (or just show ambient), then you can add a "Special/Light Color" implementation on top of the Shadow Color in the [[Shader Properties]] tab: ![](images/shadow_color_shading_tip.png) -------------------------------------------------------------------------------------------------------------------------------- ### Shadow Color Mode ((Default)) ((URP)) How the shadow color is blended on the model: either multiplied on top of the albedo color, or it replaces the albedo color entirely (and thus hides any texture detail). ![Shadow Color Mode: Multiply](images/shadow_color_mode_mult.png) ![Shadow Color Mode: Replace](images/shadow_color_mode_replace.png) -------------------------------------------------------------------------------------------------------------------------------- ### Shadow HSV ((Default)) Generate hue, saturation, value controls for the shadowed parts of the material. This means that you can add color variations for shadowed parts of the model, instead of just having a single shadow color multiplied. ![Shadow HSV: the hue of the texture gets redder in the shadows](images/shadow_hsv.png) !!! WARNING This will change the HSV values of the *albedo* color in the shadowed areas, *not the shadow color itself*. If you want to change the HSV values of the shadow color, you can easily do that by adding a [[Special / HSV]] implementation to the *Shadow Color* property of the [[Shader Properties]]. -------------------------------------------------------------------------------------------------------------------------------- ### Apply Shadows before Ramp ((Default)) ((URP)) This will integrate the shadow attenuation before calculating the ramp. It can be useful in some specific cases, for example when using the [RGB Slider Ramp](#featuresreference/lighting/rampstyle) option and you want the fringing colors to also show through the shadow map sampling. This also means that the ramp shading is applied to the shadow map artefacts, such as the gradient that appears due to bilinear filtering, and as such the look will also depends on the shadow map settings. In the example below, you can see that when the option is enabled, it benefits from the color fringe of the [RGB Slider Ramp](#featuresreference/lighting/rampstyle) option but it also makes the shadow map crisper (due to the smoothing value): ![Apply Shadows before Ramp Disabled](images/apply_shadow_ndl_off.png) ![Apply Shadows before Ramp Enabled](images/apply_shadow_ndl_on.png) -------------------------------------------------------------------------------------------------------------------------------- ### Specular ((Default)) ((URP)) Enable specular on the material. Specular | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Blinn-Phong | Fast and non-physically-based specular, with color and smoothness controls. The specular falloff is very soft. PBR Blinn-Phong | Physically-based version, where the intensity will decrease as the smoothness increase. GGX | More accurate physically-based version, with a specular falloff closer to real life materials.
This is the most popular specular algorithm used in real-time PBR rendering. Anisotropic | Anisotropic specular based on the [Ward algorithm](+https://en.wikipedia.org/wiki/Specular_highlight#Ward_anisotropic_distribution). Needs the mesh tangents to work properly. Hair Anisotropic | A different anisotropic model made for hair. It will calculate two specular terms, one for high-frequency details (the white wobbly line in the example), and one for low-frequency details (a broader specular term). Both terms are easily modifiable (color, strength, shift). Needs the mesh tangents to work properly. └─ Anisotropic Specular Basis | Defines which vector to use as a basis for the anisotropic specular terms calculation. ![Specular: Blinn-Phong](images/specular_blinnphong.png) ![Specular: PBR Blinn-Phong](images/specular_blinnphong_pbr.png) ![Specular: GGX](images/specular_ggx.png) ![Specular: Anisotropic](images/specular_aniso.png) ![Specular: Hair Anisotropic](images/specular_aniso_hair.png) Stylized Specular | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Cartoon | Add size and smoothness controls to the specular area, allowing to define a crisper specular shape. Bands | Similar to the cartoon one, with multiple levels, all with a crisp shape. ![Stylized Specular: Cartoon](images/specular_stylized_cartoon.png) ![Stylized Specular: Bands](images/specular_stylized_bands.png) ![Stylized Specular: Texture Ramp](images/specular_stylized_ramp.png) When using **Hair Anisotropic**, the **Anisotropic Specular Basis** option defines which vector to use as a basis for the specular term calculation. Use the one that gives the best results for your hair mesh. ![Hair Anisotropic using bitangent](images/specular_aniso_hair.png) ![Hair Anisotropic using tangent](images/specular_aniso_hair_tangent.png) -------------------------------------------------------------------------------------------------------------------------------- ### Emission ((Default)) ((URP)) Enables an emissive color on the shader. By default this will be a simple Color property, but you can change or expand it using the [[Shader Properties]] tab to use a Texture instead, or a Texture mask multiplied by a Color for examples. ![Yellow emission color  ](images/emission_color.png) ![Yellow emission color with a texture mask](images/emission_texture.png) ![Emission with a fixed mask and a scrolling mask on top](images/emission_texture_scroll.webm) -------------------------------------------------------------------------------------------------------------------------------- ### Rim Effects ((Default)) ((URP)) Enables fake rim light-like effects, i.e. light coming from behind the mesh. Technically this is calculated based on the view direction and the surface normal: faces pointing away from the view receive more 'light', while the ones facing the view directly receive no 'light' at all. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Rim Lighting | Adds the rim color, making it appear as an additional light (i.e. black color is thus transparent). Rim Outline | Linearly blends the rim color, making it appear as a solid color overlay (i.e. black color is fully visible and entirely black). Vertex Rim | Calculate the rim factor in the vertex shader, which is faster but can cause visual artifacts on meshes with few vertices. Directional Rim | Adds control for the directionality of the rim effect, i.e. make it always come from the left no matter the view angle. └─ Perspective Correction | Try to compensate the perspective distortion that appears when meshes are near the screen edges when using directional rim. Light-based Mask | Mask the rim lighting based on the lights: the rim effect will only appear on highlighted parts of the mesh. ![Strong white rim lighting Min `0.5`, Max: `1.0`](images/rim_lighting_1.png) ![Black rim outline Min: `0.5`, Max: `1.0`](images/rim_outline_1.png) ![Soft and subtle rim lighting Min: `0.0`, Max: `2.0`](images/rim_lighting_2.png) ![Crisp rim outline Min: `0.7`, Max: `0.72`](images/rim_outline_2.png) ![Light-based Mask using the light color as the rim color with the [[Shader Properties]]](images/rim_lighting_lightmask.png) ![Inverted rim lighting Min: `0.5`, Max: `-0.25`](images/rim_lighting_3.png) !!! INFO You can use the rim basis as a mask for any other property using the [N·V special implementation](#shaderproperties/implementationsreference/special/.../specialimplementationsreference) in the [[Shader Properties]] tab. You can create interesting effects this way, for example having only the edges of your mesh transparent by setting the Alpha to N·V and using alpha blending: ![](images/rim_alpha_.png) -------------------------------------------------------------------------------------------------------------------------------- ### Subsurface Scattering ((Default)) ((URP)) A fast Subsurface Scattering technique based on the [work by Colin Barré-Brisbois and Marc Bouchard](https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/). It will simulate translucency and lights behind objects will illuminate them. For a more convincing effect, you can use a thickness map (change the **Thickness** [Shader Property](#shaderproperties) to [[Material Property / Texture]] to be able to add one in the material). You can easily compute a thickness map by baking an ambient occlusion map to the mesh with inverted normals, and then inverting the resulting color. ![Moving point light behind the mesh](images/cat_subsurface.webm) ![Same with different values in the material](images/cat_subsurface_2.webm) !!! INFO The **Screen-Space Factor** option is very useful for vegetation: it will make the subsurface effect more visible as the light direction points towards the view, e.g. when the sun is looking directly at the camera. -------------------------------------------------------------------------------------------------------------------------------- ### Reflections ((Default)) ((URP)) #### Reflection Probes Add support for Unity's Reflection Probes in the shader. You can optionnally define a mask for the color and the roughness of the reflection through the [[Shader Properties]]. #### Planar Reflections Add support for crisp real-time reflections for a particular plane, using the accompanying *TCP2 Planar Reflections* script. This is mostly useful for planar reflective surfaces, such as water, ice, shiny floor, etc. It could also be used for a mirror. The script needs to be attached to the reflective GameObject, and will create a camera that will render the reflections from the point of view of that GameObject. As such it can be quite expensive, so make sure to use the layers to filter objects that have to be rendered through the reflection, and to tweak the parameters to ensure the best performances (i.e. the resolution of the reflection Render Texture). !!! WARNING Make sure that the reflective GameObject is in *its own layer*: the script will automatically exclude that layer from the reflections, to ensure that the reflective GameObject won't reflect itself. ![Planar Reflections](images/reflections_planar.png) #### Reflection Cubemap Add reflections based on a cubemap defined in the material. You can also add an option to define the surface roughness, so that the cubemap appears more or less blurred, using its mip maps. If so, make sure to set the *Convolution Type* to *Specular (Glossy Reflection)* in the cubemap texture's import settings. ![Reflection Cubemap with a roughness mask](images/reflections_cubemap_roughness.png) #### Fresnel Reflections This option applies to *all reflection types*; it will simulate a Fresnel effect on them, i.e. that fact that reflections are much more visible at grazing angles than when facing the eye. This is a good way to simulate physically reflective materials such as glass for example. ![Fresnel Reflections](images/reflections_cubemap_fresnel.png) -------------------------------------------------------------------------------------------------------------------------------- ### MatCap ((Default)) ((URP)) MatCap uses a single 2D texture to define a view-dependent shading model. It can be a cheap way to add fake reflections on a model, particularly for less powerful devices like low-end mobile, or if you need a certain kind of stylization. ![MatCap multilpied with Albedo](images/matcap_cat_1.png) ![MatCap texture only](images/matcap_cat_2.png) ![The MatCap texture used](images/matcap_tex.png) -------------------------------------------------------------------------------------------------------------------------------- ### Ambient Lighting / Indirect Diffuse ((Default)) ((URP)) Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Disable Ambient Lighting | Entirely disable ambient lighting provided by the rendering pipeline (as defined in the [Lighting Settings](+https://docs.unity3d.com/Manual/GlobalIllumination.html)). Cubemap Ambient | Provide a cubemap property that will define the ambient colors. Usually used with a blurred cubemap derived from a skybox Directional Ambient | Provide 6 colors property to define the ambient lighting coming from all axis (+X , -X, +Y, -Y, +Z, -Z).
Can be in world or view space. Occlusion | Enable the Occlusion Shader Property to block ambient lighting.
It is set to the Albedo alpha channel by default, but you can change that in the [[Shader Properties]] tab. -------------------------------------------------------------------------------------------------------------------------------- ## Surface -------------------------------------------------------------------------------------------------------------------------------- ### Vertex Displacement ((Default)) ((URP)) Enable vertex displacement, either in local (object) or world space. You can change the displacement source in the [[Shader Properties]], by default it will use a texture and a range parameter for the displacement strength. -------------------------------------------------------------------------------------------------------------------------------- ### Normal/Bump Map ((Default)) ((URP)) Enable tangent space normal mapping. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Bump Scale | Adds a value in the material to control the normal map strength. Parallax/Height Map | Performs parallax mapping on the UVs according to a height map, that is offsetting the UVs based on the view and the normal direction to emphasize the normal mapping. Sample Normal Map first | Ensures that the normal map is sampled before other properties, so that [[Material Layers]] can [benefit from the calculated normals](#materiallayers/interface/anoteonnormal-basedlayerswithnormalmaps). ![Normal mapping](images/normal_map.png) ![With specular and rim lighting](images/normal_map_specular.png) -------------------------------------------------------------------------------------------------------------------------------- ### Texture Splatting/Blending ((Default)) ((URP)) Blend multiple textures based on a source map (using a texture, vertex colors, or any other source data). It can blend up to 5 different textures: one for each R,G,B,A channel of the map texture, plus one for the black color. To change the source map data, go to the [[Shader Properties]] and look for the **Texture Blending / Blending Source** property (e.g. you can replace it with **Vertex Color**). !!! INFO As of TCP2 v2.7, the new [[Material Layers]] system is an alternative to the texture splatting/blending feature. It is a bit more complex to setup, but it can do much more as it can make the layer affect about any other property in addition to just albedo and normal map. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Blend Method | Defines how to blend the textures based on the blending source data. The height method expects the additional textures to have an alpha channel defining their height. Enhance Blend Contrast | Adds a Vector4 property to the material to allow fine-tuning the contrast of each color of the source map. Texture 0-4 | Toggles the number of textures to blend, and the color channel they are mapped to. Normal Map Blending | Adds a normal map for each additional texture (will enable the [Normal Map](#featuresreference/surface/normal/bumpmap) feature). ![Texture Blending Example](images/texture_blending_1.png) ![Source texture visualization](images/texture_blending_source.png) ![Texture Blending with Normal Maps](images/texture_blending_normal.png) -------------------------------------------------------------------------------------------------------------------------------- ### Triplanar Mapping ((Default)) ((URP)) Blend multiple textures using procedural triplanar UVs: each texture will be projected along a world normal (X, Y, Z) and blended onto the model. This technique is generally used to easily texture terrains without needing any UV on the mesh. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- UV Space | Whether to use object or world space normal to calculate the UVs. Surface Texture | How many textures to use for the surface (the XZ plane), either a single one or two (e.g. ground & ceiling). └─ Ceiling Mode | How to map the second surface texture: either using the negative Y normal (surface pointing down), or using a threshold value. Walls Texture | How many textures to use for the walls, one or two (one for each X and Z axis). Height Blending (Alpha) | Whether to use the textures' alpha channel to perform height-based blending (as in the [Texture Splatting/Blending](#featuresreference/surface/texturesplatting/blending) feature). Triplanar Normal Maps | Adds a normal map for each triplanar texture (using Witheout method for normal blending). ![Triplanar Mapping using Min/Max Threshold ceiling mode](images/triplanar.png) ![Triplanar Mapping with normal map](images/triplanar_normal.png) ![Triplanar Mapping with [Texture Blending](#featuresreference/surface/texturesplatting/blending)](images/triplanar_texture_blending.png) -------------------------------------------------------------------------------------------------------------------------------- ## Stylization -------------------------------------------------------------------------------------------------------------------------------- ### Stylized Threshold ((Default)) ((URP)) Use a texture to modulate the ?[N·L]((Dot product between the model's normals and light direction.
This is the basis for direct lighting shading, giving a value of 1 when a triangle is directly facing the light, and 0 when it points away from the light. Also called Lambert shading.)) value and thus how the lighting ?[terminator]((The terminator is the line at the edge of light and shadow in direct lighting:
)) looks. The texture works like so: - values over 0.5 will add to the value - values under 0.5 will subtract from the value - value of 0.5 (mid gray) won't do anything ![Stylized Threshold disabled Smoothing = 0.2](images/stylized_threshold_off.png) ![Stylized Threshold enabled  ](images/stylized_threshold_1.png) ![Stylized Threshold enabled with a different texture](images/stylized_threshold_2.png) -------------------------------------------------------------------------------------------------------------------------------- ### Diffuse Tint ((Default)) ((URP)) Adds a smooth tint to the model, based on the non-ramped diffuse term. Can be used to add subtle color fringing in the transition between highlights and shadows for example. Since it's additive, values towards black will tend to decrease the effect's intensity. ![Diffuse Tint disabled  ](images/diffuse_tint_off.png) ![Diffuse Tint with an orange color](images/diffuse_tint_on.png) -------------------------------------------------------------------------------------------------------------------------------- ### Sketch ((Default)) ((URP)) Adds a texture overlay on the unlit parts of the material, to simulate a pencil sketch effect for the shadowed areas. By default, the texture is in *screen-space* and its *offset is randomly animated*, but those properties can be changed in the [[Shader Properties]] tab. You can also change the *Sketch Color* in the [[Shader Properties]]: it is a constant black by default, but you can make it a [[Material Property / Color]] to be able to change it in the material. ![Sketch Overlay  ](images/sketch_overlay.png) ![Sketch Overlay affecting ambient](images/sketch_overlay_ambient.png) ![Sketch Threshold  ](images/sketch_threshold.png) ![Sketch Threshold affecting ambient](images/sketch_threshold_ambient.png) ![Sketch Threshold with a half-tone texture](images/sketch_threshold_halftone.png) ![Progressive Sketch  ](images/sketch_progressive.png) ![Progressive Sketch with smooth transitions](images/sketch_progressive_smooth.png) !!! INFO If using the **Sketch Threshold** effect, I recommend changing those settings in the [[Shader Properties]]: ![](images/sketch_threshold_shaderprops.png) Make sure that **Scale by Texel Size** is **enabled**, and optionally set **UV Animation** to **off**. -------------------------------------------------------------------------------------------------------------------------------- ### Shadow Line ((Default)) ((URP)) Generates a line at the intersection of the highlight and shadowed part. Can be useful to simulate a specific comic-book style for example. ![Black Shadow Line with a bright shadow color](images/shadow_line.png) ![Shadow Line on a character](images/shadow_line_cat.png) ![Shadow Line used with [Sketch Overlay](#featuresreference/stylization/sketch)](images/shadow_line_cat_sketch.png) !!! INFO This technique relies on the ?[N·L]((Dot product between the model's normals and light direction.
This is the basis for direct lighting shading, giving a value of 1 when a triangle is directly facing the light, and 0 when it points away from the light. Also called Lambert shading.)) gradient to generate the line. This means that unfortunately *it doesn't work well with the received shadows* from the shadow map texture, because it is more or less binary (a pixel is either in shadow, or it isn't) and therefore lacks any gradient-like information from which we could generate a consistent line. -------------------------------------------------------------------------------------------------------------------------------- ### Outline ((Default)) ((URP)) !!! INFO If using the *URP template*, please read the paragraph regarding additional passes in URP: [[Outline and Silhouette passes in URP]] Adds an outline around the mesh, using an additional shader pass. This uses the *"inverted hull"* method, where the base mesh is slightly inflated by its normal, rendered with front-face culling in a solid color, and then the regular shader is rendered on top of it, thus giving the illusion of an outline around the object: ![Outline Pass: Object is rendered with a solid color and front-face culling](images/outline_steps_0.png) ![Outline Pass: Mesh is inflated by its normals, which will define the outline width](images/outline_steps_1.png) ![Regular Pass: Object is regularly rendered on top of the outline pass](images/outline_steps_2.png) !!! WARNING This technique is an illusion based on the geometry, so it can break in some cases: - When using hard-edge shading, then the outline can appear broken. TCP2 provides the [Smoothed Normals Utility](documentation.html#tools/smoothednormalsutility) to try and fix this issue. - It doesn't work on planar meshes (plane, sprites, ...) - It doesn't work with transparency (either alpha blending or alpha testing/cutout) Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Blending | Defines the blending state of the outline pass, e.g. to make it semi-transparent or fully opaque. Space | Defines in which space the vertices will be inflated based on the normals └─ Object Space | Inflate the normals in object space └─ Clip Space | Inflate the normals in clip space, i.e. along the XY screen axis. This is the option to choose if you want pixel-perfect constant-size outline (see below). Outline Behind Model | Prevents the outline from showing inside the model itself. └─ Depth Buffer | Use the depth test to determine when the outline is inside the model to prevent rendering it; this is prone to sorting issues though. └─── Depth Pass | Adds an extra depth-only shader pass, to minimize the sorting issues. └─ Stencil Buffer | Use the stencil buffer to mark the base pass pixels, so that the outline isn't rendered on top of them.
This is the best method to draw the outline around the mesh, but you need a different group ID per object (see below) which can use many bits of the stencil buffer. Constant Size | Makes the outline width to be constant on screen. └─ Pixel Perfect | Sets the outline width value to be in pixels relative to the screen (needs to be in Clip Space). Z Correction | Adds parameters to offset the outline mesh on the Z axis, to try and hide some of the possible artifacts. Lighting | Adds simple lighting to the outline mesh, either per-vertex (cheaper but less precise) or per-pixel. └─ Wrapped Lighting | Wraps the lighting, similar to the [same feature](#featuresreference/lighting/wrappedlighting) on the base pass. Outline as fake rim | Offsets the outline mesh in a single direction instead of based on the normals, which will give the illusion of a crisp rim line around the model. Shadow/Depth Pass | Adds a special shadow pass that will take the normals inflation into account, so that the outline width is properly rendered in the shadows, as well as in the depth texture if it's used.
((Default)) template only. ![Black Outline  ](images/outline_cat.png) ![Outline as fake rim  ](images/outline_cat_fake_rim.png) ![Outline with variable width using the Shader Properties](images/outline_cat_width.png) You can further extend the outline effect using the [[Shader Properties]], e.g. to define parts where the outline should be hidden (set the width to 0 in those parts, using vertex colors or a texture for example). -------------------------------------------------------------------------------------------------------------------------------- ## Special Effects -------------------------------------------------------------------------------------------------------------------------------- ### Custom Time ((Default)) ((URP)) Adds a custom vector property to control time in the shaders, overriding the default `_Time` variable provided by Unity. This will affect *all* effects that use the `_Time` variable, for example: wind animation, water animation, UV animation (scrolling, distortion...). The custom property will be a `float4` named `_CustomTime`: this is the name needed to change it using scripts. By default, the Y component should be set to the actual time, and the other components are multiple of that value: ``` _CustomTime.x = time * 0.05 _CustomTime.y = time _CustomTime.z = time * 2 _CustomTime.w = time * 3 ``` This reflects the way Unity sets up its own `_Time` value, see on the Unity documentation about [built-in shader variables](+https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html). -------------------------------------------------------------------------------------------------------------------------------- ### Silhouette Pass ((Default)) ((URP)) Adds a shader pass to render a silhouette of the object when it is behind another object. The pass will only be rendered when the depth test determines that an object is in front, meaning that it will not work with objects that don't render to the depth buffer. ![Silhouette Sphere partially occluded by a cube](images/silhouette_pass.png) ![Silhouette using a dithering texture instead of a single color](images/silhouette_pass_tex.png) By default the silhouette pass is a semi-transparent color, so the alpha value will control the opacity. You can use the *Stencil Buffer* option to avoid transparency sorting issues for complex meshes. ![Silhouette Cat with blue semi-transparent color](images/silhouette_pass_cat.png) ![Silhouette Cat fixed with Stencil Buffer option](images/silhouette_pass_cat_stencil.png) !!! INFO If using the *URP template*, please read the paragraph regarding additional passes in URP: [[Outline and Silhouette passes in URP]] -------------------------------------------------------------------------------------------------------------------------------- ### Wind Animation ((Default)) ((URP)) Provides options to add some simple vertex movement to simulate wind. Wind Type | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Sine Wave | Calculate the movement using sine waves. The number of sine waves will define the pseudo-randomness: 1 sine wave will make animation very regular, whereas 6 sine waves will give a pseudo-random look. Look into the [[Shader Properties]] to change the various values related to the sine functions. Scrolling Texture | Use a scrolling texture as the wind influence. By default, the texture will be mapped to the vertex world position on the XZ plane. You would generally use a repeating noise texture as the wind source. The source texture and its scrolling UV calculations can be modified in the [[Shader Properties]]. ![Sine wind animation on grass meshes](images/wind_animation.webm) There are various properties that will control the wind movement in the [[Shader Properties]]. By default, vertex colors are used: - the **red vertex color** will be the wind vertex mask, it will define which vertices are affected or not by the movement - the **green vertex color** will be a per-vertex time offset; it's a good way to simulate organic swaying movement or to add a bit more movement variety to the different parts of the same mesh ![Red vertex color on this grass mesh](images/wind_vertex_colors_red.png) ![Green vertex color on this grass mesh](images/wind_vertex_colors_green.png) !!! INFO Here the red and green vertex colors are very similar, but this is not always the case! -------------------------------------------------------------------------------------------------------------------------------- ### Dissolve Map ((Default)) ((URP)) Creates a texture-based dissolve effect, driven by a property in the shader (by default a float from 0 to 1). Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Dissolve Map | Enables the effect, but doesn't do anything by itself: you have to use it along "Alpha Testing" and/or "Gradient Ramp" Alpha Testing | Enables alpha clipping for the dissolved part, i.e. make the dissolved part transparent. Gradient Ramp | Enables coloring for the dissolved part. It will use a 1D texture by default, but you can also change that to a simple color in the [[Shader Properties]] interface. ![Dissolve with color gradient](images/dissolve_gradient.png) ![Dissolve with alpha clipping](images/dissolve_alpha.png) ![Dissolve with color & alpha clipping](images/dissolve_alpha_gradient.png) ![Different gradient width and gradient texture](images/dissolve_alpha_gradient_2.png) ![Dissolve Value animated  ](images/dissolve_animation.webm) -------------------------------------------------------------------------------------------------------------------------------- ### Vertical Fog ((Default)) ((URP)) This acts like the Unity fog, but is based on the vertices Y position in world space instead of their depth from camera. This effect can be combined with Unity's built-in fog. Parameter | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Use Alpha for Transparency | The alpha value of the fog color will define its opacity on the object. Use Lighting Settings Color | The fog color will be defined by the value set in the [Lighting Window](+https://docs.unity3d.com/Manual/lighting-window.html). Color Interpolation | Defines how the fog color will be interpolated from no fog to full fog, either linearly or smoothly. Relative to Camera | The value will be dependent on the camera Y position, so moving the camera will affect the fog on objects. ![Blue Vertical Fog with Linear interpolation](images/vertical_fog.png) ![Blue Vertical Fog with Smooth interpolation](images/vertical_fog_smooth.png) -------------------------------------------------------------------------------------------------------------------------------- ### Water Effects ((Default)) ((URP)) Provides options that can help making stylized water/liquids shaders (_but you are free to use them for anything else if you want!_). ![Water shader example using: - vertex waves - UV distortion - depth-based color - depth and vertex color-based foam](images/water_animation.webm) ![Screenshot of the same effect in case the video doesn't work in your browser    ](images/water_animation_screenshot.png) #### Vertex Waves Generates wave animation by displacing vertices using up to 8 sine functions mixed together, to simulate some randomness. Vertex Waves | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Sine Functions Count | The number of sine functions to use: the more there is, the more the waves animation will seem random World-based Position | Use the world position as the sine offset. Useful if you want to tile multiple different meshes together. It is recommended to set the [texture UV to World Position](#shaderproperties/implementationsreference/materialproperty/.../materialproperty/texture) as well so that texture coordinates will tile in world-space. Displacement Axis | Displace vertices along the defined fixed axis (in object space). └─ Follow Mesh Normals | Displace vertices along their normal axis instead of a fixed axis. Calculate Normals | Procedurally calculate normals based on the sine functions using derivatives (for planar meshes). #### Depth-based Effects Features that use the *Depth Texture* in order to achieve various visual effects. The Depth Texture needs to be enabled for the Camera for these effects to work: - for the *Built-in Render Pipeline*, you can add the script `TCP2_CameraDepth` to ensure it will be generated for this camera - for the *Universal Render Pipeline*, the option needs to be enabled in the URP asset Note that the object itself needs to be excluded from the Depth Texture for the effects to work properly: - for the *Built-in Render Pipeline*, make sure that the shadow pass isn't added (as it is used for the depth texture as well) - for the *Universal Render Pipeline*, the "Depth Only" pass will automatically be disabled in the shader Effect | Description ------------------------------|------------------------------------------------------------------------------------------------------------------------------- Depth-based Color | Override the albedo color with a new one based on the difference between the object's depth and the surrounding depth (through the depth texture). Depth-based Foam | Adds an animated foam effect on top of the water surface, based on the "immersed" objects' depth. └─ Foam Texture Animation | Automatically handle the foam texture animation in the shader. It will sample the foam texture twice with different scrolling speeds to simulate a procedural foam effect, based on a grayscale noise texture. Disable this if you want to add your own procedural logic to the foam texture. └─ Foam Smoothness | Control the smoothness of the foam effect (using a `smoothstep` function, else a `step` function is used). └─ Hide on Backfaces | Prevents the foam from showing on the backfaces if you have double-sided rendering enabled. Depth-based Transparency | Multiply the alpha value with the depth difference, so that "immersed" objects' can appear slightly visible in the water. Depth View Correction | Improves the depth calculation visually at grazing angles in some cases. -------------------------------------------------------------------------------------------------------------------------------- !!! WARNING In *URP*, [[Depth-Based Effects]] will only work on "Opaque" materials *if MSAA is enabled*, because a depth prepass is done in that case thus making the depth texture available to the shaders when rendering the opaque materials down the line. *If MSAA is disabled*, then make sure that the water material has a *queue of 2500 or higher*, so that it's rendered as part of the "Transparent" materials (even if it isn't visually transparent). ## Transparency/Blending -------------------------------------------------------------------------------------------------------------------------------- ### Auto Optional Transparency ((Default)) ((URP)) Automatically handle alpha blended transparency as an option in the material: you can choose between *opaque*, *fade* and *transparent* render modes. Relevant options will automatically be set according to the selected mode (blending, culling and depth writing). This is similar to how the [Hybrid Shader](documentation.html#hybridshader/optionsreference/transparency) handles transparency. Example from the Hybrid Shader 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)_ ![Opaque](images/hybrid_shading_opaque.png) ![Fade](images/hybrid_shading_fade.png) ![Transparent](images/hybrid_shading_transparent_m.png) -------------------------------------------------------------------------------------------------------------------------------- ### Blending / Blend Operation ((Default)) ((URP)) Enable this to control the [shader blending state](+https://docs.unity3d.com/Manual/SL-Blend.html). A few presets are available by default, or you can use the custom option to define your own values. The *Dithered Shadows* option will render a dithered version of the material to simulate transparency in the shadow map, similarly to how the Standard shader does. It works best when using *Soft Shadows*, with the *Alpha Blending* or *Alpha Blending Premultiplied* modes. ![Alpha Blending](images/blending_alpha.png) ![Additive Blending](images/blending_additive.png) ![Multiplicative Blending](images/blending_multiplicative.png) -------------------------------------------------------------------------------------------------------------------------------- ### Depth pre-pass ((Default)) Adds a shader pass that only write to the Depth Buffer. This is generally used to avoid transparency sorting issues for complex meshes: ![Alpha Blending with and without depth pre-pass](images/depth_prepass.png) -------------------------------------------------------------------------------------------------------------------------------- ### Alpha Testing ((Default)) ((URP)) Enables per-fragment transparency, i.e. a pixel will either be fully opaque or fully transparent, based on the alpha value. Also known as *"Cutout"* in Unity shaders. This is the option to prefer when it is needed for the shader to write to the depth buffer, for proper sorting or inclusion in some post effects (e.g. depth of field). Parameter | Description -------------------------------------|--------------------------------- Alpha to Coverage | Enables multi-sampling anti-aliasing (MSAA) for the cutout parts using [alpha to coverage](+https://docs.unity3d.com/2019.3/Documentation/Manual/SL-Blend.html). └─ Disable alpha sharpening | Disables the needed calculation to make alpha to coverage work properly, as [extensively explained by Ben Golus here](+https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f).
This option should remain disabled unless you have a good reason to do it! ![Alpha Testing](images/alpha_testing.png) -------------------------------------------------------------------------------------------------------------------------------- ## Shader States Enable these options to control various fixed shader states. State | Description -------------------------------------|--------------------------------- Face Culling (double-sided) | Controls front and back faces culling in the GPU. By default, back faces are hidden.
Set the value to `Off` to get double-sided rendering. └─ Backface Lighting | Will modify that normals for back faces so that lighting and other effects look accurate. Depth Write | Controls writing to the depth buffer. Depth Test | Controls test against the depth buffer. This is how the GPU determines whether a face has to be rendered or not, based on its depth compared to the currently existing depth. Stencil | Enable stencil [[shader properties]] to customize the [stencil state](+https://docs.unity3d.com/Manual/SL-Stencil.html). Shader Target | Define to which shader model version the shader should compile to.
Increase that number if you get compile errors such as `Not enough instructions/interpolators...`, if your platform supports it. -------------------------------------------------------------------------------------------------------------------------------- ## Options Various options related to Unity's rendering pipelines. These usually translate to [surface shader optional parameters](+https://docs.unity3d.com/Manual/SL-SurfaceShaders.html) for the ((Default)) template. -------------------------------------------------------------------------------------------------------------------------------- ## Third-Party Plugins Add support to your shader for third-party packages from the Unity Asset Store. - [VertExmotion](+http://www.kalagaan.com/#vertexmotion) - [Curved World](+https://assetstore.unity.com/packages/vfx/shaders/curved-world-2020-173251) _(**Curved World** and **Curved World 2020** are both supported)_ !!! INFO 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! Material Layers =============== About ----- The Material Layers system allow you to define additional layers for your material. Once that layer is setup, you can define which properties should be differentiated for that layer, through the [[Shader Properties]] interface. This is a powerful system that can add many effects to a single material, from simple texture-based terrain maps to normal-based snow accumulation, position-based moss, or a dirt layer driven by both normal and a noise map. How it works ------------ Each layer has a *Source* Shader Property that will define where it should appear: white _(value = 1)_ will entirely show the layer, black _(value = 0)_ will hide it, and in-between values will make a transition between the two. Using the [[Shader Properties]] system, this source can be fetched or calculated from various sources: a texture map, the local or world-space normal or position... A few presets are available to easily get started. Once a layer is setup, you need to define which Shader Properties will actually be blended based on it. You can optionally toggle the *Contrast* and *Noise* properties: those options will automatically add properties that can modulate the source mapping directly from the Material Inspector. ![Source example: a simple gradient](images/matlayers_example_0.png) ![The result when blending two Albedo textures](images/matlayers_example_1.png) ![Contrast applied  ](images/matlayers_example_2.png) ![Noise with a Perlin texture applied  ](images/matlayers_example_3.png) ![Using the height-map of the albedo texture can give height-based blending](images/matlayers_example_4.png)
**Here are the same examples but using a texture as the layer source instead:** ![Source Texture](images/matlayers_texture_0.png) ![Raw layer result](images/matlayers_texture_1.png) ![Contrast applied](images/matlayers_texture_2.png) ![Perlin Noise](images/matlayers_texture_3.png) ![Height-map Noise](images/matlayers_texture_4.png) Interface --------- Move your mouse on the different elements to learn about the interface. ### Material Layers tab
Select the **Material Layers** tab to view this interface.
These buttons allow you to **remove** this Material Layer, or to **add** a new one.
This is the internal ID of this Material Layer.
This ID will be replaced by the name for labels and variable names in the final shader.
The name of the layer (note: this affects the property names by default, so be careful if you change it afterwards: you might lose texture references in your materials).
Enable the Noise property: it will affect the layer source to add an extra level of detail.
Enable the Contrast property: it will add a way to adjust the contrast of the layer source easily from the material.
Load a preset for the Layer Source (note: this will entirely replace the Layer Source implementations).
These are the Layer's [[Shader Properties]]: you can modify their implementations like any other Shader Property (here this is the Layer Source).
Material Layers can use [[Custom Material Properties]], so their interface is replicated here.
A typical example would be to use a single texture as a source, where each R,G,B channel is the source for 3 different material layers.
### Shader Properties tab You can enable layers for any Shader Property, here's an example with the Albedo property:
Select the **Shader Properties** tab to view all the properties, and be able to toggle layers for any of them.
This icon indicates that this property uses at least 1 material layer. Moving the mouse over will show a tooltip telling which layers are used exactly.
This is a convenient way to view which Shader Properties are using Material Layers when they are all folded.
When at least 1 Material Layer has been defined, this small menu will show for each property. Select a Material Layer here to view its options for this property.
Enable the Material Layer for this Shader Property: this means that this property will be blended between two values, according to the Material Layer source.
Disable this option to be able to edit the implementations of the layer version of the Shader Property.
Here it is disabled and the layer property is now a **Color** instead of a **Texture**: the shader is thus more optimized since a color is much faster to sample than a texture.
See **"Same as Base Layer" option** below for more details.
Tip: no need to change the label here, even though it is the same as the base property, because all properties for a single layer will be regrouped under the same section in the material inspector!
### Same as Base Layer option When a *Shader Property* uses a *Material Layer*, a *copy* of it will be made, and then the shader code will blend between those two properties according to the layer source. By default, the copied Shader Property will use the same implementations of the base Shader Property, with only its variable name changing if it's a Material Property. You can override that behavior by disabling the "*Same as Base layer*" option, and use any other implementations for the copied property. For example, the base property could be a *Texture*, and the copied one a simple *Color*, as in the example above. Or both could be textures, but the layered one could use *UV Scrolling*. ### A note on normal-based layers with normal maps When using normal-based layers (e.g. procedural snow based on upward normals), you get normals from the base normal map. In the *Features* tab, *Surface* section, under the [Normal/Bump Map](#featuresreference/surface/normal/bumpmap) feature, you have the *Sample Normal Map first* option. Enabling it will allow the *Material Layers* to use the normal from the normal map, instead of from the vertices: ![Left: vertex normals / Right: normal map You can see that the rocks get a bit of snow on them when the normal map is used.](images/matlayers_normalmap.png) Code Injection ============== About ----- If you need even more control on the output shader, you can use the *Code Injection* system to add arbitrary code in various places throughout the shader. It adds extra flexibility in addition to the [[Shader Properties]] system, and can also be used as a replacement if you are comfortable enough with shader code and don't want to deal with the Shader Properties UI. The system requires you to prepare your own .cginc or .hlslinc file formatted with special comments. !!! WARNING This system is currently experimental! Please [send me](#contact) any feedback you may have on it: bug report, feature suggestion, usability... Thanks! Example ------- You can find the *"TCP2 Code Injection Example.cginc"* example file in the demo folder: - Go to the "CODE INJECTION" tab - Click on "Add Injected File" - Select "TCP2 Code Injection Example.cginc" as the injected file - The UI will update with information about auto-injected blocks - (Optional) Look for the `pulseSpeed` custom Shader Property and expand it: it is a constant by default but you can change it into a Material Property for example, like all [[Shader Properties]] - Generate a shader: a new injected property will be available in the material that will add a pulsing color to the albedo The "*TCP2 Code Injection Example.cginc*" file includes comments that describe the whole format of the code injection files. Please take a look at it to figure out how to inject your own code. Interface --------- Move your mouse on the different elements to learn about the interface:
Go to the Code Injection tab here.
Enable this option to add comments identifying each injection point in your .shader file.
Comments will have the format: `// Injection Point : NAME`
Removes that injected file and all injected blocks associated with it.
Select the injection file here, containing the code blocks in the proper format (see the "*TCP2 Code Injection Example.cginc*" file for an example).
Add a new injected block here: a menu will show to first select an injection point among those available in the current template, and then an available block to inject.
It's up to you to handle the compatibility between the injected block and the injection point (e.g. proper variables names if you are reusing existing ones).
This is a "Replace" block that can replace any text in the final shader with something else.
It can't be deleted but can be disabled like other blocks.
This is the name of the injection point for this block.
This is the name of the injected block for this point, as described in the source file.
Remove this injected block.
Reorder the injected blocks here. This is mostly useful if you are injecting multiple different blocks at the same injection point, to ensure they are in the correct order.
Injected blocks that contain custom [[Shader Properties]] will show as a foldout, to reveal their shader property(ies).
A custom `float` Shader Property as described in the source file.
It will be set as a constant by default, but can be changed to another implementation (a `Material Property/Range` for example so that the end user can change its value in the material inspector).
Add another injected file.
You can disable any block here, if you want to use a single Code Injection file for multiple shaders for example
This is the optional information for the "Replace" block defined in the injection file
Shader Properties Tutorials =========================== These tutorials can help you understand the process and possibilities of modifying [[Shader Properties]] to customize your generated shader. For clarity they are regrouped in an external page: [Shader Generator 2 Tutorials](+tutorials). Tutorials list: Quick tips: - [Add UV Scrolling to a Texture]("tutorials.html#adduvscrollingtoatexture") - [Use Non-Repeating Tiling]("tutorials.html#usenon-repeatingtiling") - [Add Hue/Saturation/Value control to any color]("tutorials.html#addhue/saturation/valuecontroltoanycolor") Step-by-step: - [Use Vertex Colors as Albedo]("tutorials.html#usevertexcolorsasalbedo") - [Add a detail texture (simple)]("tutorials.html#addadetailtexture(simple)") - [Add a detail texture (advanced)]("tutorials.html#addadetailtexture(advanced)") - [Create a hologram shader]("tutorials.html#createahologramshader") - [Create an advanced dissolve shader]("tutorials.html#createanadvanceddissolveshader") Contact ======= If you have questions, bug reports or suggestions please contact me by email at: jean.moreno.public+unity@gmail.com