Shader13 Fragmentshader片段级光照

本文深入解析Unity中的Shader编程,详细介绍了两种不同的Shader实现方式:MyDiffuseFrag和MySpecularFrag。通过具体的代码示例,展示了如何在顶点和片段程序中处理光照计算,包括漫反射和高光效果,以及如何在片段程序中进行光栅化处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Shader "Sbin/MyDiffuseFrag" 
{
	SubShader 
	{	
		pass
		{	
			//渲染路径的类型
			tags("LightMode"="Vertex")
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag	 		
			
			//引用公用方法  Unity\Editor\Data\CGIncludes\sbin
			#include "unitycg.cginc"	
			#include "Lighting.cginc"
			
			struct v2f
			{
				float4 pos: POSITION;
				//float3 normal:NORMAL;错误的不能用NORMAL,从顶点到片段程序不支持
				float3 normal:TEXCOORD1;
				float3 lightDir:COLOR;
			};
			   
			
			//基于顶点,模型当中有一个顶点,就会启动一个顶点程序,有N个顶点启动N个顶点程序
			//顶点程序计算完v2f传递给片段程序
			//一个三角形有很多个像素点,但是我们用了一个发向量和一个光照向量
			v2f vert(appdata_base v)
			{
				v2f o;
				o.pos=mul(UNITY_MATRIX_MVP,v.Vertex);
				//发向量转化到世界空间
				o.normal= v.normal;
				//光照向量转化到世界空间
				O.lightDir=v.vertex;
				
				return o;			 
			}

			//片段程序进行光栅化处理,将三角形面片生成适配于屏幕像素点的片段,
			//一个片段程序对应一个像素点的处理
			//对原始的法线,原始的顶点数据的计算要在片段程序中进行
			//法线旋转到世界空间,计算光向量都要在片段程序中
			fixed4 frag(v2f IN):COLOR
			{	
				//环境光源
				fixed4 col=UNITY_LIGHTMODEL_AMBIENT;
				//发向量
				float3 N=UnityObjectWorldNormal(IN.normal);
				//光照向量
				float3 L=normalize(WorldSpaceLightDir(IN.Vertex));
				//漫反射强度
				float diffuseScale=saturate(dot(N,L));
				col+=_LightColor0*diffuseScale;
				return col;
			}	
			ENDCG
		}
	}
}

 

 

Shader "Sbin/MySpecularFrag" 
{
	Properties
	{
		_MainColor("MainColor",color)=(1,1,1,1)
		_SpecularLightColor("SpecularColor",color)=(1,1,1,1)
		//光照系数
		_Shininess=("Shininess",range(1,32))=8
	}

	SubShader 
	{	
		pass
		{	
			//渲染路径的类型
			tags("LightMode"="Vertex")
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag	 		
			
			//引用公用方法  Unity\Editor\Data\CGIncludes\sbin
			#include "unitycg.cginc"	
			#include "Lighting.cginc"
			#include "UnityShaderVariables.cginc"
			
			float4 _MainColor;
			float4 _SpecularLightColor;
			float _Shininess;
			struct v2f
			{
				float4 pos: POSITION;
				//float3 normal:NORMAL;错误的不能用NORMAL,从顶点到片段程序不支持
				float3 normal:TEXCOORD1;
				float3 lightDir:COLOR;
			};
			
			//基于顶点,模型当中有一个顶点,就会启动一个顶点程序,有N个顶点启动N个顶点程序
			//顶点程序计算完v2f传递给片段程序
			//一个三角形有很多个像素点,但是我们用了一个发向量和一个光照向量
			v2f vert(appdata_base v)
			{
				v2f o;
				o.pos=mul(UNITY_MATRIX_MVP,v.Vertex);
				//发向量转化到世界空间
				o.normal= v.normal;
				//光照向量转化到世界空间
				O.lightDir=v.vertex;
				return o;			 
			}

			//片段程序进行光栅化处理,将三角形面片生成适配于屏幕像素点的片段,
			//一个片段程序对应一个像素点的处理
			//对原始的法线,原始的顶点数据的计算要在片段程序中进行
			//法线旋转到世界空间,计算光向量都要在片段程序中
			fixed4 frag(v2f IN):COLOR
			{	
				//环境光源
				fixed4 col=UNITY_LIGHTMODEL_AMBIENT;
				//发向量
				float3 N=UnityObjectWorldNormal(IN.normal);
				//光照向量
				float3 L=normalize(WorldSpaceLightDir(IN.Vertex));
				//漫反射强度
				float diffuseScale=saturate(dot(N,L));
				col+=_LightColor0*_MainColor*diffuseScale;

				//Specular color  
				//视向量
				float3 V=normalize(WorldSpaceLightDir(IN.Vertex));
				//反射向量
				float3 R=2*dot(N,L)*N-L;
				float specularScale=saturate(dot(R,V));
				col+=_SpecularColor*pow(specularScale,_Shininess);

				//点光源的渲染计算
				float3 wpos=mul(_Object2World,IN.vertex).xyz;
				col.rgb+=Shade4PointLights(		

					unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
					unity_LightColor[0].rgb,unity_LightColor[1].rgb,unity_LightColor[2].rgb,unity_LightColor[3].rgb,
					unity_4LightAtten0,
					wpos,N
				);
				return col;
			}	
			ENDCG
		}
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值