其oneMinusReflectivity = 1-SpecularStrength(specColor);//SpecularStrength函数是来获取rgb通道最大值;
oneMinusReflectivity 用于计算IBL reflection的菲涅尔项,具体可看源码,但是我不知道算法的原理==;
注意:unity_ColorSpaceDielectricSpec在unity内部的值为half4(0.04, 0.04, 0.04, 1.0 - 0.04) //linear space
half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity));
FresnelLerp (specColor, grazingTerm, nv);
其它项为:
half surfaceReduction;
# ifdef UNITY_COLORSPACE_GAMMA
surfaceReduction = 1.0-0.28*roughness*perceptualRoughness; // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]
# else
surfaceReduction = 1.0 / (roughness*roughness + 1.0); // fade \in [0.5;1]
# endif
注意:只有含有shadowcaster pass的物体才可以渲染进_CameraDepthTexture,并且只能是不透明物体( render queue <= 2500);参考Unity官方文档
came.depthTextureMode = DepthTextureMode.Depth;
;此时,可以直接使用_CameraDepthTexture,并且MSAA与HDR一起开好像也没问题;查看frame debugger,会发现先渲染_CameraDepthTexture深度图,然后在渲染一张ShadowMap,然后才开始正常的渲染流程;UnpackNormal(tex2D(_BumpMap, i.uv));
half3 UnpackScaleNormal(half4 packednormal, half bumpScale);
float3 normalWorld = UnityObjectToWorldNormal(v.normal);
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
half3x3 tangentToWorld = CreateTangentToWorldPerVertex(half3 worldNormal, half3 worldTangent, half tangentSign)
{
// For odd-negative scale transforms we need to flip the sign
half sign = tangentSign * unity_WorldTransformParams.w;
half3 binormal = cross(normal, tangent) * sign;
return half3x3(tangent, binormal, normal);
}
o.tangent = tangentToWorld[0];
o.binormal = tangentToWorld[1];
o.normal = tangentToWorld[2];
inline bool IsGammaSpace();
inline half3 GammaToLinearSpace (half3 sRGB);
inline half3 LinearToGammaSpace (half3 linRGB);
阴影的投射只要有shadow caster通道即可;
阴影接受的计算:
方法一:
#pragma multi_compile_fwdbase
#include “AutoLight.cginc”
SHADOW_COORDS(1) // put shadows data into TEXCOORD1
TRANSFER_SHADOW(o)
fixed shadow = SHADOW_ATTENUATION(i);
方法二:
#pragma multi_compile_fwdbase
// after CGPROGRAM;
#include "AutoLight.cginc"
// in v2f struct;
LIGHTING_COORDS(0,1) // replace 0 and 1 with the next available TEXCOORDs in your shader, don't put a semicolon at the end of this line.
// in vert shader;
TRANSFER_VERTEX_TO_FRAGMENT(o); // Calculates shadow and light attenuation and passes it to the frag shader.
//in frag shader;
float atten = LIGHT_ATTENUATION(i); // This is a float for your shadow/attenuation value, multiply your lighting value by this to get shadows. Replace i with whatever you've defined your input struct to be called (e.g. frag(v2f [b]i[/b]) : COLOR { ... ).
方法三:
#pragma multi_compile_fwdbase
#include "AutoLight.cginc"
UNITY_LIGHTING_COORDS(6,7)
UNITY_TRANSFER_LIGHTING(o, v.uv1);
UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld);
注意:其计算空间为tangent space;
按照unity的顶点变换流程,mul( UNITY_MATRIX_MVP, v.vertex)的结果进行归一化后应位于NDC空间,即xyz的范围都为[-1, 1]。
但是在shader手动进行归一化后发现z的范围为[1,0];感觉很奇怪,而如果采用脚本中获取相机的vp矩阵计算,归一化后其深度范围刚好为[-1,1];
事实证明shader中的VP矩阵与相机中的VP矩阵根本不一致;
具体可参考这里;
原文为:
Note: On DX11/12, PS4, XboxOne and Metal, the Z buffer range is 1–0 and UNITY_REVERSED_Z is defined. On other platforms, the range is 0–1.
原文中的宏被废弃了,文档也不更新,呵呵呵。。。
另外使用unity内部的_CameraDepthTexture时,其范围是(0,1);
获取shader中所使用VP:
由于DX平台与OpenGL平台的差异性,unity使用了GL类来进行两者的统一,同样使用该库来进行统一的渲染,因此我们可以使用该库来获取shader中VP矩阵:
Matrix4x4 projectionMatrix = GL.GetGPUProjectionMatrix(mCamera.projectionMatrix, true);
unity_MatrixVP = projectionMatrix * mCamera.worldToCameraMatrix;
参考这里
没事多看看unity内部源码,想用什么从里面摘什么==