目录
视差贴图
反射贴图(镜面反射)
制作金属材质
折射效果(Reflection)
菲涅尔效应
细节法线贴图
顶点颜色
顶点动画
溶解特效
offset hight = 0
offset hight = 0.06
//自定义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 }
//自定义反射贴图材质(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允许按照权重混合两个颜色 }
reflectionBlur = 6的效果
导入了黑白格子的模糊贴图后效果
进行反射混合之后的效果
//水晶、透明等类似材质的折射效果 //自定义函数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时情况
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
//自定义参数: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); }
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; }