- 我创建了一个游戏制作交流群:637959304 进群密码:(CSGO的拆包密码)欢迎各位大佬一起学习交流,不限于任何平台(U3D、UE、COCO2dx、GamesMaker等),以及欢迎编程,美术,音乐等游戏相关的任何人员一起进群学习交流。
视差贴图
- 增加法线信息细节,增添深度信息细节,通过营造高度差来模拟深度细节。
- 缺点:数值设置过大会造成图片拉伸效果,摄像机视角如果与贴图法线角度接近90度则看不出效果。
offset hight = 0
offset hight = 0.06- 前置条件:高度贴图(Height Map),可以存入到法线贴图的alpha通道中
//自定义Offset Height变量
v2f v(a2v In,uniform float4 lightPosition)
{
//在v2f中定义t_eyeVec,代表切线空间下的观察向量
float3x3 objTangentXf = //ObjectToTangentSpaceTransform,类似于mvp矩阵
objTangentXf[0] = In.binoraml.xyz;
objTangentXf[0] = -In.tangent.xyz;
objTangentXf[0] = In.normal.xyz;
float4 objSpaceEyePos = mul(Viewinverse[3] , worldI);//摄像机坐标物体空间,worldI为定义的Inverse矩阵
float3 objEyeVec = objSpaceEyePos.xyz - In.position.xyz;//观察向量
Out.t_eyeVec = mul(objEyeVec,objTangentXf);.//切线空间下观察向量
}
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
//计算出能够跟随观察向量和高度贴图移动的UV坐标
float2 t_eyeVec = normalize(In.t_eyeVec).xy;
t_eyeVec.y = -t_eyeVec.y;//这里是视频里适配3DS MAX的UV坐标才这么写的
float heightAlpha = tex2D(normalMapSampler,In.texCoord).a * 2 - 1;
float2 nevTextCoords = (heightAlpha * t_eyeVec * OffsetHeight) + In.texCoord.xy;
//之后把新的nevTextCoords在ColorTexture、SpecularTexture、noraml中替换原来的In.texCoord.xy
}
反射贴图(镜面反射)
- 反射贴图(Reflection Mapping),依靠反射贴图实现实时反(Realtime)射计算,实现环境光的效果
- (现在可以直接使用光追,NVIDIA yes!)
- 前置条件:立方贴图
- 数据结构
//自定义反射贴图材质(texture reflectMap)以及反射贴图采样器(samplerCUBE reflectMapSampler)
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
//计算反射向量,解决贴图旋转问题
float3 refvector = reflect(V,N);
refvector.yz = -refvector.zy;//同3DS的问题
float4 ref = texCUBE(reflectMapSampler, refvector);
return ref * 5;//该系数根据贴图亮度进行调整即可
}
制作金属材质
//自定义采样层数reflectionBlur
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
//texCUB->texCUBElod从更模糊的贴图中进行采样 LOD->level of detail
//此处ColorTexture.a为模糊贴图的设置,导入模糊贴图后可以让指定区域展示不同的模糊效果
float4 ref = texCUBElod(reflectMapSampler, float4(refvector,reflectionBlur * ColorTexture.a));
//将反射混合进原有光装模型当中
Diffuse = lerp(Diffuse,ref,colorTexture.a);//lerp允许按照权重混合两个颜色
}
- Tip:因为导入图片是黑白贴图,所以在作乘法运算时,黑色区域的值为0,0乘以任何值都为0,所以无论如何提高模糊度该表面区域都是光滑的。
reflectionBlur = 6的效果
导入了黑白格子的模糊贴图后效果
进行反射混合之后的效果
折射效果(Reflection)

//水晶、透明等类似材质的折射效果
//自定义函数refractionIndex代表曝光率
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
//计算折射向量
//refract用于计算折射的函数,第一介质折射率除以第二介质折射率,此时第一介质为空气,第二介质为水。绝对折射率分别为函数内填入数据
//把1.330替换为refractionIndex,可让用户自定义材质折射率
float3 refractvector = refract(V,-N,1.000293/1.330).xyz;
refractvector = -refractvector.xzy;
refractvector.z = -refractvector.z;
refractedColor = texCUBE(reflectMapSampler,refractvector ) * 5;//系数5用来提高贴图亮度
}
折射效果贴图
材质折射率=1.0时情况
菲涅尔效应
- 利用菲涅尔效应(Fresnel)来结合反射和折射的效果。也可以用该思路制作边缘光效果,制作厨房表面,
- 菲涅尔效应(第二集里有详细链接):物体边缘或光线入射角较大的部位,比入射角小的部分体现出了更强烈的反射性质。
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
float fresnelTerm = pow(1 - dot(V,N),fresnelPower)* fresnelBrightness;//边缘白色中间黑色,直接是dot为边缘黑色中间白色,fresnelPower,fresnelBrightness为自定义变量
float4 reflectionAndRefraction = lerp(refractedColor,ref,fresnelTerm);
}
dot(V,N)
1 – dot(V,N)
pow(1 – dot(V,N),4)
反射折射混合后效果
pow(1 – dot(V,N),4)* 3
细节法线贴图
- 细节法线贴图(Detail Normal Mapping):允许放大观察后的图片拥有更多的细节。
//自定义参数:detailnormalmap 自定义采样器:detailNoramlMapSampler
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
//自定义参数detailSize,detialHeight
float3 detailNormal = tex2D(detailNoramlMapSampler,In.textCoord * detailSize).xyz * 2.0 -1.0 t;
normal = float3((normal.x + detailNormal.x* detialHeigh),(normal.y + detailNormal.y* detialHeigh),normal.z);
}

顶点颜色
- 利用顶点颜色和不同明度编写着色器。具体教程请看视频3.7章节。
- 用处举例:有两张漫反射贴图,通过顶点色决定哪些地方显示第一张,哪些地方显示第二张。
顶点动画

v2f v(a2v In,uniform float4 lightPosition)
{
float4 ObjectSpacePosition = In.position;
ObjectSpacePosition.z += 50;//这里的单位为cm,在3dsmax中
}
float time : TIME;
float wave(float value,float frequency,float speed,float amplitude)
{
return sin(value * frequency + speed) * amplitude;
}
v2f v(a2v In,uniform float4 lightPosition)
{
float4 ObjectSpacePosition = In.position;
ObjectSpacePosition.z += wave(ObjectSpacePosition.x,0.1,time,8) ;
}
波动效果
float2 teetertotter(float2 Textcoords,float2 center,float maxAngle,float time)
{
float theta = maxAngle * sin(time);
float2 sc;
sincos(theta,sc.x,sc.y);
float2 uv = Texcoords - center;
float2 rotateduv;
rotateduv.x = dot(uv,float2(sc.y-sc.x));
rotateduv.y = dot(uv,sc.xy);
rotateduv += center;
return rotateduv;
}
v2f v(a2v In,uniform float4 lightPosition)
{
float4 ObjectSpacePosition = In.position;
ObjectSpacePosition.yz += teetertotter(ObjectSpacePosition.yz,float2(0,0),1,time) ;
}
溶解特效

technique regular
{
pass one
{
AlphaTTestEnable = true;//开启透明度测试,根据透明度选择是否剔除片元
AlphaRef = 128;//用于定义透明度分界线。透明度低于128分为一组视为完全透明,高于128视为完全不透明
}
}
//自定义参数brightnessAmount,contrastAmount
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
float4 OutColor = (Ambient + Diffuse + Specular) * lightColor;
Outcolor.a = ColorTexture.a + brightnessAmount;
Outcolor.a = contrastAmount * (Outcolor.a - 0.5) + 0.5;//对比度调整公式
if(Outcolor.a <= 0.55) OutColor.rgb = float3(1.0,0.5,0.0);//因为在AlphaRef中规定了小于128的颜色会完全透明,所以实际上是在0.5-0.55的区间段内进行颜色的渲染
return OutColor;
}