Lighting models other than Lambert - BlinnPhong, Standard, StandardSpecular

So far we've just been using the Lambert lighting model in our shaders. This is all well and good for simple non-shiny surfaces - but if we do want proper specular highlights, or more physical accuracy we'll want to use some other lighting models.

Blinn Phong

First up is BlinnPhong. To use it, change the usual #pragma statement to

    #pragma surface surf BlinnPhong

Also, in the Properties block we now will be using a few more variables - 

Properties{

    _Color("Colour",color)=(1,1,1,1)

    _SpecColor("Specular Colour",color)=(1,1,1,1)

    _Spec("Specular",Range(0,1))=0.5

    _Gloss("Gloss",Range(0,1))=0.5

}

The _Spec/Specular controls the coverage of the highlight & the _Gloss/Gloss controls the strength of the highlight. We do not have to define the _SpecColor within the SubShader block -Unity already has this built in for some reason & might complain if you do redefine it.

Datatypes are - Float4/Fixed 4 for Color, Half for Spec and Fixed for Gloss.

In the "surf" function, you will want to output o.Albedo, o.Specular and o.Gloss.

 

Standard Material

Next up is the Unity Standard lighting model, which is based on PBR - physically based rendering. This one uses the "metallic" property to deal with shininess. This means it is more concerned with metallic (wow much surprise) types of surfaces - usually a coloured metal will have a highlight that is tinted the same colour as the metal itself - eg. gold will have a yellowish highlight to it - copper a reddish brown etc. 

Here's the struct for the Standard to show the datatypes

struct SurfaceOutputStandard

    fixed3 Albedo;

    fixed3 Normal;

    half3 Emission;

    half Metallic; //0 is non metal, 1 metal

    half Smoothness;//0 is rough, 1 smooth

    half Occlusion;

    fixed Alpha;

};

We don't have to rewrite the lighting model to use it, we just have to make some changes, as we did with the BlinnPhong.

 First up - #pragma surface surf Standard

 Next we might want to add some metallic variables to our Properties

_MetallicTex("MetallicMap",2D)="white"{}

_Metallic("Metallic",Range(0,1)=0

The surf function changes a little too -

void surf(Input IN, inout SurfaceOutputStandard o) 

Define them in the SubShader as Sampler2D and half, respectively and put the uv_MetallicTex in for the Input struct.

In the void surf(............) function lets assign these to some stuff-

o.Smoothness=tex2D( _MetallicTex, IN.uv_MetallicTex).r;

o.Metallic=_Metallic ;

Here we are using the Red channel of the Metallic Texture to control the smoothness of the surface. Where the value is high, we get a very smooth and glossy surface, where it is low we get a rough one. The metallicity is controlled by the _Metallic variable and is pretty straight forward.

 

Standard Specular

Pretty much the same as the Standard, except we have

fixed3 Specular; instead of half Metallic;

in the SurfaceOutputStandardSpecular struct. This is the colour of the specular highlight.

Also the #pragma becomes

#pragma surface surf StandardSpecular

and the surf function becomes

void surf(Input IN, inout SurfaceOutputStandardSpecular)

Comments

Popular posts from this blog

setting VFX graph properties using C#