-
课时77 Fragment shader - Cube纹理采样
1.需求:让一个模型表面反射一个Cube纹理,纹理相对静止,根据摄像机相对位置的不同,反射的图像角度实时变化。
2.代码:
Shader "Custom/Lesson77"
{
//课时77 Fragment shader - Cube纹理采样
Properties
{
_Cube("Cubemap",Cube)=""{}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
samplerCUBE _Cube;
struct v2f
{
float4 pos : POSITION;
float3 R : TEXCOORD0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 V=-WorldSpaceViewDir(v.vertex);
float3 N=UnityObjectToWorldNormal(v.normal);
N=normalize(N);
o.R=reflect(V,N);
return o;
}
fixed4 frag (v2f IN) : COLOR
{
fixed4 col = texCUBE(_Cube, IN.R);
return col;
}
ENDCG
}
}
}
效果:不是实时的Cubemap贴图。Camera.RenderToCubmap()可以获得实时Cubemap,见 Camera.RenderToCubemap
-
课时78 Fragment shader - 实现高效的reflection shader
1.需求:实现Surface着色器的Cube纹理采样。
2.代码:
Shader "Custom/Lesson78"
{
//课时78 Fragment shader - 实现高效的reflection shader
Properties{
_SecondColor("SecondColor",Color)=(1,1,1,1)
_Center("Center",Range(-0.07,0.07))=0
_R("R",Range(0,0.02))=0.001
_Glossiness("Smoothness",Range(0,1))=0
_Metallic("Metallic",Range(0,1))=0
_Cube("Cubemap",Cube)=""{}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
//等同于:pragma surface surf Standard vertex:vert fullforwardshadows
//有时会不识别vert函数,但不报错
#pragma surface surf Standard fullforwardshadows vertex:vert
#pragma target 3.0
samplerCUBE _Cube;
fixed4 _MainColor;
fixed4 _SecondColor;
float _Center;
float _R;
half _Glossiness;
half _Metallic;
//surfaceshader的Input声明可以不加语义
struct Input{
float x;//可省略TEXCOORD0语义
float3 worldRefl;//(视线的)反射向量,在自动生成的顶点程序里赋值。自己写的顶点程序里需要手动赋值
};
void vert(inout appdata_full v,out Input o)
{
// o.uv_MainTex=v.texcoord.xy;
float3 V=-WorldSpaceViewDir(v.vertex);
float3 N=UnityObjectToWorldNormal(v.normal);
N=normalize(N);
o.worldRefl=reflect(V,N);
o.x=v.vertex.x;
}
void surf(Input IN,inout SurfaceOutputStandard o){
fixed4 c=texCUBE(_Cube,IN.worldRefl);
o.Albedo=c.rgb;
o.Metallic=_Metallic;
o.Smoothness=_Glossiness;
o.Alpha=c.a;
float d=IN.x-_Center;//-0.5~0.5 原始区间
float s=abs(d);//0~0.5 原始绝对区间
d=d/s;//-1,1 正负号
float f=s/_R;//0~1.x
f=saturate(f);//0~1 缩减绝对区间
d*=f;//-f,f 给绝对区间加正负号
d=d/2+0.5;//变换至0~1区间
o.Albedo.rgb *= lerp(_MainColor,_SecondColor,d)*2;
}
ENDCG
}
Fallback "Diffuse"
}
效果:
4.待学内容:①各向异性②玉石的次表面散射问题③透明物体的折射问题④菲涅尔定律⑤体积光体积雾⑥brdf光照模型⑦后期特效⑧gpgpu通用计算。