本文最后更新于188 天前,其中的信息可能已经过时,如有错误请发送邮件到2939296129@qq.com
基础知识
漫反射和镜面反射

各种向量

漫反射
漫反射-Diffuse:
- 因其向四面八方均匀散射,所以反射亮度和观察者看的方向无关
- 实现方式:Lambert(NdotL),显然vDir不参与计算

镜面反射
镜面反射-Specular:
- 因其反射有明显方向性,所以观察者的视角决定了反射光线的有无,明暗
- 实现方式:
- Phong(R dot V),即光反射方向和视角方向越重合,反射越强
- Blinn-Phong(N dot H),即法线方向和半角方向越重合,反射越强

连连看
直接看图就好了,ASE同理
Phong

Blinn-Phong

代码-OldSchool
模版

添加材质参数

修改结构体和顶点Shader

修改片元Shader

这里注意:
尽量:三维向量 * 一维向量
否则某些手机机型会出bug(矩阵乘法)
贴个HLSL的代码
Shader "Unlit/HLSL-BlinnPhong"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Specular("Specular Color",Color)=(1,1,1,1)
_BaseColor("Base Color",Color)=(1,1,1,1)
_SpecularRange("Specular Range",Range(10,300))=10
}
SubShader
{
Tags{"RenderPipeline"="UniversalPipeline" "RenderType"="Opaque"}
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
CBUFFER_START(UnityPerMaterial)
half4 _BaseColor;
float4 _MainTex_ST;
half4 _Specular;
half _SpecularRange;
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
struct a2v
{
float4 vertex : POSITION;
float2 texcoord:TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f
{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
float3 viewDir:TEXCOORD1;
float3 normal:TEXCOORD2;
};
ENDHLSL
Pass
{
Tags{"LightMode"="UniversalForward"}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
v2f vert(a2v i)
{
v2f o;
o.pos=TransformObjectToHClip(i.vertex);
o.normal=TransformObjectToWorldNormal(i.normal);
o.uv=TRANSFORM_TEX(i.texcoord,_MainTex);
o.viewDir=normalize(_WorldSpaceCameraPos.xyz-TransformObjectToWorld(i.vertex.xyz));
return o;
}
half4 frag(v2f i):SV_TARGET
{
Light mylight=GetMainLight();
half3 lightDir=normalize(mylight.direction);
half3 viewDir=normalize(i.viewDir);
half3 normal=normalize(i.normal);
half3 halfDir=normalize(lightDir+viewDir);
half3 lightCol=mylight.color.rgb;
half3 baseCol=SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv).rgb*_BaseColor.rgb;
half3 spec=baseCol*_Specular.rgb*pow(saturate(dot(halfDir,normal)),_SpecularRange);
half3 diffuse=baseCol*lightCol*saturate(dot(lightDir,normal));
//half3 ambient=half3(unity_SHAr.w,unity_SHAg.w,unity_SHAb.w);
half3 finalColor=diffuse+spec;
return half4(finalColor,1);
}
ENDHLSL
}
}
}
结果

