Shader 学习笔记(7) 基本光照模型中高光反射

这篇博客深入探讨了Shader中的基本光照模型,特别是关于高光反射的部分。通过数学公式详细解释了如何计算高光反射效果,为理解和实现更真实的3D图形渲染提供了基础。

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

公式

             CGPROGRAM
              #pragma vertex vert
              #pragma fragment frag
              #include "Lighting.cginc"
              fixed4 _Diffuse;
              fixed4 _Specular;
              float _Gloss;
              struct a2v{
                  float4 vertex:POSITION;
                  float3 normal:NORMAL;
                  float3 color :COLOR;
              };
              struct v2f{
                  float4 pos:SV_POSITION;
                  fixed3 worldNormal:COLOR0;
                  fixed3 color:COLOR1;
                  fixed3 worldPosition:COLOR2;       //声明世界坐标
              };
              v2f vert(a2v v){
                 v2f o;
                 o.pos=UnityObjectToClipPos(v.vertex);      
                 o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
                 o.worldPosition=mul(unity_ObjectToWorld,v.vertex);//得到物体的世界坐标
                 o.color=fixed3(1,0,0);
                 return o;
              }
              fixed4 frag(v2f i):SV_Target{
              fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
               fixed3 worldNormal=normalize(i.worldNormal);
               fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);
               fixed halfLambert=dot(worldNormal,worldLight)*0.5+0.5;
               fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*halfLambert;
               fixed3 reflectDir=normalize(reflect(-worldLight,worldNormal));//见上图,reflect(i,n)
               fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-i.worldPosition.xyz);//摄像机的世界坐标减去物体的世界坐标,得到一个向
               量然后归一化既得到了摄像机朝向.
               fixed3 specular=_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(reflectDir,viewDir)),_Gloss);
               fixed3 color =ambient+diffuse+specular;
                  return fixed4(color,1.0);
              }
              ENDCG


用unity内置函数重写了shader
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'


Shader"wx/Single Texture"{
     Properties{
          _Color("Color Tint",Color)=(1,1,1,1)
          _MainTex("Main Tex",2D)="white"{}
          _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 _Color;
              sampler2D _MainTex;
              float4 _MainTex_ST;
              fixed4 _Specular;
              float _Gloss;
              struct a2v {
                 float4 vertex:POSITION;
                 float3 normal:NORMAL;
                 float4 texcoord:TEXCOORD0;
              };
              struct v2f{
                  float4 pos:SV_POSITION;
                  float3 worldNormal:TEXCOORD0;
                  float3 worldPos:TEXCOORD1;
                  float2 uv:TEXCOORD2;
              };
              v2f vert(a2v v){
                 v2f o;
                 o.pos=UnityObjectToClipPos(v.vertex);
                 o.worldNormal=UnityObjectToWorldNormal(v.normal);
                 o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
                 o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
                 return o;
              }
              fixed4 frag(v2f i):SV_TARGET{
                  fixed3 worldNormal=normalize(i.worldNormal);
                  fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
                  fixed3 albedo=tex2D(_MainTex,i.uv).rgb*_Color.rgb;
                  fixed3 diffuse=_LightColor0.rgb*albedo*max(0,dot(worldNormal,worldLightDir));
                  fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldPos));
                  fixed3 halfDir=normalize(worldLightDir+viewDir);
                  fixed3 specular =_Specular.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss);
                  return fixed4 (diffuse+specular,1.0);


              }
              ENDCG
         }
        
     }
     Fallback "Specular"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值