Unity's Shader study notes (iv)--specular reflection

Source: Internet
Author: User
Tags mul pow reflection

But we will find that the back surface of the object is an all-black color, the real life of the object's back surface is not all black, but can see the approximate shape of the object, not all black, before the use of the method is Lambert lighting model. To achieve this, it is necessary to use the semi-Lambert illumination model to achieve

semi-Lambert illumination model
Diffuse = Direct light color * (cosθ*0.5+0.5)
Lambert Lighting Model
Diffuse = Direct light color * MAX (0,cosθ) θ refers to the angle between the light direction and the normal direction

Semi-Lambert light effect as shown:

High Light reflection calculation (Blinn illumination model) specular = Direct light *pow (max (cosθ,0), highlight parameter)

Explanations for the above formula:
Θ refers to the angle between the reflected light direction and the reflection point to the camera direction.
The second side of the POW means cosθ 's high-light parameters.
Max (cosθ,0) is to prevent the surface of the object, if the highlight parameter is even, then the last value will be changed from negative to positive

The sample code used is as follows

properties{_diffuse ("Diffuse color", color) = (1,1,1,1) _gloss ("Gloss", Range (8,200)) = ten} Su

                bshader{pass{tags{"Lightmode" = "forwardbase"} Cgprogram              #include "lighting.cginc"//unity system-defined classes can use some built-in variables to simplify calculation operations//_lightcolor0 The variable represents the color of the first direct light//_WORLDSPACELIGHTPOS0 the variable represents the position of the First direct light (world coordinates)//UNITY_LIGHTMODEL_AMB Ient this variable represents the ambient light of the system #pragma vertex vert #pragma fragment Frag fixed4 _diff
                Use

                Half _gloss;   struct A2V {float4 vertex:position;//The system automatically passes vertex coordinates to vertex float3 normal:normal;

                The system automatically passes the normals into the variable normal};
                    struct V2F {float4 position:sv_position;
                Fixed3 Color:color;



                }; v2f Vert (a2vx) {v2f F; 
                    UNITY_MATRIX_MVP This matrix is used to convert a coordinate from model space to clipping space f.position = Mul (UNITY_MATRIX_MVP, X.vertex);

                    Fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);


                    Fixed3 ambient = Unity_lightmodel_ambient.rgb;
                    Fixed3 Normaldir = Normalize (Mul (X.normal, (float3x3) unity_worldtoobject)); For the time being, the alpha attribute is not considered fixed3 diffuse = _lightcolor0.rgb*max (dot (Lightdir, Normaldir), 0) *_diffuse.rgb;//get diffuse The color of the shot//Calculate high light//Calculate reflection light angle fixed3 Reflectdir = Normalize (refle
                    CT (-lightdir,normaldir));

                    Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). xyz);

                    Fixed3 specular = _lightcolor0.rgb*pow (max (dot (Reflectdir, Viewdir), 0), _gloss);
                    F.color = Diffuse +ambient+ specular;return F; } fixed4 Frag (v2f f): sv_target{//output computed color values to objects in the field of view return fix
                Ed4 (F.color, 1); } ENDCG}}

The code has a reflect method, which is used to calculate the angle between the reflected light and the normal of the incident light.
The first parameter in the function reflect is the incident light vector, the second one is the normal vector, and the angle between the reflected light vector and normal is calculated by the angle between the incident light vector and the normal, so the incoming light needs to be flipped, otherwise the incident light and the normal angle is (180-( The angle of the incident light vector and the normal vector) °. the angle of the vertex to the field of view is then obtained by the variable defined by the macro. Finally, just use the formula to calculate.
High-gloss effect as shown:

The area range of the highlight is determined by the specular reflectance factor, which defines a parameter for controlling the highlight range

_gloss ("Gloss", Range (8,200)) = 10

and used in the formula, and finally can be free to control the size of the high-light range.

blinn-phone Illumination Model : Improvement of Blinn illumination model
Calculation formula modified to: specular = Direct light *pow (max (cosθ,0), highlight parameter)

Θ here refers to the angle between the normal and x x is the direction of the light and the angle of the camera's viewing direction (middle line)
As shown in figure

So in the end as long as the vert inside the code to make the following changes.

v2f Vert (a2v x) {v2f F; 
                    UNITY_MATRIX_MVP This matrix is used to convert a coordinate from model space to clipping space f.position = Mul (UNITY_MATRIX_MVP, X.vertex);

                    Fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);


                    Fixed3 ambient = Unity_lightmodel_ambient.rgb;
                    Fixed3 Normaldir = Normalize (Mul (X.normal, (float3x3) unity_worldtoobject)); For the time being, the alpha attribute is not considered fixed3 diffuse = _lightcolor0.rgb*max (dot (Lightdir, Normaldir), 0) *_diffuse.rgb;//get diffuse The color of the shot//Calculate high light//calculate the angle of reflection light//fixed3 Reflectdir = normalize (ref
                    Lect (-lightdir,normaldir));

                    Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). xyz);
                    Split Line Fixed3 Halfdir = normalize (Viewdir + lightdir); Control the highlight color fixed3 specular = _specUlar * _LIGHTCOLOR0.RGB*POW (max (dot (Normaldir, Halfdir), 0), _gloss);
                    F.color = Diffuse +ambient+ specular; 
                return F; } fixed4 Frag (v2f f): sv_target{//output computed color values to objects in the field of view return fix
                Ed4 (F.color, 1); } ENDCG}

This b-p model is optimized compared to the previous Blinn illumination model, where we will see a highlight point on the back surface, but not in b-p

Some common functions and macro definition variables in Unitycg.cginc

_lightcolor0              the variable represents the color of the first direct light

_worldspacelightpos0      The variable represents the position of the First direct light (world coordinates)

Unity_lightmodel_ AMBIENT  the variable represents the system's ambient light
_world2object This matrix is used to convert a direction from world space to model space
unity_lightmodel_ambient to obtain ambient light

    // Camera orientation (angle of view)
    float3 Worldspaceviewdir (float4 v)      gets (World space) from this point to the camera's viewing direction based on the vertex coordinates in the model space
    FLOAT3 Unityworldspaceviewdir (float4 v) vertex coordinates in world space = = "World space from this point to the camera's viewing direction
    float3 Objspaceviewdir (float4 v)        Vertex coordinates in model space = = "model space from this point to the camera's viewing direction
    //light source Direction
    Float3 Worldspacelightdir (float4 v)     the vertex coordinates in the model space = =" In world space from this point to the direction of the light source
    float3 Unityworldspacelightdir (float4 v)    vertex coordinates in world space = = "From this point to the direction of the light source in world space
    FLOAT3 Objspacelightdir (Float4 v)   the vertex coordinates in model space = = "In model space from this point to the direction
    //direction of the light source
    float3 Unityobjecttoworldnormal ( FLOAT3 norm) The normal direction model space = = "World Space
    float3 Unityobjecttoworlddir (float3 dir) to the direction model space =" World Space
    FLOAT3 Unityworldtoobjectdir (FLOAT3 dir) take the direction world space = "model space"

Use the built-in function method to make the code easier to write
The code in the program needs to be

Fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);

Replaced by

Fixed3 Lightdir = Normalize (Worldspacelightdir (Mul (X.vertex, Unity_worldtoobject)). xyz);
Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). xyz);

Replaced by

Fixed3 Viewdir = Normalize (Unityworldspaceviewdir (Mul (X.vertex, (float3x3) unity_worldtoobject). xyz));

The calculation of normals is replaced directly by the
Direct use of a method to convert from model space to world space

Fixed3 Normaldir = Normalize (Unityobjecttoworldnormal (x.normal));

Replace the modified code as follows

v2f Vert (a2v x) {v2f F; 
                    UNITY_MATRIX_MVP This matrix is used to convert a coordinate from model space to clipping space f.position = Mul (UNITY_MATRIX_MVP, X.vertex);
                    A point of light source//fixed3 Lightdir = normalize (_WORLDSPACELIGHTPOS0.XYZ);
                    Fixed3 Lightdir = Normalize (Worldspacelightdir (Mul (X.vertex, Unity_worldtoobject)). xyz);

                    Fixed3 ambient = Unity_lightmodel_ambient.rgb;
                    The direct use method transforms from model space to world space fixed3 Normaldir = normalize (Unityobjecttoworldnormal (x.normal)); For the time being, the alpha attribute is not considered fixed3 diffuse = _lightcolor0.rgb*max (dot (Lightdir, Normaldir), 0) *_diffuse.rgb; Get diffuse color//Calculate high light//calculate reflected light angle//fixed3 Reflectdir = Normali
                    Ze (Reflect (-lightdir,normaldir)); Fixed3 Viewdir = Normalize (_worldspacecamerapos.xyz-mul (X.vertex, (float3x3) unity_worldtoobject). XYZ);
                    Fixed3 Viewdir = Normalize (Unityworldspaceviewdir (Mul (X.vertex, (float3x3) unity_worldtoobject). xyz));
                    Split Line Fixed3 Halfdir = normalize (Viewdir + lightdir);

                    Control the highlight color fixed3 specular = _specular * _LIGHTCOLOR0.RGB*POW (max (dot (Normaldir, Halfdir), 0), _gloss);
                    F.color = Diffuse +ambient+ specular; 
                return F; }

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.