keyle的Shader-学习手札

时间:2022-11-08 04:09:10

keyle的Shader-学习手札

 

前一段时间出去面试没有找到自己想要的工作,原因是shader熟练,虽然用的来ShaderForge但是面试官仍然会问到关于shader的基本知识,特写如下学习心得不断更新以此鞭策自己,少壮不努力老大徒伤悲(六月不学习,七月徒伤悲,八月忘穿秋水也找不到工作),接下来的日子好好补充数学与图形学知识,只有基础牢固才rong攻yi无zhuang不bi克 ! 另外给我们的开源项目做做宣传 https://git.oschina.net/keyle/SuperStrange ,创意3D跑酷手游,每个周末开发者一起协作开发,周期不限,欢迎大牛!

附件 1. CG标准函数库查询 链接: http://pan.baidu.com/s/1hq8Ir1i 密码: 3d3q

 

1.属性

_MyColor ("Some Color", Color) = (1,1,1,1) 
_MyVector ("Some Vector", Vector) = (0,0,0,0) 
_MyFloat ("My float", Float) = 0.5 
_MyTexture ("Texture", 2D) = "white" {} 
_MyCubemap ("Cubemap", CUBE) = "" {}

 

2.基本内建指令

#pragma surface surf Lambert
 
#pragma surface surf BasicDiffuse

#pragma surface surf SimpleLambert

#pragma surface surf WrapLambert

#pragma surface surf Ramp

#pragma surface surf SimpleSpecular

#pragma surface surf Standard

#pragma surface surf Tonemapped
 
#pragma surface surf BlinnPhong
 
#pragma surface surf Phong

(1) #pragma surface surf Lambert 基础Lambert 光照模型:默认导入

(2) #pragma surface surf BasicDiffuse 基础漫反射光照模型

(3) #pragma surface surf SimpleLambert 简单Lambert,通过计算法线与光的方向夹角的点乘来判断光的衰减:出自官网介绍

It computes lighting by doing a dot product between surface normal and light direction, and then applies light attenuation and color.

(4) #pragma surface surf WrapLambert 环绕漫反射——漫反射光照的修改版,即照明环绕在物体的边缘。它对用来仿照表面下散射效果很有用。

(5) #pragma surface surf Ramp 渐变照明模式,使用一个渐变纹理定义光与法线夹角对surface影响,可用于卡通照明

(6) #pragma surface surf SimpleSpecular 简单光源反射,内置的blinnphong光照模型,

关于blinnphong光照模型可以参考ShaderForge博文中的这一篇 http://www.cnblogs.com/Keyle/p/4451887.html

(7) #pragma surface surf Standard 模仿内置的光照贴图解码工作,使用Unity自带的DecodeLightmap函数解码lightmap中储存的数据信息,以及使用自带的 UNITY_DIRBASIS宏定义方向光照贴图(Directional lightmap)的基本向量

We’ll start with a shader that mimics built-in lightmap decoding and uses Unity built-in function DecodeLightmap to decode information from data stored in lightmap textures and built-in UNITY_DIRBASIS macro defining basis vectors for Directional lightmaps:

(8) #pragma surface surf Tonemapped 色调映射

这几个内建光照模型的翻译我翻译到一半居然发现已经有了便不再费力直接上链接 点我

(9)#pagma surface surf BlinnPhong  Phong光照模型优化版

(10)#pagma surface surf Phong 

(11)#pagma surface surf CustomPhong 

3.光照模型函数

当你声明一个光照模型函数,就可以创建一个新的光照模型,函数的格式是

half4 LightingYouName(SurfaceOutput s,half3 lightDir,float atten){} 本函数在不需要视角方向的先前着色时使用

half4 LightingYouName(SurfaceOutput s,half lightDir,half3 viewDir,half atten){} 用于需要视角方向着色时使用,考虑观察者视角方向

half4 LightingYouName(SurfaceOutput s,half4 light){} 此函数用于需要延迟着色的项

 

附件 今天的学习成果

#pragma surface surf BasicDiffuse
inline float4 LightingKeyle(SurfaceOutput s,half3 dir,fixed aten)
{
    float difLight = max(0,dot(s.Normal,dir));
    difLight = difLight *0.5+0.5;

    float4 temp;
 
    //这个_LightingColor0是U3d内建变量获取环境光 s.Albedo是表面输出的反射率 
    temp.rgb = s.Albedo * _LightColor0.rgb*(difLight*aten*2); 
    temp.a = s.Alpha; //拿到SurfaceOutput的透明通道
    return temp;
}

3.1 注意事项

1.如果不需要自己创建光照模型 可以将BasicDiffuse改回Lambert

2.在U3d5.0中自定义光照模型的名字时会报错类似 BasicDiffuse1, BlinnPhong, Lambert at line 11 (on ) ,此时改成默认的LightingBasicDiffuse,报错消失

3.位于光照模型参数列表中的atten 意为衰弱 注意:rgbA * rgbB 颜色会变暗,最终至全黑

4._LightColor0 通常为主光源的颜色

5._Time 内置时间函数通常配合text2D给图形做动态偏移 代码如下  

keyle的Shader-学习手札

6._Time 是一个float4类型,默认使用的时候输出_Time.x,官方翻译如下

Time (t/20, t, t*2, t*3), use to animate things inside the shaders.

7.灰阶公式

dot(float4, fixed3(.222,.707,.071));

8.#pragma target 版本 指定shader模型使用的版本

#pragma target 3.0 定义Shader模型为Shader Model 3.0
2.0 Direct3D 9 (默认缺省值) 支持32张贴图 + 64个计算
3.0 Direct3D 9 支持512张贴图 + 512个计算
4.0 只支持DirectX 11
5.0 只支持DirectX 11

http://blog.sina.com.cn/s/blog_471132920101dcnr.html

9.Phong基础光照模型

float4 LightingPhong(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten) 使用带观察者视角的方法签名

float3 reflectionVector = normalize(2.0* s.Normal * _Diffuse - lightDir);
float specular = pow(max(0,dot(reflectionVector,viewDir)),POW);
float3 finalSpecular = _SpecularColor.rgb*specular;
float4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * _Diffuse )+(_LightColor0*finalSpecular);
c.a = 1.0;

伪代码如上,核心算法  Dot( normailize(2*s.Normal*dot(s.Normal,lightDir) – lightDir) , viewDir)

 

10.BlinnPhong基础光照模型

inline float4 LightingPhong(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten) 使用带观察者视角的方法签名

float3 halfDir = normalize(lightDir + viewDir); //半光照

float nh = dot(s.Normal,halfDir);
float specular = pow(nh,_SpecularPower)*_SpecularColor;

float4 c;
c.rgb = (s.Albedo*_LightColor0.rgb*_Diffuse )+(_LightColor0*_SpecularColor.rgb*specular) * (atten*2);

伪代码如上,核心算法 dot(normalize(lightDir+viewDir) , s.Normal)


 

11.CustomPhong自定义Phong基础光照模型

结构体的名称必须为SurfaceCustomOutput

struct SurfaceCustomOutput 
{
    …
    fixed3 SpecularColor;
};
inline fixed4 LightingCustomPhong (SurfaceCustomOutput s, fixed3 lightDir, half3 viewDir, fixed atten) 签名中SurfaceOutput换成SurfaceCustomOutput

在surf函数中赋值SpecularColor,在光照模型中使用

4.常用基本函数

1.tex2D(sampler2D,half2)  贴图采样返回对应坐标的像素值

2.fmod(float,float) 返回第一个数除以第二个数的余数

3.ceil(float) 向上取整

4.lerp(float3,float3,float) 插值,效果是叠加两张图在一个图片上,从第一个rgb渐变到第二个rgb数值,第三个参数是叠加的最后一个图的透明通道(Texture.a)

5.UnpackNormal(float4) 获得贴图信息

6.saturate 将颜色规范化0-1之间,类似于Vector2.Normalize函数