The half vector is a vector between the viewing direction and the light source we can obtain this by summing those two vectors and normalizing the result. The strength of the specular reflection is defined in Blinn-Phong as the dot product between the normal of the surface and the half vector. This calculation takes in two properties from the surface, a specular color that tints the reflection, and a glossiness that controls the size of the reflection. We'll now implement the specular component of Blinn-Phong. This is the direction from the current vertex towards the camera. We will calculate the world view direction in the vertex shader and pass it into the fragment shader. This reflection is view dependent, in that it is affected by the angle that the surface is viewed at. Specular reflection models the individual, distinct reflections made by light sources. However, in between that range it will smoothly blend between 0 and 1. When NdotL is above 0.01 or below 0 it returns one and zero like before, respectively. Our lower and upper bounds, 0 and 0.01, are very close together-this helps maintain a relatively sharp, toony edge. float lightIntensity = smoothstep(0, 0.01, NdotL) This makes it ideal for smoothly blending values, which is how we'll use it to blend our light intensity value. Smoothstep is not linear: as the value moves from 0 to 0.5, it accelerates, and as it moves from 0.5 to 1, it decelerates. The values are mapped to the greyscale background, as well as the curves in red. It is a fixed4 declared in the Lighting.cginc file, so we include the file above to make use of the value.Ĭomparison between smoothstep (left) and a linear function (right). _LightColor0 is the color of the main directional light. We multiply our existing lightIntensity value and store it in a float4, so that we include the light's color in our calculation. Return _Color * sample * (_AmbientColor + light ) Add below the lightIntensity declaration.įloat4 light = lightIntensity * _LightColor0 Add below the existing #include "Unit圜G.cginc" When it comes to defining colors that represent lights, I like to allow them to extend to the HDR range, just like any other light in Unity can. While the screen cannot render colors outside the 0.1 range, the values can be used for certain kinds of rendering effects, like bloom or tone mapping. Colors normally have their RGB values set between 0 and 1 The attribute specifies that this color property can have its values set beyond that. Return _Color * sample * (_AmbientColor + lightIntensity) Matching variable, add above the fragment shader. We will model it as a light that affects all surfaces equally and is additive to the main directional light. For now, we will add ambient light.Īmbient light represents light that bounces off the surfaces of objects in the area and is scattered in the atmosphere. Also, the edge between dark and light looks a bit sharp, but we'll deal with that later. This looks good, but the dark side is too dark right now it is completely black. NdotL is in the -1.1 range, so we transform it to be 0.1, and invert it so that the most illuminated surfaces map to the left of the texture, and the darkest to the right. We then sample the ramp texture with NdotL transformed to a UV coordinate that maps to the ramp, lightest to darkest. The simplest way to implement this is with a ramp texture. To render more than two bands of shading, we will need a function with more than two steps. Right now our line of code above using the ternary operator is a step function with two steps, light and dark. ![]() The amount of light is proportional to the direction, or normal of the surface with respect to the light direction. ![]() ![]() The first step is to calculate the amount of light received by the surface from the main directional light. To calculate our lighting, we will use a common shading model called Blinn-Phong, and apply some additional filters to give it a toon look. The first line requests some lighting data to be passed into our shader, while the second line further requests to restrict this data to only the main directional light. Add the following code at the top of the Pass, just after its opening curly brace. We will set up our shader to receive lighting data. However, as our shader will only interact with a single directional light, it will not be necessary to use surface shaders. Surface shaders use code generation to automate the object's interaction with lights and global illumination. When writing shaders in Unity that interact with lighting it is common to use Surface Shaders.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |