zoukankan      html  css  js  c++  java
  • unity shader入门(四):高光

    高光反射计算公式(phong模型)Cspecular=(Clight*Mspecular)max(0,v*r)mgloss

    mgloss为材质的官泽度,也成反射度,控制高光区域亮点有多大

    Mspecular是材质的高光反射颜色,控制材质对于高光反射的轻度和颜色

    Clight为光源的颜色和强度

    v是观察方向的单位向量

    r是反射方向 r=2(法线单位向量n*光源方向向量)法线单位向量-光源方向向量

    高光反射计算公式(Blinn模型)Cspecular=(Clight*Mspecular)max(0,n*h)mgloss

    n为法线向量的单位向量

    h是对观察方向和光源方向取平均后归一化得到的:h(注:单位向量)=(v(注:单位向量)+光源方向)/|(v(注:单位向量)+光源方向)|

    下面分别是逐顶点和逐像素两种写法

    phong模型 逐顶点:

    Shader "study/Chapter6/halfLambertShader" {
    	Properties{
    	_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
    	_Specular("Specular",Color)=(1,1,1,1)//控制材质高光反射颜色
    	_Gloss("Gloss",Range(8.0,256)) = 20 //用于控制高光区域的大小
    	}
    	SubShader{
    			Pass{
    			Tags{"LightMode"="ForwardBase"}
    			CGPROGRAM
    
    			#pragma vertex vert
    			#pragma fragment frag
    
    			#include "Lighting.cginc"
    
    			fixed4 _Diffuse;
    			fixed4 _Specular;
    			float _Gloss;
    
    			struct a2v{
    				float4 vertex:POSITION;
    				fixed4 normal:NORMAL;
    			};
    			struct v2f{
    				float4 pos:SV_POSITION;
    				fixed3 color:COLOR;
    			};
    			v2f vert(a2v v){
    
    			v2f o;
    			o.pos=UnityObjectToClipPos(v.vertex);
    
    			fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
    			//内置函数写法,下面给出内置函数
    			//fixed3 worldNormal=normalize(UnityObjectToWorldNormal(v.normal););
    			fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));
    
    			fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
    
    			fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));
    
    			//反射方向get the reflect direction in world space
    			fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));
    
    			//get the view direction in world space
    			//世界空间下观察方向
    			fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(unity_ObjectToWorld,v.vertex).xyz);
    
    			//Computer specular term
    			fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss);
    
    			o.color=diffuse+ambient+specular;
    
    			return o;
    
    			}
    			fixed4 frag(v2f i):SV_Target{
    			return fixed4(i.color,1.0);
    			}
    
    		ENDCG
    		}
    	}
    	FallBack "Specular"
    }
    

      phong模型 逐像素:

    Shader "study/Chapter6/SpecularPixelLevelShader"
    {
    	Properties{
    	_Diffuse("Diffuse",Color)=(1,1,1,1)
    		_Specular("Specular",Color)=(1,1,1,1)
    		_Gloss("Gloss",Range(8.0,256))=20
    	}
    	
    	SubShader{
    		Pass{
    			Tags{"LightMode"="ForwardBase"}
    			CGPROGRAM
    			#pragma vertex vert
    			#pragma fragment frag
    
    			#include "Lighting.cginc"
    
    			fixed4 _Diffuse;
    			fixed4 _Specular;
    			float _Gloss;
    
    			struct a2v{
    				fixed4 vertex:POSITION;
    				fixed3 normal:NORMAL;
    			};
    			struct v2f{
    				fixed4 pos:SV_POSITION;
    				float3 worldNormal:TEXCOORD0;
    				float3 worldPos:TEXCOORD1;
    			};
    
    			v2f vert(a2v v){
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				//使用内置函数写法
    				//o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
    				o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
    				return o;
    			}
    
    			fixed4 frag(v2f i): SV_Target{
    			//环境光、自发光部分
    			fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
    			//世界空间下法线单位矢量
    			fixed3 worldNormal=normalize(i.worldNormal);
    			//世界空间下光源方向单位矢量
    			fixed3 worldLightDir=normalize(_WorldSpaceCameraPos.xyz);
    			//漫反射部分
    			fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
    			//世界空间下反射光矢量
    			fixed3 reflectDir=normalize(reflect(-worldLightDir,worldNormal));
    			//视野方向
    			fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
    			//高光
    			fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss);
    			//最终观察到的光照
    			return  fixed4(ambient+diffuse+specular,1.0);
    			}
    			ENDCG
    		}
    	}
    		FallBack "Specular"
    }
    

      Blinn模型逐像素

    Shader "study/Chapter6/BlinnPhongShader"
    {
    	Properties{
    	_Diffuse("Diffuse",Color)=(1,1,1,1)
    	_Specular("Specular",Color)=(1,1,1,1)
    	_Gloss("Gloss",Range(8.0,256))=20
    	}
    	SubShader{
    		Pass{
    			Tags{"LightMode"="ForwardBase"}
    
    			CGPROGRAM
    
    			#pragma vertex vert
    			
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    
    			fixed4 _Diffuse;
    			fixed4 _Specular;
    			float _Gloss;
    
    			struct a2v{
    
    				float4 vertex:POSITION;
    				float3 normal:NORMAL;
    			};
    			struct v2f{
    
    				float4 pos:SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    			};
    
    			v2f vert(a2v v){
    				v2f o;
    				o.pos=UnityObjectToClipPos(v.vertex);
    				o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
    				o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
    				return o;
    			}
    			
    			fixed4 frag(v2f i):SV_Target{
    
    				float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
    				fixed3 worldNormal = normalize(i.worldNormal);
    				//内置函数写法
    				//float3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
    				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
    				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldNormal, worldLightDir));
    				//内置函数写法
    				//fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldNormal));
    				fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
    				fixed3 halfDir=normalize(worldLightDir + viewDir);
    				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);
    				return fixed4(ambient+diffuse+specular,1.0);
    			}
    			ENDCG
    		}
    	}
    	FallBack "Specular"
    }
    

      

    unity的内置函数

     

    仅用于前向渲染的只有在渲染模式为前向渲染时(“LightMode”=“ForwordBase”或者"LightMode"="ForwordAdd")

    这三个函数里的内置变量——WorldSpaceLightPos0等才能被正确赋值。

    注:这一篇以及之前漫反射都是单一平行光源下计算的,查看效果时,去掉天空盒,设置方法为window->Lighting->skybox

  • 相关阅读:
    php4的一个创建xml的类
    ecshop在模板里调用广告位的代码
    文件导出dbf功能实现
    [转] 处事22计、心态24条、伤心50句、礼仪73、学会长大20!
    在线客服 qq,msn,skype, outlook 链接
    解决动网论坛Bug缺少对象: 'Application(...).documentElement.selectSingleNode(...)'
    创建一个SharePoint 样式(Creating a SharePoint Theme)
    Sharepoint Portal Services 2003开发环境
    [译]Hour 7 Teach.Yourself.WPF.in.24.Hours
    远程桌面连接无法最大化的解决办法
  • 原文地址:https://www.cnblogs.com/lanrenqilanming/p/7727577.html
Copyright © 2011-2022 走看看