"Unity Shaders" Diffuse shading--create a custom diffuse lighting model (diffuse illumination models)

Source: Internet
Author: User
Tags pow

This series focuses on Unity Shaders and Effects Cookbook (thanks to the author of the book), plus a bit of personal understanding or outreach.

Here are all the illustrations of this book. Here is the code and resources required for this book (you can also download it from the website, of course).

========================================== Split Line ==========================================



In the previous article, we learned how to use the properties variables that you define in surface shader (this is the surf function). In previous studies, we were actually using Unity's built-in diffuse Lighting model, the diffuse light. This time, we'll learn how to make unity render with our own defined lighting model.


preparatory work
Use the shader code at the end of the previous article.

Shader "Custom/basicdiffuse" {Properties {_emissivecolor ("emissive color", color) = (1,1,1,1) _ambientcolor ("AMB Ient color ", color) = (1,1,1,1) _myslidervalue (" This is a Slider ", Range (0,10)) = 2.5} Subshader {Tags {" Rendert Ype "=" Opaque "} LOD cgprogram #pragma surface surf Lambert//we need to Decla
        Re the properties variable type inside of the//cgprogram so we can access it value from the properties block.
        FLOAT4 _emissivecolor;
        FLOAT4 _ambientcolor;
        
        float _myslidervalue;
        struct Input {float2 Uv_maintex;
        
        };
            void Surf (Input in, InOut surfaceoutput o) {//we can and use the properties values in our shader
            FLOAT4 C;
            c = Pow ((_emissivecolor + _ambientcolor), _myslidervalue);
            O.albedo = C.rgb;
        O.alpha = C.A;
 } ENDCG} FallBack "Diffuse"}

Implement
Change line 11th of the above code, #pragma surface surf Lambert Line, to the following code:
#pragma surface surf Basicdiffuse

Add the following function to Subshader (the position needs to be below #pragma):
        Inline Float4 Lightingbasicdiffuse (surfaceoutput s, fixed3 lightdir, fixed atten)
       	{
       	  	float diflight = max (0, Dot ( S.normal, Lightdir));
       	  	Float4 Col;
       	  	Col.rgb = S.albedo * _lightcolor0.rgb * (diflight * atten * 2);
       	  	COL.A = S.alpha;
       	  	return col;
	}

Save and go to Unity to view the compilation results. Once unity compiles successfully, you will find that material does not have any visual changes. Because it's just the surface Lighting model--lambert from Unity, it's replaced with our custom lighting model--basicdiffuse.
explain
#pragma surface will tell shader directly which lighting model to use for the calculation. When we initially created a shader, Untiy gave us a default lighting model called Lambert (defined in Lighting.cginc). So we can start with this default model for rendering. And now, we tell shader, hey, use a light model called Basicdiffuse to render to me oh. In order to create a new lighting model, we need to declare a new lighting model function. For example, we declare basicdiffuse and define a function called Lightingbasicdiffuse, and as you can see, the relationship between the two is lighting< custom lighting model name >. There are three types of light model functions to choose from:
Half4 Lightingname (surfaceoutput s, Half3 lightdir, half atten) {}

This function is used for forward rendering (forward rendering), but it is not necessary to consider the view direction (viewing angle).
Half4 Lightingname (surfaceoutput s, half3 Lightdir, Half3 viewdir, half atten) {}

This function is used for forward rendering (forward rendering) and requires consideration of the view direction (viewing angle).
Half4 Lightingname_prepass (surfaceoutput s, Half4 light) {}

This function is used when you need to use defferred rendering (deferred rendering). Observe the lighting model functions we define. The dot function is a CG built-in mathematical function that can be used to compare the direction of two vectors in space. If the two parameter vectors are all unit vectors (in general), 1 means that the two vectors are parallel but in the opposite direction, and 1 means that the two vectors are parallel and in the same direction, and 0 means that the two vectors are perpendicular. To complete the illumination model function, we also used a unity-supplied data-a variable s of type Surfaceoutput. We will be S. Albedo (output from the surf function) and _LIGHTCOLOR0.RGB (Unity provided) multiply the result by (Diflight * atten * 2) and finally output as a color value. Here, you may not understand the Lightingbasicdiffuse code. Let's talk about my understanding. The first is the parameter. S is the output of the previous surf function.
        void Surf (Input in, InOut surfaceoutput o)
        {
            //we can and use the properties values in our shader
            float4 c;< C4/>c =  Pow ((_emissivecolor + _ambientcolor), _myslidervalue);
            O.albedo = C.rgb;
            O.alpha = C.A;
        }
It can be seen from the surf function that the albedo (reflectivity) and alpha (transparency) of s are computed.
The Lightbasicdiffuse function will output a color value and a transparency value for a point on your surface. So lightdir the direction of the light that should be lit. The atten shows the attenuation rate of the light. The first line of code in the lighting model function calculates the illumination value reaching that point by dot function and Max function (since the DOT function's two parameters are unit vectors, it can also be interpreted as the cosine of the angle of the incident light, the greater the angle, the smaller the cosine, the less light entering the human eye, and the darker the object looks). Since the light is likely to be injected from the opposite direction, the value obtained by dot may be negative. If you don't use Max to limit it, you'll get unintended results, such as full black. Next calculate the color value col. The RGB of Col is calculated from three parts: the first part is the reflectivity of surface itself, which is well understood, because the greater the reflectivity, the more light entering the human eye, the brighter the color, and the second is the _LIGHTCOLOR0.RGB. _lightcolor0 is a unity built-in variable that we can use to get the color of the light source in the scene, and finally the product of the light and decay ratios obtained from the first step. Careful children's shoes can be found, here is multiplied by a multiple of 2. As I guess, this is just a self-modifying, as needed. For example, without a multiplier of 2 o'clock, the effect is as follows:

Multiply by multiples of 2 after the effect is as follows:

Concluding remarks
For more information on surface shader lighting model function parameters, see the official Unity documentation.
Hoo, this time it's here.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.