Unity Shader 学习笔记(7) 高光反射

44 篇文章 5 订阅
36 篇文章 5 订阅

Unity Shader 学习笔记(7) 高光反射

参考书籍:《Unity Shader 入门精要》
3D数学 学习笔记(8) 光照

Phong模型的逐顶点、逐像素,和Blinn模型对比:

在这里插入图片描述


Phong模型

在这里插入图片描述
在这里插入图片描述


逐顶点光照(Gouraud shading,高洛德着色)

Properties {
	_Diffuse ("Diffuse",Color) = (1,1,1,1)
	_Specular ("Specular",Color) = (1,1,1,1)	// 反射颜色
	_Gloss ("Gloss",Range(8.0,256)) = 20		// 高光区域大小
}

Pass中关键代码:

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

struct v2f {
	float4 pos : SV_POSITION;
	fixed3 color : COLOR0;
};

v2f vert (a2v v){
	v2f o;
	o.pos = UnityObjectToClipPos(v.vertex);
	
	// 下面这块是逐顶点漫反射,详见上一篇。
	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
	fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));
	fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
	fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
	
	// 计算获得出射方向r。reflect:发射方向,CG提供的函数。worldLightDir是光照方向,与L方向相反。
	fixed reflectDic = normalize(reflect(-worldLightDir,worldNormal));

	// 视觉方向v。即相机到物体的向量归一化。
	// 等价UnityWorldSpaceViewDir(mul(unity_ObjectToWorld,v.vertex))
	fixed viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld,v.vertex).xyz);

	// 高光反射系数,Phong模型公式,假设只有一个平行光源_LightColor0。
	fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDic,viewDir)),_Gloss);

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

fixed4 frag(v2f i) : SV_Target {
	return fixed4(i.color,1.0);
}

逐像素光照(Phong shanding,Phong着色)

没有太大区别,只是把计算过程丢到了片元着色器。

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 {
	
	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

	fixed3 worldNormal = normalize(i.worldNormal);
	fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
	fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
	
	fixed reflectDic = normalize(reflect(-worldLightDir,worldNormal));
	fixed viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
	fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDic,viewDir)),_Gloss);

	return fixed4(ambient + diffuse + specular,1.0);
}

Blinn光照模型

计算快于Phong模型。两种都是经验模型。一些情况下Blinn模型更符合实验结果。

在这里插入图片描述

直接修改上面Phong的逐片元代码即可。

// 视觉方向v
//fixed viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));

// 单位向量h
fixed3 halfDir = normalize(worldLightDir + viewDir);

// 套公式
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(worldNormal,halfDir)),_Gloss);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值