unity里standard pbr(一)
关注forwardbase下的
standard.shader
#pragma vertex vertBase
#pragma fragment fragBase
#include "UnityStandardCoreForward.cginc"
跟踪到UnityStandardCoreForward.cginc
#if UNITY_STANDARD_SIMPLE
#include "UnityStandardCoreForwardSimple.cginc"
VertexOutputBaseSimple vertBase (VertexInput v) { return vertForwardBaseSimple(v); }
VertexOutputForwardAddSimple vertAdd (VertexInput v) { return vertForwardAddSimple(v); }
half4 fragBase (VertexOutputBaseSimple i) : SV_Target { return fragForwardBaseSimpleInternal(i); }
half4 fragAdd (VertexOutputForwardAddSimple i) : SV_Target { return fragForwardAddSimpleInternal(i); }
#else
#include "UnityStandardCore.cginc"
VertexOutputForwardBase vertBase (VertexInput v) { return vertForwardBase(v); }
VertexOutputForwardAdd vertAdd (VertexInput v) { return vertForwardAdd(v); }
half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseInternal(i); }
half4 fragAdd (VertexOutputForwardAdd i) : SV_Target { return fragForwardAddInternal(i); }
#endif
UNITY_STANDARD_SIMPLE开关是简化版意思,进下边的分支
顶点着色器 vertForwardBase
先看输出
struct VertexOutputForwardBase
{
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
half3 eyeVec : TEXCOORD1;
half4 tangentToWorldAndParallax[] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax]
half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV
SHADOW_COORDS()
UNITY_FOG_COORDS() // next ones would not fit into SM2.0 limits, but they are always for SM3.0+
#if UNITY_REQUIRE_FRAG_WORLDPOS
float3 posWorld : TEXCOORD8;
#endif #if UNITY_OPTIMIZE_TEXCUBELOD
#if UNITY_REQUIRE_FRAG_WORLDPOS
half3 reflUVW : TEXCOORD9;
#else
half3 reflUVW : TEXCOORD8;
#endif
#endif UNITY_VERTEX_OUTPUT_STEREO
};
UNITY_REQUIRE_FRAG_WORLDPOS要不要worldpos,要
reflUVW是用来做反射的,要
UNITY_VERTEX_OUTPUT_STEREO 是用来做实例化的,不要
简化成
struct VertexOutputForwardBase
{
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
half3 eyeVec : TEXCOORD1;
half4 tangentToWorldAndParallax[] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax]
half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV
SHADOW_COORDS()
UNITY_FOG_COORDS()
float3 posWorld : TEXCOORD8;
half3 reflUVW : TEXCOORD9;
};
再来看顶点着色器
VertexOutputForwardBase vertForwardBase (VertexInput v)
{
VertexOutputForwardBase o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
#if UNITY_REQUIRE_FRAG_WORLDPOS
o.posWorld = posWorld.xyz;
#endif
o.pos = UnityObjectToClipPos(v.vertex); o.tex = TexCoords(v);
o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
float3 normalWorld = UnityObjectToWorldNormal(v.normal);
#ifdef _TANGENT_TO_WORLD
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
o.tangentToWorldAndParallax[].xyz = tangentToWorld[];
o.tangentToWorldAndParallax[].xyz = tangentToWorld[];
o.tangentToWorldAndParallax[].xyz = tangentToWorld[];
#else
o.tangentToWorldAndParallax[].xyz = ;
o.tangentToWorldAndParallax[].xyz = ;
o.tangentToWorldAndParallax[].xyz = normalWorld;
#endif
//We need this for shadow receving
TRANSFER_SHADOW(o); o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld); #ifdef _PARALLAXMAP
TANGENT_SPACE_ROTATION;
half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
o.tangentToWorldAndParallax[].w = viewDirForParallax.x;
o.tangentToWorldAndParallax[].w = viewDirForParallax.y;
o.tangentToWorldAndParallax[].w = viewDirForParallax.z;
#endif #if UNITY_OPTIMIZE_TEXCUBELOD
o.reflUVW = reflect(o.eyeVec, normalWorld);
#endif UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
UNITY_SETUP_INSTANCE_ID是instance用的,不要
UNITY_INITIALIZE_OUTPUT啥也没干,不要
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO不要
NormalizePerVertexNormal相等于什么都没做
_TANGENT_TO_WORLD是切线空间和世界空间转换矩阵 保留
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
因为打算用pbr来做角色,没有lightmap,所以这儿等于
o.ambientOrLightmapUV = 0 ;
_PARALLAXMAP视差贴图,不用
去掉分支后代码如下
VertexOutputForwardBase vertForwardBase (VertexInput v)
{
VertexOutputForwardBase o;
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
o.posWorld = posWorld.xyz;
o.pos = UnityObjectToClipPos(v.vertex);
o.tex = TexCoords(v);
o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
float3 normalWorld = UnityObjectToWorldNormal(v.normal);
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
o.tangentToWorldAndParallax[0].xyz = tangentToWorld[0];
o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1];
o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2];
//We need this for shadow receving
TRANSFER_SHADOW(o);
o.ambientOrLightmapUV = 0;
o.reflUVW = reflect(o.eyeVec, normalWorld);
UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
至此顶点着色器完事,下篇开始像素着色器
unity里standard pbr(一)的更多相关文章
- 关于unity里pbr技术和材质 unity5默认shader和传统的对比
刚开始也不知道什么是pbr (Physically Based Rendering)后来才发现这是一种新的渲染方式 与之对应的是材质是pbs(Physically Based Shader) unit ...
- 【Unity Shaders】Unity里的雾效模拟
写在前面 熟悉Unity的都知道,Unity可以进行基本的雾效模拟.所谓雾效,就是在远离我们视角的方向上,物体看起来像被蒙上了某种颜色(通常是灰色).这种技术的实现实际上非常简单,就是根据物体距离摄像 ...
- Unity里的人物驱动/换装备/换武器/换衣服/卡通重定位(转)
Unity里的人物驱动/换装备/换武器/换衣服/动画重定位 刚学的过程被这个问题困扰最多. 首先,基本的,大家都知道驱动人物需要骨架.绑骨的Mesh和动画(这三个要是不知道的话就得考虑看看计算机图形学 ...
- Unity里的Mesh属性
----------------------------------------------------------------------------------------------- Mesh ...
- 用C# 模拟实现unity里的协程
注:需要了解C#的迭代器,不然很难理解. 之前面试有被问到unity协程的原理,以及撇开unity用纯C#去实现协程的方法.后来了解一下,确实可以的.趁这会有空,稍微总结一下. 还是结合代码说事吧: ...
- unity, access standard shared emission by script
unity 5.1.1f1 personal 用下面方法在脚本中设置standard shader的emssion: gameObject.GetComponent<MeshRenderer&g ...
- standard pbr(二)
下一步看像素着色器代码 half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseInternal( ...
- Unity里包裹Debug,且不影响Debug的重定向
Debug.Log, Debug.LogWarning, Debug.LogError在project中常常须要再包裹一层.做些定制.也方便开关Log.但有一个问题时.当用一个类将Debug包裹起来后 ...
- FairyGUI编辑器的和unity里的Obj对应关系
1.在FairyGUI官网上下载好unity的工程,用FairyGUI编辑器打开它的官方案例 2.在FairyGUI编辑器和Unity中,从一个最简单的示例"Bag"着手. ...
随机推荐
- Poj 4227 反正切函数的应用
Description 反正切函数可展开成无穷级数,有例如以下公式 (当中0 <= x <= 1) 公式(1) 使用反正切函数计算PI是一种经常使用的方法.比如,最简单的计算PI的方法: ...
- Android官方SwipeRefreshLayout
App基本都有下拉刷新的功能,以前基本都使用PullToRefresh或者自己写一个下拉刷新,Google提供了一个官方的下拉刷新控件SwipeRefreshLayout,简单高效,满足一般需求足够了 ...
- Linux非阻塞IO(三)非阻塞IO中缓冲区Buffer的实现
本文我们来实现回射服务器的Buffer. Buffer的实现 上节提到了非阻塞IO必须具备Buffer.再次将Buffer的设计描述一下: 这里必须补充一点,writeIndex指向空闲空间的 ...
- 【Excle数据透视表】如何在数据透视表顶部显示列总计数据
解决方案 创建组并修改组名称为“合计” 如下图:原始数据透视表 步骤 选中列标签区域→右键→组合 修改组合的名称为“合计” 此时底部会有一个合计汇总项,只需要单击数据透视表任意单元格→数据透视表工具→ ...
- session的两个小案例
学完了session,写两个小案例加深一下对session的巩固. 1. 用户登陆案例 登陆html页面提交后,将参数带给处理登陆的servlet,该servlet将获得登陆的用户名和密码,并将这些信 ...
- tony_update yum
更改方法是这样的 在 /etc/yum.repos.d 下 1 wget http://mirrors.163.com/.help/CentOS6-Base-163.repo 2 #mv Cen ...
- JSON-Schema 最科学的表单验证模式
相关传送门: # JSON schema与表单验证 https://mp.weixin.qq.com/s?__biz=MjM5MTA1MjAxMQ==&mid=2651226711&i ...
- QT项目性能调优小记
最近的项目用到了QT 5.5,项目在运行过程中出现了一段时间CPU占用率持续25%,并频繁断网的情况,遂决定对项目性能进行优化. 优化工具也是VS2010自带的性能分析工具,具体的使用方法参见:htt ...
- kubernetes高级之动态准入控制
系列目录 动态准入控制器文档介绍了如何使用标准的,插件式的准入控制器.但是,但是由于以下原因,插件式的准入控制器在一些场景下并不灵活: 它们需要编译到kube-apiserver里 它们仅在apise ...
- Thread 常搞混的几个概念sleep、wait、yield、interrupt
sleep:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响.该线程不丢失任何监视器的所属权. 通过调用sleep使任务进入休眠状态,在这种情况下 ...