unity shader漫反射

1. 漫反射物体在环境光下反射的光强 = 环境光强*材质对环境光的反射系数

2. 漫反射物体在入射光下反射光强 = 光源强度*材质对环境光的反射系数*cos入射光与法线夹角

参考:https://www.cnblogs.com/luxishi/p/6422852.html 漫反射和Lambert模型

求光源下物体漫反射颜色使用的是公式 2 

物体在点光源下漫反射颜色 = 入射光颜色*漫反射系数(材质的漫反射颜色)*max(0,  cos(法线与入射光夹角) )

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "MyShader/Chapter6-DiffuseVertexLevel"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_Diffuse("Diffuse", color) = (1, 1, 1, 1)
	}
		SubShader
		{
			/*设定着色器是不透明的*/
	 Tags { "RenderType" = "Opaque" }
	 LOD 100

	 Pass
	 {
		 Tags{ "LightMode" = "ForwardBase"}


		 CGPROGRAM
		 #pragma vertex vert
		 #pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			//使用unity内置变量
			#include "UnityCG.cginc"
			#include "Lighting.cginc"

            struct a2v
            {
                float4 vertex : POSITION;//POSITION 模型顶点坐标
				float3 normal : Normal;
            };

			//使用该结构体定义顶点着色器的输出,顶点着色器中必须包含一个语义是SV_POSITION的变量,
			//否则渲染器无法得到顶点的裁剪空间坐标,也就无法将顶点渲染到屏幕
            struct v2f
            {
				float4 pos : SV_POSITION;//SV_POSITION裁剪空间顶点坐标
				fixed3 color : COLOR;
            };

            sampler2D _MainTex;
			fixed4 _Diffuse;

            v2f vert (a2v v)
            {
				v2f o;
				//Transform the vertex from object space to projection space,顶点位置从模型空间转为裁剪空间
				o.pos = UnityObjectToClipPos(v.vertex);

				//Get ambient term,使用unity内置变量获取环境光
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

				//Transform the normal from object space to world space,得到顶点世界空间法线
				fixed3 worldNormal = normalize(mul(v.normal, unity_WorldToObject));

				//Get the light direction in world space,获取世界空间光照方向
				fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);

				//Compute diffuse term, 漫反射 = ( 入射光颜色和强度Clight*材质漫反射系数Mdiffuse )*max(0, n*l)
				fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot( worldNormal , worldLight ) );

				o.color = ambient + diffuse;
				return o;
            }

			//片元着色器的输入其实是顶点着色器的输出进行插值后的结果,
			//个人理解:对于上面的顶点着色器的输出,是一个顶点的裁剪空间坐标以及该顶点的颜色,
			//因此插值后获取到该片元的裁剪坐标以及颜色,最终输出到屏幕
            fixed4 frag (v2f i) : SV_Target
            {
				return fixed4( i.color, 1.0 );
            }
            ENDCG
        }
    }
}

 

Shader "MyShader/Chapter6-DiffusePixelLevel"
{
	//逐像素光照
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_Diffuse("Diffuse", color) = (1,1,1,1)
	}
		SubShader
		{
			Tags { "RenderType" = "Opaque" }
			LOD 100

			Pass
			{
				Tags{"LightMode" = "ForwardBase"}

				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog

			#include "UnityCG.cginc"
			#include "Lighting.cginc"

			fixed4 _Diffuse;

            struct a2v
            {
                float4 vertex : POSITION;
				float3 normal : Normal;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
            };

            sampler2D _MainTex;

            v2f vert (a2v v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
				o.worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 worldLight = normalize( _WorldSpaceLightPos0.xyz );
				fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(i.worldNormal, worldLight));
				return fixed4(ambient + diffuse, 1.0);
            }
            ENDCG
        }
    }
}

参考:unity shader编程精要

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值