unity里standard pbr(一)
Posted marcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV SHADOW_COORDS(6) UNITY_FOG_COORDS(7) // 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[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV SHADOW_COORDS(6) UNITY_FOG_COORDS(7) 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[0].xyz = tangentToWorld[0]; o.tangentToWorldAndParallax[1].xyz = tangentToWorld[1]; o.tangentToWorldAndParallax[2].xyz = tangentToWorld[2]; #else o.tangentToWorldAndParallax[0].xyz = 0; o.tangentToWorldAndParallax[1].xyz = 0; o.tangentToWorldAndParallax[2].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[0].w = viewDirForParallax.x; o.tangentToWorldAndParallax[1].w = viewDirForParallax.y; o.tangentToWorldAndParallax[2].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(一)的主要内容,如果未能解决你的问题,请参考以下文章