Unity Shader开发案例精讲

Unity Shader Development

默认教学计划
25人加入学习
(0人评价)
价格 ¥99.00
教学计划
承诺服务

突然就全程看不懂了!!!!看不懂!!!

好懵逼!!!!懵逼!!!

 

镜面反射的数量_specularAmount,range

 强弱_SpecularPower

方向_AnisoDir,2D

纹理的偏移控制_AnisoOffset ,range(-1,1)

声明变量

#pragma surface surf AnisotropicSpec

创建自定义的表面输出结构体

struct SurfaceAnisoOutput{

 

 

fixed3 Normal;

fixed3 Emission;自发光

fixede3 AnisoDirection;各向异性方向

half Specular;镜面反射系数

fixerde Gloss;高光系数

fixede ALpha;

}

void surf(Input In,inout SurfaceAnisoOutput o)

 

fixed4 LightingAnisotropicSpec(SurfaceAnisoOutputs,fxied3 lightdir,half3 viewDir,fixed atten{}

fixed3 halfVector=normallize(normalize(lightDir,)normal(viewDir));

float NdotL=saturate(dot(s.normal,lightDir));

fixed HdotA=dot(normallize(s.Normal,s.AnisoDirection),halvVector);

float aniso=max(0,sin(radians(HdotA+_AnisoOffset)*180));各向异性系数
float spec=saturate(

pow(aniso,s.Gloss*128)*s._SpecularAmount

)

c.rgb=(s.Albedo*_LightColor0*NdotL+_LightColor0.rgb*_SpecularColor.rgb*spec)*atten;

c.a=s.Alpha;

return c;

 

)

 

 

 

[展开全文]

fixed4 LightingcustomBlinnPhong(SurfaceOUtput s,fixed3 lightDir,half3 viewDir,fixed atten) {

float NdotL=max(0,dot(s.Normal,lightDir));

float3 halfVector=normalize归一化(lightdir+viewdir(光线个饭视图中间的方向))

float NdotH=max(0,dot(s.Normal,halfVector));

flaot spec=pow(NdotH,_SpecPower)

float4 c;

c.rgb=(s.Albedo*LightColor0.rgb*NdotL)+(_LightColor0.rb*_Specularcolor.rgb*spec)*atten;

c.a=s.Alpha;

return c;

}

---------------------------------------------------

 

[展开全文]

_MainTint漫反射主色调;

_SpecularColor镜面反射颜色;

_SpecPower range 镜面反射强度;

 fixed4 LightingCunsotmPhong(SufaceOutput s,fixede3 lightDir光线方向,half3 viewDir师徒方向,fixed atten衰减率){

//Reflection 反射部分

float NdotL=dot(s.Normal,lightDir);

float3 reflctiongVector=normalize标准化(2.0*s.Normal*NdotL-lightDir}**********001

//specular镜面反射部分


 float spec=pow(

max(0,dot(reflectiongVector,viewDir))),_SpecPower);

float3 finalSpec=_SpecularColor.rgb*spec;

//finaleffect最后效果

fixed4 c;

c.rgb=(s.Albedo*_LightColor0.rgb*max(0,NdotL)*atten)漫反射部分+(_LightColor0.rgb*finalspec);

c.a=s.Alpha;

return c;

}

______________________________________________

常用光照函数:

非视线依赖:

half4 Lightingxxxxx(SurfaceOutput s,half3 lightdir,half atten);

视线依赖:

half4 Lightingxxxx(SurfaceOutput s,half3 lightdir,half3 viewdir,half atten);

______________________________________________

 

[展开全文]

Ramp map 坡度映射

wrap mode :clamp,不需要重复,保持边界就可以了

filter mode point 边缘比较明显;

_RampTex("Ramp",2D)

#pragma surface suf Toon(卡通)

fixed4 LightingToon(SurfaceOutput s,fixed3 lightDir,fixed atten衰减率)

{

half NdotL=dot(s.Normal,LightDir);

NdotL=tex2D(_RampTex,fixed2(NdotL,0.5));

fixed4c;

c.rgb=s.Albedo*_LightColor0.rgb*NdotL*atten;

c.a=s.Alpha;

return c;

}

______________________________________________

 half4 LightingToon2((SurfaceOutput s,fixed3 lightDir光线强度,half3 viewDir观察方向,fixed atten衰减率))

{

half NdotL=dot(s.Normal,LightDir);

half toon=floor(NdotL*_ToonShadingLevels记得之前要声明一下)/(ToonShadingLevels-0.5)

half4 c;

c.rgb=s.albedo*_LightColor0*toon*atten;

c.a=s.Alpha;

return c;

}

 

 

[展开全文]

#pragma surface surf SimpleLambert(这个单词是自定义)

surf  inout SurfaceOutput就可以

根据uv数据采样tex2D(纹理,uv);

光照模型计算的函数,返回值都是half4

half4 Lighting接光照模型的名字SimpleLambert()

记得加Lighting,会自动对应

接收表面输出结构体,给光照模型处理函数使用,接收光照方向,接收光线衰减率atten

half4 LightingSimpleLambert(SurfaceOutput s,half3 lightDir,half atten){

本节课要实现反射

half NdotL=dot(s.Normal,lightDir);

half4 c;

c.rgb=s.Albedo(表面无光照的纹理也就是表面输出结构体的albedo)*_LightColor0(Unity内置光线颜色).rgb*(NdotL*atten)(夹角跟衰减);

c.a=s.Alpha;

return c;(直接返回光照颜色)

}

------------------------------------------------

预编译器指令pragma

使用了函数surf

使用了光照模型SimpleLambert,

让unity去寻找LightingSimpleLambert;

光线处理函数LightingSimpleLambert接收:

表面函数输出体SurfaceOutput s,有各种参数,albedo啥的

lambert模型漫反射表面反射光的数量取决于夹角

dot(光线,法线),就是夹角,

[展开全文]

_Center("",Vector),位置;

_Radius,float圆环大小;

_RadiusColor 颜色

_RadiusWidth 宽度,float,

subshader

定义刚才那些

input

定义世界坐标中心

surf

求一下当前绘制位置跟中心位置的距离

float d=distance(_Center,In.worldPos);

if(d>Radius&&d<_Radius+_RadiusWidth )

o.Albedo=_RadiusColor;

else

o.Albedo=tex2D(_Maintex,IN.un_Maintex).rgb;

识别地形就行了

---------------------------------------------

[展开全文]

 属性:

主色调_MainTint("Diffuse Tint",Color)=1,1,1,1)

_ColorA("Terrain ColorA")

_ColorA("Terrain ColorA")

_RTexture("Red Channel Texture",2D)=""{}

_G..._B..._A...

_Blend Texture控制融合的纹理

subshader里面添加

float4 _MainTint;_ColorA..

sampler2D _RTexture...G..B..A..Blend..

只要用lambert,阴影不需要,

注意输入参数要变成SurfaceOutput

设置Input ,

float2 uv_R..B..G..A..Blend..Texture;

修改surf函数;

float4 blendData=tex2D(_BlendTex,IN.uv_BlendTex);

rgba..

tex2D进行采样之后,通过差值函数,融合每个纹理

1.2参数是要融合的纹理,3是融合的比例(系数)

float4 finalcolor;

finalcolor=lerp(rTexData,gTexData,blendData.g);

finalcolor=lerp(finalColor,bTexData,blendData.b);

finalcolor=lerp(finalColor,aTexData,blendData.a);

finalcolor.a=1.0;

给两个颜色差值;

flaot4 色调terrainLayers=lerp(_ColorA,_ColorB,_blendDAta.r);

finalColor*=terrainLayers;

可能会超过1,所以约束一下

finalColor=saturate(finalColor);

o.Albedo=finalColor*_MainTint.rgb;

o.Alpha=finalColor.a;

 

=========================

共用一个UV值,纹理过多的时候,或者target提高等级,不过老旧的GPU不支持,

--------------------------------------------

lerp(a,b,f)使用线性插值:(1-f)*a+b*f,

a,b是矢量或者标量,f可以使用和a与b相同的类型;

 

[展开全文]

holographics全息投影

 _RimEffect边缘效果range;

float _RimEffect

半透明效果,Tags:

RenderType=Transparent;

IgnoreProjector=True

Queue=Transparent

Cull Off 关闭剔除;

Lighting Off 关闭光照;

不是一个模拟现实 的所以不要standard,用个简单的,

#pragma surface surf Lambert alpha:fade

struct input

 float3 worldNormal世界法向;

float3 viewDir;视图方向

兰伯特光照模型 的inout是SurfaceOutput;

----求边缘;

当前定点法向与视图方向平行,在正中,垂直,在边缘;

float border=1-abs(dot(In.viewDir,IN.worldNormal));

求的点积;

越中心越透明;

float alpha=(border*(1-_RimEffect)+_RimEffect);

o.Alpha=c.a*alpha;

———————————————————

 

[展开全文]

transparent透明材质

标签:RenderType =Transparent

IgnoreProjector=True忽视其他物体

Queue=Transparent 透明的队列

 

Cull Back剔除背面物体;

#pragma surface surf Standard alpha:fade(a通道的融合)

————————————————————

Tags添加渲染信息,描述如何渲染;

Queue默认按照距离相机顺序;

Background是第一个,队列值1000;

Geometry 默认,不透明几何体,2000;

Alpha Test ,所有实体对象绘制完之后,对alpha效率更高,2450;

Transarent 在Geometry跟Alpha Test之后渲染,任何需要alpha融合(alpha blending,不写入深度缓存中),玻璃,粒子都在这,3000;

Overlay 叠加特效,镜头炫光什么的,4000;

 

[展开全文]

面板:

_NormalTex("Normal MAp",2D)="bump"{}

添加变量

sampler2D _NormalTex;

获取法线UV值:

struct Input{

      float2 uv_NoamalTex;

}

void surf..

   float3 normalMap=UnpackNormal(tex2D(_NormalTex,IN.uv_NormalTex));(解析法线映射)

o.Normal=naomalMap;

o.Alebdo=_Color.rgb;

o.Alpha=_Color.a;

 

UnpackNormal

unity自带:

安装目录/Contents/CGIncludes/UnityCG.cginc

也可以加个强度,

属性,变量,normalMap.x*=...;

o.Normal=normalize//单位矢量//(normalMap)

[展开全文]

Tint色调

内置时间变量_Time

================================

fixed2 scrolledUV=IN.uv_MainTex;

fixed xScrollValue=_ScrollingXSpeed*_Time;

y...

=================================

面板显示XY滚动速度range,显示漫反射颜色MainTint;

声明属性;xy滚动、漫反射;

获取主纹理uv值:

fixed2 scrolledUV=IN.uv_MainTex;

获得XY方向纹理偏移量;

fixed xScrollValue=_ScrollingXSpeed*_Time;

偏移量封装在fixed2(xScrollValue,yScrollValue)---

新的纹理值是scrolledUV += fixed2(xScrollValue,yScrollValue)

获取信息:

half4 c=tex2D(_Maintex,scrolledUV);

输出o.Albedo=c.rgb*_MainTint;

o.Alpha=c.a;

--------------------------------------

_Time变量,float4类型,

t是shader开始运行之后所经过的时间;

t,(t/20,t,t*2,t*3)四个分量

_SinTime变量,float4

t,(t/8,t/4,t/2,t)

_CosTime,float4

t,(t/8,t/4,t/2,t)

unity_DeltaTime,float4

dt,(dt,1/dt,smoothDT(柔和变换),1/SmoothDt)

 

[展开全文]

tex2D-内置函数,接收纹理 跟uv数据

Filter Mode 颜色采样的差值方式;

bilinear双线性差值;

如果开发2D游戏,有点糊,需要用point,不差值;找个最近的作为返回值;大角度观察的时候 

anisolevel 各向异性等级,调大,可以减少大角度人工痕迹;比如地面,

[展开全文]

CG语言特殊的数据结构-压缩数组

CG里两种变量:单值,压缩数组

例如:float3,int4,若干个单值组成的

xyzw跟rgba没有什么本质的不同只是看着方便;

·o.Alpha=_Color.a

o为结构体,_Color是压缩数组;

特点

混写swizzling

o.Albedo=_Color.rgb

//如果是C#那就要变成

//o.Albedo.r=_Color.r

//o.Albedo.g=_Color.g

//o.Albedo.b=_Color.b

也可以调换

_Color.bgr

也可以一起赋值(涂抹smearing)

o.Albedo=0//(0,0,0)

遮罩masking

o.Albedo.rg=_Color.rg

-----------------------------------------

float4X4 matrix;

//......

float first=matrix._m00//_m是members成员的意思

float last=matrix._mm33;

float4 diagonal=matrix._m00_11_22_33

float4 firstRow=matrix[0]//获取第一行

[展开全文]

3D model→Vertex modifiler→input输入结构体→ Surface functions surf函数→SurfaceOutput表面输出结构体→光照模型Lighting model

*surf就是将我们在场景中获得到的数据经过运算填充到表面输出结构体中,表面数出结构体再被传递到光照模型里进行光照计算;

*所以surf如何计算很重要

SurfaceOutput结构体属性:

·fixed3 Albedo 材质的漫反射颜色

·fixed3 Normal 切空间法线

·fixed3 Emission 材质的自发光颜色

·fixed Alpha 材质的透明度

·half Specular 镜面反射强度,0-1

·fixed Gloss 高光强度

SurfaceOutputStandard结构体的属性:

·fixed3 Albedo 材质的基本颜色

·fixed3 Normal 切空间法线

·half3 Emission 材质的自发光颜色

·fixed Alpha 材质的透明度

·half Occlusion 遮挡率,默认是1

·half Smoothness 光滑度,0粗糙,1光滑

·half Metallic 金属度,0非金属,1金属

SurfaceOutputStandardSpecular结构体属性:

·fixed3 Albedo 材质的基本颜色

·fixed3 Normal 切空间法线

·half3 Emission 材质的自发光颜色

·fixed Alpha 材质的透明度

·half Occlusion 遮挡率,默认是1

·half Smoothness 光滑度,0粗糙,1光滑

·fixed3 Specular镜面反射颜色。与SurfaceOutput里面的Specular属性完全不同,这里指定更丰富的颜色信息。

--------------------------------------

 

[展开全文]

授课教师

客户端高级开发、高级讲师

课程特色

视频(47)
下载资料(24)