public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            ShaderReferenceUtil.DrawTitle("Math");
            ShaderReferenceUtil.DrawOneContent("abs (x)", "取绝对值,即正值返回正值,负值返回的还是正值,x值也可以为向量\n" +
                                               "float abs(float a)\n" +
                                               "{\n" +
                                               "    return max(-a, a);\n" +
                                               "}");

            ShaderReferenceUtil.DrawOneContent("acos (x)", "反余切函数,输入参数范围为[-1, 1],返回[0, π] 区间的角度值");
            ShaderReferenceUtil.DrawOneContent("all (a)", "当a或a的所有分量都为true或者非0时返回1(true),否则返回0(false).\n" +
                                               "bool all(bool4 a)\n" +
                                               "{\n" +
                                               "    return a.x && a.y && a.z && a.w;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("any (a)", "如果a=0或者a中的所有分量为0,则返回0(false);否则返回1(true).\n" +
                                               "bool any(bool4 a)\n" +
                                               "{\n" +
                                               "    return a.x || a.y || a.z || a.w;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("asin (x)", "返回x的反正弦值,范围为(-π/2,π/2)");
            ShaderReferenceUtil.DrawOneContent("atan2 (y,x)", "返回y/x的反正切值");
            ShaderReferenceUtil.DrawOneContent("atan (x)", "返回x的反正切值,范围为(-π/2,π/2),表示弧度");
            ShaderReferenceUtil.DrawOneContent("ceil (x)", "对x进行向上取整,即x=0.1返回1,x=1.5返回2,x=-0.3返回0\n" +
                                               "float ceil(float x)\n" +
                                               "{\n" +
                                               "    return -floor(-x);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("clamp(x,a,b)", "如果 x 值小于 a,则返回 a;如果 x 值大于 b,返回 ;否则,返回 x.\n" +
                                               "float clamp(float x, float a, float b)\n" +
                                               "{\n" +
                                               "    return max(a, min(b, x));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("clip (x)", "如果x<0则裁剪掉此片断\n" +
                                               "void clip(float4 x)\n" +
                                               "{\n" +
                                               "    if (any(x < 0))\n" +
                                               "    discard;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("cosh (x)", "双曲余弦函数\n" +
                                               "float cosh(float x)\n" +
                                               "{\n" +
                                               "    return 0.5 * (exp(x) + exp(-x));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("cross (a,b)", "返回两个三维向量a与b的叉积\n" +
                                               "float3 cross(float3 a, float3 b)\n" +
                                               "{\n" +
                                               "    return a.yzx * b.zxy - a.zxy * b.yzx;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("degrees (x)", "将x从弧度转换成角度\n" +
                                               "float degrees(float x)\n" +
                                               "{\n" +
                                               "    return 57.29577951 * x;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("determinant (M)", "返回方阵M的行列式,注意只有方阵才有行列式");
            ShaderReferenceUtil.DrawOneContent("dot (a,b)", "点乘,a和b可以为标量也可以为向量,其计算结果是两个向量夹角的余弦值,相当于|a|*|b|*cos(θ)或者a.x*b.x+a.y*b.y+a.z*b.z\na和b的位置无所谓前后,结果都是一样的");
            ShaderReferenceUtil.DrawOneContent("distance (a,b)", "返回a,b间的距离.\n" +
                                               "float distance(a, b)\n" +
                                               "{\n" +
                                               "    float3 v = b - a;\n" +
                                               "    return sqrt(dot(v, v));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("exp(x)", "计算e的x次方,e = 2.71828182845904523536");
            ShaderReferenceUtil.DrawOneContent("exp2 (x)", "计算2的x次方");

            ShaderReferenceUtil.DrawOneContent("floor (x)", "对x值进行向下取整(去尾求整)\n比如:floor (0.6) = 0.0,floor (-0.6) = -1.0");
            ShaderReferenceUtil.DrawOneContent("fmod (x,y)", "返回x/y的余数。如果y为0,结果不可预料,注意!如果x为负值,返回的结果也是负值!\n" +
                                               "float fmod(float a, float b)\n" +
                                               "{\n" +
                                               "    float c = frac(abs(a / b)) * abs(b);\n" +
                                               "    return (a < 0) ? -c : c;   /* if ( a < 0 ) c = 0-c */\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("frac (x)", "返回x的小数部分\n" +
                                               "float frac(float x)\n" +
                                               "{\n" +
                                               "    return x - floor(x);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("length (v)", "返回一个向量的模,即 sqrt(dot(v,v))");
            ShaderReferenceUtil.DrawOneContent("lerp (A,B,alpha)", "线性插值.\n如果alpha=0,则返回A;\n如果alpha=1,则返回B;\n否则返回A与B的混合值;内部执行:A + alpha*(B-A)\n" +
                                               "float3 lerp(float3 A, float3 B, float alpha)\n" +
                                               "{\n" +
                                               "    return A + alpha*(B-A);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("log (x)", "返回x的自然对数");
            ShaderReferenceUtil.DrawOneContent("max (a,b)", "比较两个标量或等长向量元素,返回最大值");
            ShaderReferenceUtil.DrawOneContent("min (a,b)", "比较两个标量或等长向量元素,返回最小值");
            ShaderReferenceUtil.DrawOneContent("mul (M,V)", "表示矩阵M与向量V进行点乘,结果就是对向量V进行M矩阵变换后的值");

            ShaderReferenceUtil.DrawOneContent("normalize (v)", "返回一个向量的归一化版本(方向一样,但是模为1)" +
                                               "\nnormalize(v) = rsqrt(dot(v,v))*v; rsqrt返回的是平方根的倒数");
            ShaderReferenceUtil.DrawOneContent("pow (x,y)", "返回x的y次方");
            ShaderReferenceUtil.DrawOneContent("reflect(I, N)", "根据入射光方向向量 I ,和顶点法向量 N ,计算反射光方向向量。其中 I 和 N 必须被归一化,需要非常注意的是,这个 I 是指向顶点的;函数只对三元向量有效。");
            ShaderReferenceUtil.DrawOneContent("refract(I,N,eta)", "计算折射向量, I 为入射光线, N 为法向量, eta 为折射系数;其中 I 和 N 必须被归一化,如果 I 和 N 之间的夹角太大,则返回( 0 , 0 , 0 ),也就是没有折射光线; I 是指向顶点的;函数只对三元向量有效。");
            ShaderReferenceUtil.DrawOneContent("round (x)", "返回x四舍五入的值");
            ShaderReferenceUtil.DrawOneContent("rsqrt (x)", "返回x的平方根倒数,注意x不能为0.相当于 pow(x, -0.5)");
            ShaderReferenceUtil.DrawOneContent("saturate (x)", "如果x<0返回0,如果x>1返回1,否则返回x.");
            ShaderReferenceUtil.DrawOneContent("sqrt (x)", "返回x的平方根.");
            ShaderReferenceUtil.DrawOneContent("step (a,b)", "如果a<b返回1,否则返回0.");
            ShaderReferenceUtil.DrawOneContent("sign (x)", "如果x=0返回0,如果x>0返回1,如果x<0返回-1.");
            ShaderReferenceUtil.DrawOneContent("smoothstep (min,max,x)", "float smoothstep (float min, float max, float x)\n" +
                                               "{\n" +
                                               "\tfloat t = saturate ((x - min) / (max - min));\n" +
                                               "\treturn t * t * (3.0 - (2.0 * t));\n" +
                                               "}\n" +
                                               "如果 x 比min 小,返回 0\n如果 x 比max 大,返回 1\n如果 x 处于范围 [min,max]中,则返回 0 和 1 之间的值(按值在min和max间的比例).\n如果只想要线性过渡,并不需要平滑的话,可以直接使用saturate((x - min)/(max - min))");

            ShaderReferenceUtil.DrawTitle("纹理采样");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawOneContent("tex1D(samper1D tex,float s)", "一维纹理采样");
                ShaderReferenceUtil.DrawOneContent("tex2D(samper2D tex,float2 s)", "二维纹理采样");
                ShaderReferenceUtil.DrawOneContent("tex2Dlod(samper2D tex,float4 s)", "二维纹理采样,s.w表示采样的是mipmap的几级,仅在ES3.0以上支持.");
                ShaderReferenceUtil.DrawOneContent("tex2DProj(samper2D tex,float4 s)", "二维投影纹理采样");
                ShaderReferenceUtil.DrawOneContent("texCUBE(samperCUBE tex,float3 s)", "立方体纹理采样");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("TEXTURE2D (textureName);", "二维纹理的定义(纹理与采样器分离定义),此功能在OpenGL ES2.0上不支持,会使用原来sampler2D的形式.\n" +
                                                   "textureName:Properties中声明的2D纹理.");
                ShaderReferenceUtil.DrawOneContent("SAMPLER(samplerName);", "采样器的定义(纹理与采样器分离定义),采样器是指纹理的过滤模式与重复模式,此功能在OpenGL ES2.0上不支持,相当于没写.\n" +
                                                   "1.SAMPLER(sampler_textureName):sampler+纹理名称,这种定义形式是表示采用textureName这个纹理Inspector面板中的采样方式.\n" +
                                                   "2.SAMPLER(_filter_wrap):比如SAMPLER(point_clamp),使用自定义的采样器设置,自定义的采样器一定要同时包含过滤模式<filter>与重复模式<wrap>的设置.\n" +
                                                   "3.SAMPLER(_filter_wrapU_wrapV):比如SAMPLER(linear_clampU_mirrorV),可同时设置重复模式的U与V的不同值.\n" +
                                                   "4.filter:point/linear/triLinear\n" +
                                                   "5.wrap:clamp/repeat/mirror/mirrorOnce");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURE2D(textureName, samplerName, coord);", "进行二维纹理采样操作\n" +
                                                   "textureName:Properties中声明的2D纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置" +
                                                   "coord:采样用的UV");
                break;
            }

            ShaderReferenceUtil.DrawTitle("常用指令");
            ShaderReferenceUtil.DrawOneContent("mov dest, src1", "dest = src1");
            ShaderReferenceUtil.DrawOneContent("add dest, src1, src2", "dest = src1 + src2 (可通过在src2前加-,实现减功能)");
            ShaderReferenceUtil.DrawOneContent("mul dest, src1, src2", "dest = src1 * src2");
            ShaderReferenceUtil.DrawOneContent("div dest, src1, src2", "dest = src1 / src2");
            ShaderReferenceUtil.DrawOneContent("mad dest, src1, src2 , src3", "dest = src1 * src2 + src3");
            ShaderReferenceUtil.DrawOneContent("dp2 dest, src1, src2", "(src1.x * src2.x) + (src1.y * src2.y)");
            ShaderReferenceUtil.DrawOneContent("dp3 dest, src1, src2", "(src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z)");
            ShaderReferenceUtil.DrawOneContent("dp4 dest, src1, src2", "(src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z) + (src1.w * src2.w)");
            ShaderReferenceUtil.DrawOneContent("rsq dest, src1", "rsqrt(src1) 对src1进行平方根的倒数,然后将值存入dest中");
            EditorGUILayout.EndScrollView();
        }
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            ShaderReferenceUtil.DrawTitle("光照模型");
            ShaderReferenceUtil.DrawOneContent("Lambertian", "Diffuse = Ambient + Kd * LightColor * max(0,dot(N,L))\n" +
                                               "Diffuse:\t最终物体上的漫反射光强.\n" +
                                               "Ambient:\t环境光强度,为了简化计算,环境光强采用一个常数表示.\n" +
                                               "Kd:\t物体材质对光的反射系数.\n" +
                                               "LightColor:\t光源的强度.\n" +
                                               "N:\t顶点的单位法线向量.\n" +
                                               "L:\t顶点指向光源的单位向量.");
            ShaderReferenceUtil.DrawOneContent("Phong", "Specular = SpecularColor * Ks * pow(max(0,dot(R,V)), Shininess)\n" +
                                               "Specular:\t最终物体上的反射高光光强.\n" +
                                               "SpecularColor:\t反射光的颜色.\n" +
                                               "Ks:\t反射强度系数.\n" +
                                               "R:\t反射向量,可使用2 * N * dot(N,L) - L或者reflect (-L,N)获得.\n" +
                                               "V:\t观察方向.\n" +
                                               "N:\t顶点的单位法线向量.\n" +
                                               "L:\t顶点指向光源的单位向量.\n" +
                                               "Shininess:\t乘方运算来模拟高光的变化.");
            ShaderReferenceUtil.DrawOneContent("Blinn-Phong", "Specular = SpecularColor * Ks * pow(max(0,dot(N,H)), Shininess)\n" +
                                               "Specular:\t最终物体上的反射高光光强.\n" +
                                               "SpecularColor:\t反射光的颜色.\n" +
                                               "Ks:\t反射强度系数.\n" +
                                               "N:\t顶点的单位法线向量.\n" +
                                               "H:\t入射光线L与视线V的中间向量,也称为半角向量H = normalize(L+V).\n" +
                                               "Shininess:\t乘方运算来模拟高光的变化.");
            ShaderReferenceUtil.DrawOneContent("Disney Principled BRDF", "f(l,v) = diffuse + D(h)F(v,h)G(l,v,h)/4cos(n·l)cos(n·v)\n" +
                                               "f(l,v):\t双向反射分布函数的最终值,l表示光的方向,v表示视线的方向.\n" +
                                               "diffuse:\t漫反射.\n" +
                                               "D(h):\t法线分布函数(Normal Distribution Function),描述微面元法线分布的概率,即朝向正确的法线浓度.h为半角向量,表示光的方向与反射方向的半角向量,只有物体的微表面法向m = h时,才会反射到视线中.\nD(h) = roughness^2 / π((n·h)^2(roughness^2-1)+1)^2\n" +
                                               "F(v,h):\t菲涅尔方程(Fresnel Equation),描述不同的表面角下表面所反射的光线所占的比率.\nF(v,h) = F0 + (1-F0)(1-(v·h))^5(F0是0度入射角的菲涅尔反射值)\n" +
                                               "G(l,v,h):\t几何函数(Geometry Function),描述微平面自成阴影的属性,即微表面法向m = h的并未被遮蔽的表面点的百分比.\n" +
                                               "4cos(n·l)cos(n·v):\t校正因子(correctionfactor)作为微观几何的局部空间和整个宏观表面的局部空间之间变换的微平面量的校正.");

            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawTitle("法线 NormalMap");
                ShaderReferenceUtil.DrawOneContent("使用切线空间下的法线",
                                                   "1.appdata中定义NORMAL与TANGENT语义.\n" +
                                                   "2.v2f中声明三个变量用于组成成切线空间下的旋转矩阵.\n" +
                                                   "   float3 tSpace0:TEXCOORD3;\n" +
                                                   "   float3 tSpace1:TEXCOORD4;\n" +
                                                   "   float3 tSpace2:TEXCOORD5;\n" +
                                                   "3.在顶点着色器中执行:\n" +
                                                   "   half3 worldTangent = UnityObjectToWorldDir(v.tangent);\n" +
                                                   "   //v.tangent.w:DCC软件中顶点UV值中的V值翻转情况.\n" +
                                                   "   //unity_WorldTransformParams.w:模型缩放是否有奇数负值. \n" +
                                                   "   half tangentSign = v.tangent.w * unity_WorldTransformParams.w;\n" +
                                                   "   half3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;\n" +
                                                   "   o.tSpace0 = float3(worldTangent.x,worldBinormal.x,worldNormal.x);\n" +
                                                   "   o.tSpace1 = float3(worldTangent.y,worldBinormal.y,worldNormal.y);\n" +
                                                   "   o.tSpace2 = float3(worldTangent.z,worldBinormal.z,worldNormal.z);\n" +
                                                   "4.在片断着色器中计算出世界空间下的法线,然后再拿去进行需要的计算:\n" +
                                                   "   half3 normalTex = UnpackNormalWithScale(tex2D(_NormalTex,i.uv),scale);\n" +
                                                   "   half3 worldNormal = half3(dot(i.tSpace0,normalTex),dot(i.tSpace1,normalTex),dot(i.tSpace2,normalTex));");
                ShaderReferenceUtil.DrawTitle("ShadowMap阴影");
                ShaderReferenceUtil.DrawOneContent("生成阴影", "添加\"LightMode\" = \"ShadowCaster\"的Pass.\n" +
                                                   "1.appdata中声明float4 vertex:POSITION;和half3 normal:NORMAL;这是生成阴影所需要的语义.\n" +
                                                   "2.v2f中添加V2F_SHADOW_CASTER;用于声明需要传送到片断的数据.\n" +
                                                   "3.在顶点着色器中添加TRANSFER_SHADOW_CASTER_NORMALOFFSET(o),主要是计算阴影的偏移以解决不正确的Shadow Acne和Peter Panning现象.\n" +
                                                   "4.在片断着色器中添加SHADOW_CASTER_FRAGMENT(i)");
                ShaderReferenceUtil.DrawOneContent("采样阴影", "" +
                                                   "1.在v2f中添加UNITY_SHADOW_COORDS(idx),unity会自动声明一个叫_ShadowCoord的float4变量,用作阴影的采样坐标.\n" +
                                                   "2.在顶点着色器中添加TRANSFER_SHADOW(o),用于将上面定义的_ShadowCoord纹理采样坐标变换到相应的屏幕空间纹理坐标,为采样阴影纹理使用.\n" +
                                                   "3.在片断着色器中添加UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos),其中atten即存储了采样后的阴影.");

                ShaderReferenceUtil.DrawTitle("Global Illumination 全局照明GI");
                ShaderReferenceUtil.DrawOneContent("产生间接光照", "添加\"LightMode\" = \"Meta\"的Pass.\n" +
                                                   "可参考内置Shader中的Meta Pass.");

                ShaderReferenceUtil.DrawTitle("Light Probe 光照探针");
                ShaderReferenceUtil.DrawOneContent("规则01", "当逐像素平行灯标记为Mixed时,同时场景内有LightProbe时,那么当前平行灯的光照值会自动被LightProbe影响,所以不管物体Shader中是否有SH相关的运算,都会受到LightProbe的影响.");
                ShaderReferenceUtil.DrawOneContent("规则02", "当逐像素平行灯标记为Baked时,同时场景内有LightProbe时,那么需要自行在物体Shader中添加SH相关的运算,才会受到LightProbe的影响.");

                ShaderReferenceUtil.DrawTitle("Reflection Probe 反射探针");
                ShaderReferenceUtil.DrawOneContent("反射探针的采样", "反射探针中当前激活的CubeMap存储在unity_SpecCube0当中,必须要用UNITY_SAMPLE_TEXCUBE进行采样,然后需要对其进行解码\n" +
                                                   "   half3 worldView = normalize (UnityWorldSpaceViewDir (i.worldPos));\n" +
                                                   "   half3 R = reflect (-worldView, N);\n" +
                                                   "   half4 cubemap = UNITY_SAMPLE_TEXCUBE (unity_SpecCube0, R);\n" +
                                                   "   half3 skyColor = DecodeHDR (cubemap, unity_SpecCube0_HDR);");

                ShaderReferenceUtil.DrawTitle("Fog 雾效");
                ShaderReferenceUtil.DrawOneContent("unity_FogColor", "内置雾效颜色值");
                ShaderReferenceUtil.DrawOneContent("方案一:", "常规方案\n" +
                                                   "1.#pragma multi_compile_fog声明雾效所需要的内置变体:FOG_LINEAR FOG_EXP FOG_EXP2.\n" +
                                                   "2.UNITY_FOG_COORDS(idx): 声明顶点传入片断中的雾效插值器(fogCoord).\n" +
                                                   "3.UNITY_TRANSFER_FOG(o,o.vertex): 在顶点着色器中计算雾效采样.\n" +
                                                   "4.UNITY_APPLY_FOG(i.fogCoord, col): 在片断着色器中进行雾效颜色混合.");
                ShaderReferenceUtil.DrawOneContent("方案二:", "当在v2f中有定义worldPos时,可以把worldPos.w利用起来做为雾效值.\n" +
                                                   "1.#pragma multi_compile_fog声明雾效所需要的内置变体:FOG_LINEAR FOG_EXP FOG_EXP2.\n" +
                                                   "2.UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o,o.positionCS): 在顶点着色器中添加,会自动取o.worldPos.z=裁剪空间下的坐标z值.\n" +
                                                   "3.UNITY_EXTRACT_FOG_FROM_WORLD_POS(i): 在片断着色器中添加.\n" +
                                                   "4.UNITY_APPLY_FOG(_unity_fogCoord, c): 在片断着色器中进行雾效颜色混合.");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawTitle("法线 NormalMap");
                ShaderReferenceUtil.DrawOneContent("使用切线空间下的法线",
                                                   "1.Attributes中定义NORMAL与TANGENT语义.\n" +
                                                   "2.Varyings中声明三个变量用于组成成切线空间下的旋转矩阵.\n" +
                                                   "   half4 normalWS      :TEXCOORD3;\n" +
                                                   "   half4 tangentWS     :TEXCOORD4;\n" +
                                                   "   half4 bitangentWS   :TEXCOORD5;\n" +
                                                   "3.在顶点着色器中执行:\n" +
                                                   "   o.normalWS.xyz = TransformObjectToWorldNormal(v.normalOS);\n" +
                                                   "   o.tangentWS.xyz = TransformObjectToWorldDir(v.tangentOS.xyz);\n" +
                                                   "   half sign = v.tangentOS.w * GetOddNegativeScale();\n" +
                                                   "   o.bitangentWS.xyz = cross(o.normalWS, o.tangentWS) * sign;\n" +
                                                   "4.在片断着色器中计算出世界空间下的法线,然后再拿去进行需要的计算:\n" +
                                                   "   half3 normalMap = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv),scale);\n" +
                                                   "   half3 normalWS = mul(normalMap,half3x3(i.tangentWS.xyz, i.bitangentWS.xyz, i.normalWS.xyz));");
                ShaderReferenceUtil.DrawOneContent("法线混合", "方法一:\n" +
                                                   "return normalize(float3(A.rg + B.rg, A.b * B.b));\n" +
                                                   "方法二:\n" +
                                                   "float3 t = A.xyz + float3(0.0, 0.0, 1.0);\n" +
                                                   "float3 u = B.xyz * float3(-1.0, -1.0, 1.0);\n" +
                                                   "float3 r = (t / t.z) * dot(t, u) - u;\n" +
                                                   "return r;");

                ShaderReferenceUtil.DrawTitle("获取主平行灯");
                ShaderReferenceUtil.DrawOneContent("Light light = GetMainLight(shadowCoord);", "获取主平行灯相关参数:\n" +
                                                   "light.direction : 主平行灯的方向(_MainLightPosition.xyz),已归一化.\n" +
                                                   "light.color : 主平行灯的颜色(_MainLightColor.rgb).\n" +
                                                   //"light.distanceAttenuation : 主平行灯的CullingMask,当主灯的CullingMask包含当对象所在的层时返回1,否则返回0(unity_LightData.z).\n" +
                                                   "light.shadowAttenuation : 在此函数下为1(half).");
                ShaderReferenceUtil.DrawTitle("额外的灯");
                ShaderReferenceUtil.DrawOneContent("_ADDITIONAL_LIGHTS", "是否额外的灯启用.");
                ShaderReferenceUtil.DrawOneContent("_ADDITIONAL_LIGHTS_VERTEX", "额外的灯是否采用逐顶点照明.");
                ShaderReferenceUtil.DrawTitle("投射阴影");
                ShaderReferenceUtil.DrawOneContent("ShadowCaster", "添加LightMode=ShadowCaster的pass即可渲染进lightmap产生投影.");
                ShaderReferenceUtil.DrawTitle("接收阴影");
                ShaderReferenceUtil.DrawOneContent("_MAIN_LIGHT_SHADOWS", "是否开启主灯的阴影(管线设置中主灯的Cast Shadows是否开启)");
                ShaderReferenceUtil.DrawOneContent("MAIN_LIGHT_CALCULATE_SHADOWS", "当管线上设置了主灯投影,并且当前对象也没有激活_RECEIVE_SHADOWS_OFF时开启");
                ShaderReferenceUtil.DrawOneContent("_MAIN_LIGHT_SHADOWS_CASCADE", "是否开启主灯的级联阴影(当管线设置中Shadows>Cascades为No Cascades时不激活,否则激活)");
                ShaderReferenceUtil.DrawOneContent("REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR", "当开启主灯阴影但是没有开启级联阴影时,则激活");
                ShaderReferenceUtil.DrawOneContent("_MainLightShadowmapSize", "ShadowMap的尺寸\n" +
                                                   "x=1/width y=1/height z=width w=height");
                ShaderReferenceUtil.DrawOneContent("_MainLightShadowParams", "Shadow的参数\n" +
                                                   "x=ShadowStrength(阴影强度) y=(1为软阴影,0为硬阴影)");
                ShaderReferenceUtil.DrawOneContent("_SHADOWS_SOFT", "管线上Shadows中是否开启软阴影(Soft Shadows)");
                ShaderReferenceUtil.DrawTitle("Fog 雾效");
                ShaderReferenceUtil.DrawOneContent("unity_FogColor", "内置雾效颜色值");
                ShaderReferenceUtil.DrawOneContent("实现方法", "#pragma multi_compile_fog\n" +
                                                   "float fogCoord  : TEXCOORD1;\t//在Varyings中定义fogCoord\n" +
                                                   "o.fogCoord = ComputeFogFactor(o.positionCS.z);\t//在顶点着色器中添加\n" +
                                                   "c.rgb = MixFog(c.rgb, i.fogCoord);\t//在片断着色器中添加");
                ShaderReferenceUtil.DrawOneContent("Linear", "线性雾公式:(end-z)/(end-start)");
                ShaderReferenceUtil.DrawOneContent("EXP", "指数雾公式:exp(-density*z)");
                ShaderReferenceUtil.DrawOneContent("EXP2", "指数2次方雾公式:exp(-(density*z)^2)");
                ShaderReferenceUtil.DrawTitle("光照烘焙");
                ShaderReferenceUtil.DrawOneContent("LIGHTMAP_ON", "是否开启光照烘焙\n" +
                                                   "1.Lighting界面中的Baked Global Illumination勾选\n" +
                                                   "2.场景烘焙,或者勾选自动烘焙\n" +
                                                   "3.模型勾选Static中的Contribute GI");
                ShaderReferenceUtil.DrawOneContent("_MIXED_LIGHTING_SUBTRACTIVE", "\n" +
                                                   "1.Lighting界面中的Baked Global Illumination勾选\n" +
                                                   "2.Lighting Mode设置为Subtractive模式\n" +
                                                   "3.场景烘焙,或者勾选自动烘焙\n" +
                                                   "4.模型勾选Static中的Contribute GI\n" +
                                                   "5.灯光必须设置为Mixed模式");
                ShaderReferenceUtil.DrawTitle("环境色");
                ShaderReferenceUtil.DrawOneContent("",
                                                   "1.half3 vertexSH : TEXCOORD?    在v2f中声明\n" +
                                                   "2.o.vertexSH = SampleSHVertex(世界空间法线);    在顶点着色器中调用\n" +
                                                   "3.half3 sh = SampleSHPixel(i.vertexSH, 世界空间法线);    在片断着色器中调用");
                break;
            }
            EditorGUILayout.EndScrollView();
        }
Beispiel #3
0
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            ShaderReferenceUtil.DrawTitle("Math");
            ShaderReferenceUtil.DrawOneContent("abs (x)", "取绝对值,即正值返回正值,负值返回的还是正值,x值也可以为向量\n" +
                                               "float abs(float a)\n" +
                                               "{\n" +
                                               "    return max(-a, a);\n" +
                                               "}");

            ShaderReferenceUtil.DrawOneContent("acos (x)", "反余弦函数,输入参数范围为[-1, 1],返回[0, π] 区间的弧度值");
            ShaderReferenceUtil.DrawOneContent("all (a)", "当a或a的所有分量都为true或者非0时返回1(true),否则返回0(false).\n" +
                                               "bool all(bool4 a)\n" +
                                               "{\n" +
                                               "    return a.x && a.y && a.z && a.w;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("any (a)", "如果a=0或者a中的所有分量为0,则返回0(false);否则返回1(true).\n" +
                                               "bool any(bool4 a)\n" +
                                               "{\n" +
                                               "    return a.x || a.y || a.z || a.w;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("asin (x)", "返回x的反正弦值,范围为(-π/2,π/2)");
            ShaderReferenceUtil.DrawOneContent("atan2 (y,x)", "返回y/x的反正切值");
            ShaderReferenceUtil.DrawOneContent("atan (x)", "返回x的反正切值,范围为(-π/2,π/2),表示弧度");
            ShaderReferenceUtil.DrawOneContent("ceil (x)", "对x进行向上取整,即x=0.1返回1,x=1.5返回2,x=-0.3返回0\n" +
                                               "float ceil(float x)\n" +
                                               "{\n" +
                                               "    return -floor(-x);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("clamp(x,a,b)", "如果x值小于a,则返回a;如果x值大于b,返回b;否则返回x.\n" +
                                               "float clamp(float x, float a, float b)\n" +
                                               "{\n" +
                                               "    return max(a, min(b, x));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("clip (x)", "如果x<0则裁剪掉此片断\n" +
                                               "void clip(float4 x)\n" +
                                               "{\n" +
                                               "    if (any(x < 0))\n" +
                                               "    discard;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("cos(x)", "返回弧度x的余弦值,范围在[-1,1]之间.\n");
            ShaderReferenceUtil.DrawOneContent("cosh(x)", "双曲余弦函数\n" +
                                               "float cosh(float x)\n" +
                                               "{\n" +
                                               "    return 0.5 * (exp(x) + exp(-x));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("cross(a,b)", "返回两个三维向量a与b的叉积\n" +
                                               "float3 cross(float3 a, float3 b)\n" +
                                               "{\n" +
                                               "    return a.yzx * b.zxy - a.zxy * b.yzx;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("ddx(v)", "当前像素右边的v值-当前像素的v值(水平方向的差值),假如v是坐标,那就是求坐标差");
            ShaderReferenceUtil.DrawOneContent("ddy(v)", "当前像素下边的v值-当前像素的v值(垂直方向的差值)");
            ShaderReferenceUtil.DrawOneContent("degrees(x)", "将x从弧度转换成角度\n" +
                                               "float degrees(float x)\n" +
                                               "{\n" +
                                               "    return 57.29577951 * x;\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("determinant(M)", "返回方阵M的行列式,注意只有方阵才有行列式");
            ShaderReferenceUtil.DrawOneContent("dot(a,b)", "点乘,a和b可以为标量也可以为向量,其计算结果是两个向量夹角的余弦值,相当于|a|*|b|*cos(θ)或者a.x*b.x+a.y*b.y+a.z*b.z\na和b的位置无所谓前后,结果都是一样的");
            ShaderReferenceUtil.DrawOneContent("distance(a,b)", "返回a,b间的距离.\n" +
                                               "float distance(a, b)\n" +
                                               "{\n" +
                                               "    float3 v = b - a;\n" +
                                               "    return sqrt(dot(v, v));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("exp(x)", "计算e的x次方,e = 2.71828182845904523536");
            ShaderReferenceUtil.DrawOneContent("exp2(x)", "计算2的x次方");

            ShaderReferenceUtil.DrawOneContent("floor(x)", "对x值进行向下取整(去尾求整)\n比如:floor (0.6) = 0.0,floor (-0.6) = -1.0");
            ShaderReferenceUtil.DrawOneContent("fmod(x,y)", "返回x/y的余数。如果y为0,结果不可预料,注意!如果x为负值,返回的结果也是负值!\n" +
                                               "float fmod(float a, float b)\n" +
                                               "{\n" +
                                               "    float c = frac(abs(a / b)) * abs(b);\n" +
                                               "    return (a < 0) ? -c : c;   /* if ( a < 0 ) c = 0-c */\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("frac (x)", "返回x的小数部分\n" +
                                               "float frac(float x)\n" +
                                               "{\n" +
                                               "    return x - floor(x);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("fwidth(v)", "当前像素与它右边及下边像素的差值,abs( ddx(v) )+ abs(ddy(v))");
            ShaderReferenceUtil.DrawOneContent("length (v)", "返回一个向量的模,即 sqrt(dot(v,v))");
            ShaderReferenceUtil.DrawOneContent("lerp (A,B,alpha)", "线性插值.\n如果alpha=0,则返回A;\n如果alpha=1,则返回B;\n否则返回A与B的混合值;内部执行:A + alpha*(B-A)\n" +
                                               "float3 lerp(float3 A, float3 B, float alpha)\n" +
                                               "{\n" +
                                               "    return A + alpha*(B-A);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("log(x)", "返回x的自然对数,如果a^x = N(a>0,且a≠1),那么x就叫做以a为底N的对数.");
            ShaderReferenceUtil.DrawOneContent("log2(x)", "返回以2为底的自然对数");
            ShaderReferenceUtil.DrawOneContent("log10(x)", "返回以10为底的自然对数");
            ShaderReferenceUtil.DrawOneContent("max(a,b)", "比较两个标量或等长向量元素,返回最大值");
            ShaderReferenceUtil.DrawOneContent("min(a,b)", "比较两个标量或等长向量元素,返回最小值");
            ShaderReferenceUtil.DrawOneContent("mul", "mul(M,v):矩阵M与列向量v相乘,结果就是对向量v进行矩阵M变换后的值,相当于mul(v,transpose(M)).\n" +
                                               "mul(v,M):行向量v与矩阵M相乘,结果就是对向量v进行矩阵M变换后的值,相当于mul(transpose(M),v).");

            ShaderReferenceUtil.DrawOneContent("normalize(v)", "返回一个向量的归一化版本(方向一样,但是模为1)" +
                                               "\nnormalize(v) = rsqrt(dot(v,v))*v; rsqrt返回的是平方根的倒数");
            ShaderReferenceUtil.DrawOneContent("pow(x,y)", "返回x的y次方\n" +
                                               "float pow(float x, float y)\n" +
                                               "{\n" +
                                               "   exp(x * log(y));\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("PositivePow(x,y)", "同pow(),但是避免了报错的警告信息.");
            ShaderReferenceUtil.DrawOneContent("rcp(x)", "返回x的倒数,相当于 1/x");
            ShaderReferenceUtil.DrawOneContent("reflect(I, N)", "根据入射光方向向量 I ,和顶点法向量 N ,计算反射光方向向量。其中 I 和 N 必须被归一化,需要非常注意的是,这个 I 是指向顶点的;函数只对三元向量有效。\n\n" +
                                               "float3 reflect( float3 i, float3 n )\n" +
                                               "{\n" +
                                               "   return i - 2.0 * n * dot(n,i);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("refract(I,N,eta)", "计算折射向量, I 为入射光线, N 为法向量, eta 为折射系数;其中 I 和 N 必须被归一化,如果 I 和 N 之间的夹角太大,则返回( 0 , 0 , 0 ),也就是没有折射光线; I 是指向顶点的;函数只对三元向量有效。\n\n" +
                                               "float3 refract( float3 i, float3 n, float eta )\n" +
                                               "{\n" +
                                               "   float cosi = dot(-i, n);\n" +
                                               "   float cost2 = 1.0f - eta * eta * (1.0f - cosi*cosi);\n" +
                                               "   float3 t = eta*i + ((eta*cosi - sqrt(abs(cost2))) * n);\n" +
                                               "   return t * (float3)(cost2 > 0);\n" +
                                               "}");
            ShaderReferenceUtil.DrawOneContent("round(x)", "返回x四舍五入的值");
            ShaderReferenceUtil.DrawOneContent("rsqrt(x)", "返回x的平方根倒数,注意x不能为0.相当于 pow(x, -0.5)");
            ShaderReferenceUtil.DrawOneContent("saturate (x)", "如果x<0返回0,如果x>1返回1,否则返回x.");
            ShaderReferenceUtil.DrawOneContent("sqrt(x)", "返回x的平方根.");
            ShaderReferenceUtil.DrawOneContent("step(a,b)", "如果a<=b返回1,否则返回0.");
            ShaderReferenceUtil.DrawOneContent("sign(x)", "如果x=0返回0,如果x>0返回1,如果x<0返回-1.");
            ShaderReferenceUtil.DrawOneContent("sin(x)", "返回弧度x的正弦值,范围在[-1,1]之间.\n");
            ShaderReferenceUtil.DrawOneContent("sincos(x,a,b)", "同时返回弧度x的正弦值a与余弦值b.\n");
            ShaderReferenceUtil.DrawOneContent("smoothstep (min,max,x)", "float smoothstep (float min, float max, float x)\n" +
                                               "{\n" +
                                               "\tfloat t = saturate ((x - min) / (max - min));\n" +
                                               "\treturn t * t * (3.0 - (2.0 * t));\n" +
                                               "}\n" +
                                               "如果 x 比min 小,返回 0\n如果 x 比max 大,返回 1\n如果 x 处于范围 [min,max]中,则返回 0 和 1 之间的值(按值在min和max间的比例).\n如果只想要线性过渡,并不需要平滑的话,可以直接使用saturate((x - min)/(max - min))");
            ShaderReferenceUtil.DrawOneContent("tan(x)", "返回x的正切值");
            ShaderReferenceUtil.DrawOneContent("transpose (M)", "求矩阵M的转置.");

            ShaderReferenceUtil.DrawTitle("普通纹理采样");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawOneContent("tex1D(samper1D tex,float s)", "一维纹理采样");
                ShaderReferenceUtil.DrawOneContent("tex2D(samper2D tex,float2 s)", "二维纹理采样");
                ShaderReferenceUtil.DrawOneContent("tex2Dlod(samper2D tex,float4 s)", "二维纹理采样,s.w表示采样的是mipmap的几级,仅在ES3.0以上支持.");
                ShaderReferenceUtil.DrawOneContent("tex2DProj(samper2D tex,float4 s)", "二维投影纹理采样,uv使用s.xy/s.w");
                ShaderReferenceUtil.DrawOneContent("texCUBE(samperCUBE tex,float3 s)", "立方体纹理采样");
                ShaderReferenceUtil.DrawOneContent("tex3D(samper3D tex,float3 s)", "3D纹理采样,uv使用xyz");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("TEXTURE2D (textureName);", "二维纹理的定义(纹理与采样器分离定义),此功能在OpenGL ES2.0上不支持,会使用原来sampler2D的形式.\n" +
                                                   "textureName:Properties中声明的2D纹理.");
                ShaderReferenceUtil.DrawOneContent("TEXTURECUBE (textureName);", "立方体纹理的定义(纹理与采样器分离定义),此功能在OpenGL ES2.0上不支持,会使用原来samplerCube的形式.\n" +
                                                   "textureName:Properties中声明的立方体纹理.");
                ShaderReferenceUtil.DrawOneContent("SAMPLER(samplerName);", "采样器的定义(纹理与采样器分离定义),采样器是指纹理的过滤模式与重复模式,此功能在OpenGL ES2.0上不支持,相当于没写.\n" +
                                                   "1.SAMPLER(sampler_textureName):sampler+纹理名称,这种定义形式是表示采用textureName这个纹理Inspector面板中的采样方式.\n" +
                                                   "2.SAMPLER(_filter_wrap):比如SAMPLER(sampler_linear_repeat),使用自定义的采样器设置,自定义的采样器一定要同时包含过滤模式<filter>与重复模式<wrap>的设置,注意这种自定义写法很多移动平台不支持!.\n" +
                                                   "3.SAMPLER(_filter_wrapU_wrapV):比如SAMPLER(sampler_linear_clampU_mirrorV),可同时设置重复模式的U与V的不同值.\n" +
                                                   "4.filter:point/linear/triLinear\n" +
                                                   "5.wrap:clamp/repeat/mirror/mirrorOnce");
                ShaderReferenceUtil.DrawOneContent("float4 [textureName]_ST;", "获取纹理的Tiling(.xy)和Offset(.zw)");
                ShaderReferenceUtil.DrawOneContent("float4 [textureName]_TexelSize;", "获取纹理的宽高分之一(.xy)和宽高(.zw)");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURE2D(textureName, samplerName, coord);", "进行二维纹理采样操作\n" +
                                                   "textureName:Properties中声明的2D纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的UV");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord,lod);", "进行二维纹理采样操作\n" +
                                                   "textureName:Properties中声明的2D纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的UV\n" +
                                                   "lod:mipmap级别");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord,bias);", "对mipmap进行偏移后再采样纹理\n" +
                                                   "textureName:Properties中声明的2D纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的UV\n" +
                                                   "bias:mipmap偏移量,比如0=默认,-1=比当前级别更清晰一级,1=比当前级别更模糊一级.");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURECUBE(textureName, samplerName, coord);", "进行立方体纹理采样操作\n" +
                                                   "textureName:Properties中声明的CUBE纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的UV");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord,lod);", "进行立方体纹理采样操作\n" +
                                                   "textureName:Properties中声明的CUBE纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的UV\n" +
                                                   "lod:mipmap级别");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURE3D(textureName, samplerName, coord);", "进行3D纹理采样操作\n" +
                                                   "textureName:Properties中声明的3D纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的三给UV");
                break;
            }

            ShaderReferenceUtil.DrawTitle("纹理数组采样");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:

                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("TEXTURE2D_ARRAY(textureName);", "纹理数组的定义,此功能在OpenGL ES2.0上不支持,会fallback到samplerCUBE的形式.");
                ShaderReferenceUtil.DrawOneContent("SAMPLER(sampler_samplerName);", "纹理数组的采样器定义.");
                ShaderReferenceUtil.DrawOneContent("SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index);", "纹理数组采样.\n" +
                                                   "textureName:Properties中声明的2D纹理名称\n" +
                                                   "samplerName:此纹理所使用的采样器设置\n" +
                                                   "coord:采样用的UV\n" +
                                                   "index:数组索引");
                break;
            }

            ShaderReferenceUtil.DrawTitle("常用指令");
            ShaderReferenceUtil.DrawOneContent("mov dest, src1", "dest = src1");
            ShaderReferenceUtil.DrawOneContent("add dest, src1, src2", "dest = src1 + src2 (可通过在src2前加-,实现减功能)");
            ShaderReferenceUtil.DrawOneContent("mul dest, src1, src2", "dest = src1 * src2");
            ShaderReferenceUtil.DrawOneContent("div dest, src1, src2", "dest = src1 / src2");
            ShaderReferenceUtil.DrawOneContent("mad dest, src1, src2 , src3", "dest = src1 * src2 + src3");
            ShaderReferenceUtil.DrawOneContent("dp2 dest, src1, src2", "(src1.x * src2.x) + (src1.y * src2.y)");
            ShaderReferenceUtil.DrawOneContent("dp3 dest, src1, src2", "(src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z)");
            ShaderReferenceUtil.DrawOneContent("dp4 dest, src1, src2", "(src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z) + (src1.w * src2.w)");
            ShaderReferenceUtil.DrawOneContent("rsq dest, src1", "rsqrt(src1) 对src1进行平方根的倒数,然后将值存入dest中");
            EditorGUILayout.EndScrollView();
        }
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            ShaderReferenceUtil.DrawTitle("法线 NormalMap");
            ShaderReferenceUtil.DrawOneContent("使用切线空间下的法线",
                                               "1.appdata中定义NORMAL与TANGENT语义.\n" +
                                               "2.v2f中声明三个变量用于组成成切线空间下的旋转矩阵.\n" +
                                               "   float3 tSpace0:TEXCOORD3;\n" +
                                               "   float3 tSpace1:TEXCOORD4;\n" +
                                               "   float3 tSpace2:TEXCOORD5;\n" +
                                               "3.在顶点着色器中执行:\n" +
                                               "   half3 worldTangent = UnityObjectToWorldDir(v.tangent);\n" +
                                               "   fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;\n" +
                                               "   half3 worldBinormal = cross(o.worldNormal, worldTangent) * tangentSign;\n" +
                                               "   o.tSpace0 = float3(worldTangent.x,worldBinormal.x,o.worldNormal.x);\n" +
                                               "   o.tSpace1 = float3(worldTangent.y,worldBinormal.y,o.worldNormal.y);\n" +
                                               "   o.tSpace2 = float3(worldTangent.z,worldBinormal.z,o.worldNormal.z);\n" +
                                               "4.在片断着色器中计算出世界空间下的法线,然后再拿去进行需要的计算:\n" +
                                               "   half3 normalTex = UnpackNormal(tex2D(_NormalTex,i.uv));\n" +
                                               "   half3 worldNormal = half3(dot(i.tSpace0,normalTex),dot(i.tSpace1,normalTex),dot(i.tSpace2,normalTex));");
            ShaderReferenceUtil.DrawTitle("光照模型");
            ShaderReferenceUtil.DrawOneContent("Lambertian", "Diffuse = Ambient + Kd * LightColor * max(0,dot(N,L))\n" +
                                               "Diffuse:\t最终物体上的漫反射光强.\n" +
                                               "Ambient:\t环境光强度,为了简化计算,环境光强采用一个常数表示.\n" +
                                               "Kd:\t物体材质对光的反射系数.\n" +
                                               "LightColor:\t光源的强度.\n" +
                                               "N:\t顶点的单位法线向量.\n" +
                                               "L:\t顶点指向光源的单位向量.");
            ShaderReferenceUtil.DrawOneContent("Phong", "Specular = SpecularColor * Ks * pow(max(0,dot(R,V)), Shininess)\n" +
                                               "Specular:\t最终物体上的反射高光光强.\n" +
                                               "SpecularColor:\t反射光的颜色.\n" +
                                               "Ks:\t反射强度系数.\n" +
                                               "R:\t反射向量,可使用2 * N * dot(N,L) - L或者reflect (-L,N)获得.\n" +
                                               "V:\t观察方向.\n" +
                                               "N:\t顶点的单位法线向量.\n" +
                                               "L:\t顶点指向光源的单位向量.\n" +
                                               "Shininess:\t乘方运算来模拟高光的变化.");
            ShaderReferenceUtil.DrawOneContent("Blinn-Phong", "Specular = SpecularColor * Ks * pow(max(0,dot(N,H)), Shininess)\n" +
                                               "Specular:\t最终物体上的反射高光光强.\n" +
                                               "SpecularColor:\t反射光的颜色.\n" +
                                               "Ks:\t反射强度系数.\n" +
                                               "N:\t顶点的单位法线向量.\n" +
                                               "H:\t入射光线L与视线V的中间向量,也称为半角向量H = normalize(L+V).\n" +
                                               "Shininess:\t乘方运算来模拟高光的变化.");
            ShaderReferenceUtil.DrawOneContent("Disney Principled BRDF", "f(l,v) = diffuse + D(h)F(v,h)G(l,v,h)/4cos(n·l)cos(n·v)\n" +
                                               "f(l,v):\t双向反射分布函数的最终值,l表示光的方向,v表示视线的方向.\n" +
                                               "diffuse:\t漫反射.\n" +
                                               "D(h):\t法线分布函数(Normal Distribution Function),描述微面元法线分布的概率,即朝向正确的法线浓度.h为半角向量,表示光的方向与反射方向的半角向量,只有物体的微表面法向m = h时,才会反射到视线中.\nD(h) = roughness^2 / π((n·h)^2(roughness^2-1)+1)^2\n" +
                                               "F(v,h):\t菲涅尔方程(Fresnel Equation),描述不同的表面角下表面所反射的光线所占的比率.\nF(v,h) = F0 + (1-F0)(1-(v·h))^5(F0是0度入射角的菲涅尔反射值)\n" +
                                               "G(l,v,h):\t几何函数(Geometry Function),描述微平面自成阴影的属性,即微表面法向m = h的并未被遮蔽的表面点的百分比.\n" +
                                               "4cos(n·l)cos(n·v):\t校正因子(correctionfactor)作为微观几何的局部空间和整个宏观表面的局部空间之间变换的微平面量的校正.");

            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawTitle("ShadowMap阴影");
                ShaderReferenceUtil.DrawOneContent("生成阴影", "添加\"LightMode\" = \"ShadowCaster\"的Pass.\n" +
                                                   "1.appdata中声明float4 vertex:POSITION;和half3 normal:NORMAL;这是生成阴影所需要的语义.\n" +
                                                   "2.v2f中添加V2F_SHADOW_CASTER;用于声明需要传送到片断的数据.\n" +
                                                   "3.在顶点着色器中添加TRANSFER_SHADOW_CASTER_NORMALOFFSET(o),主要是计算阴影的偏移以解决不正确的Shadow Acne和Peter Panning现象.\n" +
                                                   "4.在片断着色器中添加SHADOW_CASTER_FRAGMENT(i)");
                ShaderReferenceUtil.DrawOneContent("采样阴影", "" +
                                                   "1.在v2f中添加UNITY_SHADOW_COORDS(idx),unity会自动声明一个叫_ShadowCoord的float4变量,用作阴影的采样坐标.\n" +
                                                   "2.在顶点着色器中添加TRANSFER_SHADOW(o),用于将上面定义的_ShadowCoord纹理采样坐标变换到相应的屏幕空间纹理坐标,为采样阴影纹理使用.\n" +
                                                   "3.在片断着色器中添加UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos),其中atten即存储了采样后的阴影.");

                ShaderReferenceUtil.DrawTitle("Global Illumination 全局照明GI");
                ShaderReferenceUtil.DrawOneContent("产生间接光照", "添加\"LightMode\" = \"Meta\"的Pass.\n" +
                                                   "可参考内置Shader中的Meta Pass.");

                ShaderReferenceUtil.DrawTitle("Light Probe 光照探针");
                ShaderReferenceUtil.DrawOneContent("规则01", "当逐像素平行灯标记为Mixed时,同时场景内有LightProbe时,那么当前平行灯的光照值会自动被LightProbe影响,所以不管物体Shader中是否有SH相关的运算,都会受到LightProbe的影响.");
                ShaderReferenceUtil.DrawOneContent("规则02", "当逐像素平行灯标记为Baked时,同时场景内有LightProbe时,那么需要自行在物体Shader中添加SH相关的运算,才会受到LightProbe的影响.");

                ShaderReferenceUtil.DrawTitle("Reflection Probe 反射探针");
                ShaderReferenceUtil.DrawOneContent("反射探针的采样", "反射探针中当前激活的CubeMap存储在unity_SpecCube0当中,必须要用UNITY_SAMPLE_TEXCUBE进行采样,然后需要对其进行解码\n" +
                                                   "   half3 worldView = normalize (UnityWorldSpaceViewDir (i.worldPos));\n" +
                                                   "   half3 R = reflect (-worldView, N);\n" +
                                                   "   half4 cubemap = UNITY_SAMPLE_TEXCUBE (unity_SpecCube0, R);\n" +
                                                   "   half3 skyColor = DecodeHDR (cubemap, unity_SpecCube0_HDR);");

                ShaderReferenceUtil.DrawTitle("Fog 雾效");
                ShaderReferenceUtil.DrawOneContent("unity_FogColor", "内置雾效颜色值");
                ShaderReferenceUtil.DrawOneContent("方案一:", "常规方案\n" +
                                                   "1.#pragma multi_compile_fog声明雾效所需要的内置变体:FOG_LINEAR FOG_EXP FOG_EXP2.\n" +
                                                   "2.UNITY_FOG_COORDS(idx): 声明顶点传入片断中的雾效插值器(fogCoord).\n" +
                                                   "3.UNITY_TRANSFER_FOG(o,o.vertex): 在顶点着色器中计算雾效采样.\n" +
                                                   "4.UNITY_APPLY_FOG(i.fogCoord, col): 在片断着色器中进行雾效颜色混合.");
                ShaderReferenceUtil.DrawOneContent("方案二:", "当在v2f中有定义worldPos时,可以把worldPos.w利用起来做为雾效值.\n" +
                                                   "1.#pragma multi_compile_fog声明雾效所需要的内置变体:FOG_LINEAR FOG_EXP FOG_EXP2.\n" +
                                                   "2.UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o,o.worldPos): 在顶点着色器中添加,o.worldPos表示世界空间下的顶点坐标.\n" +
                                                   "3.UNITY_EXTRACT_FOG_FROM_WORLD_POS(i): 在片断着色器中添加.\n" +
                                                   "4.UNITY_APPLY_FOG(_unity_fogCoord, c): 在片断着色器中进行雾效颜色混合.");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawTitle("获取主平行灯");
                ShaderReferenceUtil.DrawOneContent("Light light = GetMainLight();", "获取主平行灯相关参数:\n" +
                                                   "light.direction : 主平行灯的方向(half3).\n" +
                                                   "light.color : 主平行灯的颜色(half3).\n" +
                                                   "light.distanceAttenuation : 主平行灯的CullingMask,如果希望对象受CullingMask正常影响,就需要乘上它(half).\n" +
                                                   "light.shadowAttenuation : 在此函数下为1(half).");
                ShaderReferenceUtil.DrawTitle("Fog 雾效");
                ShaderReferenceUtil.DrawOneContent("unity_FogColor", "内置雾效颜色值");
                ShaderReferenceUtil.DrawOneContent("实现方法", "#pragma multi_compile_fog\n" +
                                                   "float fogCoord  : TEXCOORD1;\t//在Varyings中定义fogCoord\n" +
                                                   "o.fogCoord = ComputeFogFactor(o.positionCS.z);\t//在顶点着色器中添加\n" +
                                                   "c.rgb = MixFog(c.rgb, i.fogCoord);\t//在片断着色器中添加");
                ShaderReferenceUtil.DrawOneContent("Linear", "线性雾公式:(end-z)/(end-start)");
                ShaderReferenceUtil.DrawOneContent("EXP", "指数雾公式:exp(-density*z)");
                ShaderReferenceUtil.DrawOneContent("EXP2", "指数2次方雾公式:exp(-(density*z)^2)");
                break;
            }
            EditorGUILayout.EndScrollView();
        }
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

            ShaderReferenceUtil.DrawTitle("");
            ShaderReferenceUtil.DrawOneContent("UNITY_INITIALIZE_OUTPUT(type,name)", "由于HLSL编缉器不接受没有初始化的数据,所以为了支持所有平台,从而需要使用此方法进行初始化.");
            ShaderReferenceUtil.DrawOneContent("TRANSFORM_TEX(i.uv,_MainTex)", "对UV进行Tiling与Offset变换");
            ShaderReferenceUtil.DrawOneContent("float3 UnityWorldSpaceLightDir( float3 worldPos )", "返回顶点到灯光的向量");

            ShaderReferenceUtil.DrawTitle("Camera and Screen");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawOneContent("_WorldSpaceCameraPos", "主相机的世界坐标位置,类型:float3");
                ShaderReferenceUtil.DrawOneContent("UnityWorldSpaceViewDir(i.worldPos)", "世界空间下的相机方向(顶点到主相机),类型:float3");
                ShaderReferenceUtil.DrawOneContent("深度:_CameraDepthTexture",
                                                   "1.在脚本中开启相机的深度:Camera.main.depthTextureMode = DepthTextureMode.Depth;\n" +
                                                   "2.sampler2D_float _CameraDepthTexture;\n" +
                                                   "3.float depth = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));");
                ShaderReferenceUtil.DrawOneContent("线性深度转换",
                                                   "从深度图中得到顶点的线性深度值(相机位置=0,相机远裁剪面=1)\n" +
                                                   "Linear01Depth(depthMap, _ZBufferParams);\n" +
                                                   "从深度图中得到顶点的线性深度值(不是0-1的范围)\n" +
                                                   "LinearEyeDepth(depthMap, _ZBufferParams);");
                ShaderReferenceUtil.DrawOneContent("ComputeScreenPos(float4 pos)", "pos为裁剪空间下的坐标位置,返回的是某个投影点下的屏幕坐标位置" +
                                                   "\n由于这个函数返回的坐标值并未除以齐次坐标,所以如果直接使用函数的返回值的话,需要使用:tex2Dproj(_ScreenTexture, uv.xyw);" +
                                                   "\n也可以自己处理其次坐标,使用:tex2D(_ScreenTexture, uv.xy / uv.w);");
                ShaderReferenceUtil.DrawOneContent("_ScreenParams", "屏幕的相关参数,单位为像素。\nx表示屏幕的宽度\ny表示屏幕的高度\nz表示1+1/屏幕宽度\nw表示1+1/屏幕高度");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("Camera相关参数", "相机在世界空间下的位置坐标(xyz):_WorldSpaceCameraPos\n" +
                                                   "相机指向前方的方向:-1 * mul(UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n" +
                                                   "是否是正交相机(1为正交,0为透视):unity_OrthoParams.w\n" +
                                                   "近裁剪面:_ProjectionParams.y\n" +
                                                   "远裁剪面:_ProjectionParams.z\n" +
                                                   "Z Buffer方向(-1为反向,1为正向):_ProjectionParams.x\n" +
                                                   "正交相机的宽度:unity_OrthoParams.x\n" +
                                                   "正交相机的高度:unity_OrthoParams.y");
                ShaderReferenceUtil.DrawOneContent("_ZBufferParams", "传统Z方向:\n" +
                                                   "x=1-far/near\n" +
                                                   "y=far/near\n" +
                                                   "z=x/far\n" +
                                                   "w=y/far\n\n" +
                                                   "反向Z:\n" +
                                                   "x=-1+far/near\n" +
                                                   "y=1\n" +
                                                   "z=x/far\n" +
                                                   "w=1/far");
                ShaderReferenceUtil.DrawOneContent("深度:_CameraDepthTexture", "在PipelineAsset中勾选DepthTexture.\n" +
                                                   "#define REQUIRE_DEPTH_TEXTURE\t//直接这样定义可以省去声明纹理的步骤(直接使用内部hlsl中的定义)\n" +
                                                   "TEXTURE2D (_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);\n" +
                                                   "float2 screenUV = i.positionCS/_ScreenParams.xy;\n" +
                                                   "half4 depthMap = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV);\n" +
                                                   "half depth = Linear01Depth(depthMap, _ZBufferParams);");
                ShaderReferenceUtil.DrawOneContent("线性深度转换",
                                                   "从深度图中得到顶点的线性深度值(相机位置=0,相机远裁剪面=1)\n" +
                                                   "Linear01Depth(depthMap, _ZBufferParams);\n" +
                                                   "从深度图中得到顶点的线性深度值(不是0-1的范围)\n" +
                                                   "LinearEyeDepth(depthMap, _ZBufferParams);");
                ShaderReferenceUtil.DrawOneContent("抓屏:_CameraOpaqueTexture", "在PipelineAsset中勾选OpaqueTexture,同时这个抓屏只能在半透明序列下正确执行.\n" +
                                                   "#define REQUIRE_OPAQUE_TEXTURE\t//直接这样定义可以省去声明纹理的步骤(直接使用内部hlsl中的定义)\n" +
                                                   "TEXTURE2D (_CameraOpaqueTexture);SAMPLER(sampler_CameraOpaqueTexture);\n" +
                                                   "float2 screenUV = i.positionCS.xy / _ScreenParams.xy;\n" +
                                                   "half4 screenColor = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, screenUV);");
                ShaderReferenceUtil.DrawOneContent("_ScreenParams", "屏幕的相关参数,单位为像素。\nx表示屏幕的宽度\ny表示屏幕的高度\nz表示1+1/屏幕宽度\nw表示1+1/屏幕高度");
                ShaderReferenceUtil.DrawOneContent("_ScaledScreenParams", "同上,但是有考虑到RenderScale的影响.");
                break;
            }

            //ShaderReferenceUtil.DrawOneContent("_ProjectionParams", "");
            //ShaderReferenceUtil.DrawOneContent("_ZBufferParams", "");
            //ShaderReferenceUtil.DrawOneContent("unity_OrthoParams", "");
            //ShaderReferenceUtil.DrawOneContent("unity_CameraProjection", "");
            //ShaderReferenceUtil.DrawOneContent("unity_CameraInvProjection", "");
            //ShaderReferenceUtil.DrawOneContent("unity_CameraWorldClipPlanes[6]", "");

            ShaderReferenceUtil.DrawTitle("Time");
            ShaderReferenceUtil.DrawOneContent("_Time", "时间,主要用于在Shader做动画,类型:float4\nx = t/20\ny = t\nz = t*2\nw = t*3");
            ShaderReferenceUtil.DrawOneContent("_SinTime", "t是时间的正弦值,返回值(-1~1): \nx = t/8\ny = t/4\nz = t/2\nw = t");
            ShaderReferenceUtil.DrawOneContent("_CosTime", "t是时间的余弦值,返回值(-1~1):\nx = t/8\ny = t/4\nz = t/2\nw = t");
            ShaderReferenceUtil.DrawOneContent("unity_DeltaTime", "dt是时间增量,smoothDt是平滑时间\nx = dt\ny = 1/dt\nz = smoothDt\nz = 1/smoothDt");

            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawTitle("Lighting(ForwardBase & ForwardAdd)");
                ShaderReferenceUtil.DrawOneContent("_LightColor0", "主平行灯的颜色值,rgb = 颜色x亮度; a = 亮度");
                ShaderReferenceUtil.DrawOneContent("_WorldSpaceLightPos0", "平行灯:\t(xyz=位置,z=0)),已归一化\n其它类型灯:\t(xyz=位置,z=1)");
                ShaderReferenceUtil.DrawOneContent("unity_WorldToLight", "从世界空间转换到灯光空间下,等同于旧版的_LightMatrix0.");
                //ShaderReferenceUtil.DrawOneContent("unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0", "");
                //ShaderReferenceUtil.DrawOneContent("unity_4LightAtten0", "");
                //ShaderReferenceUtil.DrawOneContent("unity_LightColor", "");
                //ShaderReferenceUtil.DrawOneContent("unity_WorldToShadow", "");
                ShaderReferenceUtil.DrawTitle("Fog and Ambient");
                ShaderReferenceUtil.DrawOneContent("unity_AmbientSky", "环境光(Gradient)中的Sky Color.");
                ShaderReferenceUtil.DrawOneContent("unity_AmbientEquator", "环境光(Gradient)中的Equator Color.");
                ShaderReferenceUtil.DrawOneContent("unity_AmbientGround", "环境光(Gradient)中的Ground Color.");
                ShaderReferenceUtil.DrawOneContent("UNITY_LIGHTMODEL_AMBIENT", "环境光(Color)中的颜色,等同于环境光(Gradient)中的Sky Color.");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                break;
            }

            //ShaderReferenceUtil.DrawOneContent("unity_FogColor", "");
            //ShaderReferenceUtil.DrawOneContent("unity_FogParams", "");

            //ShaderReferenceUtil.DrawTitle("Various");
            //ShaderReferenceUtil.DrawOneContent("unity_LODFade", "");
            //ShaderReferenceUtil.DrawOneContent("_TextureSampleAdd", "");

            ShaderReferenceUtil.DrawTitle("GPU Instancing");
            ShaderReferenceUtil.DrawOneContent("实现步骤", "用于对多个对象(网格一样,材质一样,但是材质属性不一样)合批,单个合批最大上限为511个对象.\n" +
                                               "1.#pragma multi_compile_instancing 添加此指令后会使材质面板上曝露Instaning开关,同时会生成相应的Instancing变体(INSTANCING_ON).\n" +
                                               "2.UNITY_VERTEX_INPUT_INSTANCE_ID 在顶点着色器的输入(appdata)和输出(v2f可选)中添加(uint instanceID : SV_InstanceID).\n" +
                                               "3.UNITY_INSTANCING_BUFFER_START(arrayName) / UNITY_INSTANCING_BUFFER_END(arrayName) 将每个你需要实例化的属性都封装在这个常量寄存器中\n" +
                                               "4.UNITY_DEFINE_INSTANCED_PROP(type, name) 在上面的START和END间把需要的每条属性加进来\n" +
                                               "5.UNITY_SETUP_INSTANCE_ID(v); 放在顶点着色器/片断着色器(可选)中最开始的地方,这样才能访问到全局变量unity_InstanceID.\n" +
                                               "6.UNITY_TRANSFER_INSTANCE_ID(v, o); 当需要将实例化ID传到片断着色器时,在顶点着色器中添加.\n" +
                                               "7.UNITY_ACCESS_INSTANCED_PROP(arrayName, propName) 在片断着色器中访问具体的实例化变量.\n");
            ShaderReferenceUtil.DrawOneContent("Instancing选项", "对GPU Instancing进行一些设置.\n" +
                                               "• #pragma instancing_options forcemaxcount:batchSize 强制设置单个批次内Instancing的最大数量,最大值和默认值是500.\n" +
                                               "• #pragma instancing_options maxcount:batchSize 设置单个批次内Instancing的最大数量,仅Vulkan, Xbox One和Switch有效.");

            EditorGUILayout.EndScrollView();
        }
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

            ShaderReferenceUtil.DrawTitle("");
            ShaderReferenceUtil.DrawOneContent("UNITY_INITIALIZE_OUTPUT(type,name)", "由于HLSL编缉器不接受没有初始化的数据,所以为了支持所有平台,从而需要使用此方法进行初始化.");
            ShaderReferenceUtil.DrawOneContent("TRANSFORM_TEX(i.uv,_MainTex)", "对UV进行Tiling与Offset变换");
            ShaderReferenceUtil.DrawOneContent("float3 UnityWorldSpaceLightDir( float3 worldPos )", "返回顶点到灯光的向量");
            ShaderReferenceUtil.DrawOneContent("ComputeScreenPos(float4 pos)", "pos为裁剪空间下的坐标位置,返回的是某个投影点下的屏幕坐标位置" +
                                               "\n由于这个函数返回的坐标值并未除以齐次坐标,所以如果直接使用函数的返回值的话,需要使用:tex2Dproj(_ScreenTexture, uv.xyw);" +
                                               "\n也可以自己处理其次坐标,使用:tex2D(_ScreenTexture, uv.xy / uv.w);");
            ShaderReferenceUtil.DrawOneContent("Luminance(float rgb)", "去色,内部公式为:dot(rgb,fixed3(0.22,0.707,0.071)).");

            ShaderReferenceUtil.DrawTitle("Camera and Screen");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawOneContent("_WorldSpaceCameraPos", "主相机的世界坐标位置,类型:float3");
                ShaderReferenceUtil.DrawOneContent("UnityWorldSpaceViewDir(i.worldPos)", "世界空间下的相机方向(顶点到主相机),类型:float3");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("Camera相关参数", "相机在世界空间下的位置坐标:_WorldSpaceCameraPos\n" +
                                                   "相机指向前方的方向:-1 * mul(UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n" +
                                                   "是否是正交相机(1为正交,0为透视):unity_OrthoParams.w\n" +
                                                   "近裁剪面:_ProjectionParams.y\n" +
                                                   "远裁剪面:_ProjectionParams.z\n" +
                                                   "Z Buffer方向(-1为反向,1为正向):_ProjectionParams.x\n" +
                                                   "正交相机的宽度:unity_OrthoParams.x\n" +
                                                   "正交相机的高度:unity_OrthoParams.y");
                break;
            }

            //ShaderReferenceUtil.DrawOneContent("_ProjectionParams", "");
            ShaderReferenceUtil.DrawOneContent("_ScreenParams", "屏幕的相关参数,单位为像素。\nx表示屏幕的宽度\ny表示屏幕的高度\nz表示1+1/屏幕宽度\nw表示1+1/屏幕高度");
            //ShaderReferenceUtil.DrawOneContent("_ZBufferParams", "");
            //ShaderReferenceUtil.DrawOneContent("unity_OrthoParams", "");
            //ShaderReferenceUtil.DrawOneContent("unity_CameraProjection", "");
            //ShaderReferenceUtil.DrawOneContent("unity_CameraInvProjection", "");
            //ShaderReferenceUtil.DrawOneContent("unity_CameraWorldClipPlanes[6]", "");

            ShaderReferenceUtil.DrawTitle("Time");
            ShaderReferenceUtil.DrawOneContent("_Time", "时间,主要用于在Shader做动画,类型:float4\nx = t/20\ny = t\nz = t*2\nw = t*3");
            ShaderReferenceUtil.DrawOneContent("_SinTime", "t是时间的正弦值,返回值(-1~1): \nx = t/8\ny = t/4\nz = t/2\nw = t");
            ShaderReferenceUtil.DrawOneContent("_CosTime", "t是时间的余弦值,返回值(-1~1):\nx = t/8\ny = t/4\nz = t/2\nw = t");
            ShaderReferenceUtil.DrawOneContent("unity_DeltaTime", "dt是时间增量,smoothDt是平滑时间\nx = dt\ny = 1/dt\nz = smoothDt\nz = 1/smoothDt");

            ShaderReferenceUtil.DrawTitle("Lighting(ForwardBase & ForwardAdd)");
            ShaderReferenceUtil.DrawOneContent("_LightColor0", "主平行灯的颜色值,rgb = 颜色x亮度; a = 亮度");
            ShaderReferenceUtil.DrawOneContent("_WorldSpaceLightPos0", "平行灯:\t(xyz=位置,z=0))\n其它类型灯:\t(xyz=位置,z=1)");
            ShaderReferenceUtil.DrawOneContent("unity_WorldToLight", "从世界空间转换到灯光空间下,等同于旧版的_LightMatrix0.");
            //ShaderReferenceUtil.DrawOneContent("unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0", "");
            //ShaderReferenceUtil.DrawOneContent("unity_4LightAtten0", "");
            //ShaderReferenceUtil.DrawOneContent("unity_LightColor", "");
            //ShaderReferenceUtil.DrawOneContent("unity_WorldToShadow", "");

            ShaderReferenceUtil.DrawTitle("Fog and Ambient");
            ShaderReferenceUtil.DrawOneContent("unity_AmbientSky", "环境光(Gradient)中的Sky Color.");
            ShaderReferenceUtil.DrawOneContent("unity_AmbientEquator", "环境光(Gradient)中的Equator Color.");
            ShaderReferenceUtil.DrawOneContent("unity_AmbientGround", "环境光(Gradient)中的Ground Color.");
            ShaderReferenceUtil.DrawOneContent("UNITY_LIGHTMODEL_AMBIENT", "环境光(Color)中的颜色,等同于环境光(Gradient)中的Sky Color.");
            //ShaderReferenceUtil.DrawOneContent("unity_FogColor", "");
            //ShaderReferenceUtil.DrawOneContent("unity_FogParams", "");

            //ShaderReferenceUtil.DrawTitle("Various");
            //ShaderReferenceUtil.DrawOneContent("unity_LODFade", "");
            //ShaderReferenceUtil.DrawOneContent("_TextureSampleAdd", "");

            ShaderReferenceUtil.DrawTitle("GPU Instancing");
            ShaderReferenceUtil.DrawOneContent("实现步骤", "用于对多个对象(网格一样,材质一样,但是材质属性不一样)合批,单个合批最大上限为511个对象.\n" +
                                               "1.#pragma multi_compile_instancing 添加此指令后会使材质面板上曝露Instaning开关,同时会生成相应的Instancing变体\n" +
                                               "2.UNITY_VERTEX_INPUT_INSTANCE_ID 在顶点着色器的输入(appdata)和输出(v2f,可选项)中添加\n" +
                                               "3.UNITY_INSTANCING_BUFFER_START(arrayName) / UNITY_INSTANCING_BUFFER_END(arrayName) 将每个你需要实例化的属性都封装在这个常量寄存器中\n" +
                                               "4.UNITY_DEFINE_INSTANCED_PROP(type, name) 在上面的START和END间把需要的每条属性加进来\n" +
                                               "5.UNITY_SETUP_INSTANCE_ID(v); 需放在顶点着色器/片断着色器(可选)中最开始的地方,这样才能访问到全局的unity_InstanceID\n" +
                                               "6.UNITY_TRANSFER_INSTANCE_ID(v, o); 当需要将实例化ID传到片断着色器时,在顶点着色器中添加\n" +
                                               "7.UNITY_ACCESS_INSTANCED_PROP(arrayName, propName) 在片断着色器中访问具体的实例化变量\n");
            ShaderReferenceUtil.DrawOneContent("Instancing选项", "对GPU Instancing进行一些设置\n" +
                                               "• #pragma instancing_options forcemaxcount:batchSize 强制设置单个批次内Instancing的最大数量,最大值和默认值是500\n" +
                                               "• #pragma instancing_options maxcount:batchSize 设置单个批次内Instancing的最大数量,仅Vulkan, Xbox One和Switch有效");

            EditorGUILayout.EndScrollView();
        }
Beispiel #7
0
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            ShaderReferenceUtil.DrawTitle("Cull");
            ShaderReferenceUtil.DrawOneContent("Cull Back | Front | Off", "背面剔除,默认值为Back。\nBack:表示剔除背面,也就是显示正面,这也是最常用的设置。\nFront:表示剔除前面,只显示背面。\nOff:表示关闭剔除,也就是正反面都渲染。");
            ShaderReferenceUtil.DrawTitle("模版测试");
            ShaderReferenceUtil.DrawOneContent("Stencil", "模板缓冲区(StencilBuffer)可以为屏幕上的每个像素点保存一个无符号整数值,这个值的具体意义视程序的具体应用而定.在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值.这个比较的过程被称为模板测试.\n将StencilBuffer的值与ReadMask与运算,然后与Ref值进行Comp比较,结果为true时进行Pass操作,否则进行Fail操作,操作值写入StencilBuffer前先与WriteMask与运算.\n公式:(Ref & ReadMask) Comp (StencilBufferValue & ReadMask)\n\n" +
                                               "Stencil\n" +
                                               "{\n" +
                                               "\n    Ref [_Stencil]" +
                                               "\n    ReadMask [_StencilReadMask]" +
                                               "\n    WriteMask [_StencilWriteMask]" +
                                               "\n    Comp [_StencilComp] ((UnityEngine.Rendering.CompareFunction))" +
                                               "\n    Pass [_StencilOp] (UnityEngine.Rendering.StencilOp)" +
                                               "\n    Fail [_Fail]" +
                                               "\n    ZFail [_ZFail]" +
                                               "\n}" +
                                               "\nRef:\t设定的参考值,这个值将用来与模板缓冲中的值进行比较.取值范围位为0-255的整数." +
                                               "\nReadMask:\tReadMask的值将和Ref的值以及模板缓冲中的值进行按位与(&)操作,取值范围也是0-255的整数,默认值为255(二进制位11111111),即读取的时候不对Ref的值和模板缓冲中的值产生修改,读取的还是原始值." +
                                               "\nWriteMask:\tWriteMask的值是当写入模板缓冲时进行的按位与操作,取值范围是0-255的整数,默认值也是255,即不做任何修改." +
                                               "\nComp:\t定义Ref与模板缓冲中的值比较的操作函数,默认值为always." +
                                               "\nPass:\t当模板测试(和深度测试)通过时,则根据(stencilOperation值)对模板缓冲值进行处理,默认值为keep." +
                                               "\nFail:\t当模板测试(和深度测试)失败时,则根据(stencilOperation值)对模板缓冲值进行处理,默认值为keep." +
                                               "\nZFail:\t当模板测试通过而深度测试失败时,则根据(stencilOperation值)对模板缓冲值进行处理,默认值为keep.");
            ShaderReferenceUtil.DrawOneContent("Comp(比较操作)",
                                               "\nLess:\t相当于“<”操作,即仅当左边<右边,模板测试通过,渲染像素." +
                                               "\nGreater:\t相当于“>”操作,即仅当左边>右边,模板测试通过,渲染像素." +
                                               "\nLequal:\t相当于“<=”操作,即仅当左边<=右边,模板测试通过,渲染像素." +
                                               "\nGequal:\t相当于“>=”操作,即仅当左边>=右边,模板测试通过,渲染像素." +
                                               "\nEqual:\t相当于“=”操作,即仅当左边=右边,模板测试通过,渲染像素." +
                                               "\nNotEqual:\t相当于“!=”操作,即仅当左边!=右边,模板测试通过,渲染像素." +
                                               "\nAlways:\t不管公式两边为何值,模板测试总是通过,渲染像素." +
                                               "\nNever:\t不管公式两边为何值,模板测试总是失败 ,像素被抛弃.");
            ShaderReferenceUtil.DrawOneContent("模版缓冲区的更新",
                                               "\nKeep:\t保留当前缓冲中的内容,即stencilBufferValue不变." +
                                               "\nZero:\t将0写入缓冲,即stencilBufferValue值变为0." +
                                               "\nReplace:\t将参考值写入缓冲,即将referenceValue赋值给stencilBufferValue." +
                                               "\nIncrSat:\t将当前模板缓冲值加1,如果stencilBufferValue超过255了,那么保留为255,即不大于255." +
                                               "\nDecrSat:\t将当前模板缓冲值减1,如果stencilBufferValue超过为0,那么保留为0,即不小于0." +
                                               "\nNotEqual:\t相当于“!=”操作,即仅当左边!=右边,模板测试通过,渲染像素." +
                                               "\nInvert:\t将当前模板缓冲值(stencilBufferValue)按位取反." +
                                               "\nIncrWrap:\t当前缓冲的值加1,如果缓冲值超过255了,那么变成0,(然后继续自增)." +
                                               "\nDecrWrap:\t当前缓冲的值减1,如果缓冲值已经为0,那么变成255,(然后继续自减).");

            ShaderReferenceUtil.DrawTitle("深度缓冲");
            ShaderReferenceUtil.DrawOneContent("ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Never | Always)", "深度测试,拿当前像素的深度值与深度缓冲中的深度值进行比较,默认值为LEqual。" +
                                               "可通过在属性中添加枚举UnityEngine.Rendering.CompareFunction\n" +
                                               "\nDisabled: 禁用,相当于永远通过。" +
                                               "\nNever: 于永远不通过。" +
                                               "\nLess:小于,表示如果当前像素的深度值小于深度缓冲中的深度值,则通过,以下类同。" +
                                               "\nEqual:等于。" +
                                               "\nLEqual:小于等于。" +
                                               "\nGreater:大于。" +
                                               "\nNotEqual:不等于。" +
                                               "\nGequal:大于等于。" +
                                               "\nAlways:永远通过。");
            ShaderReferenceUtil.DrawOneContent("ZTest[unity_GUIZTestMode]", "unity_GUIZTestMode用于UI材质中,此值默认为LEqual,仅当UI中Canvas模式为Overlay时,值为Always.");
            ShaderReferenceUtil.DrawOneContent("ZWrite On | Off", "深度写入,默认值为On。\nOn:向深度缓冲中写入深度值。\nOff:关闭深度写入。");
            ShaderReferenceUtil.DrawOneContent("Offset Factor, Units", "深度偏移,offset = (m * factor) + (r * units),默认值为0,0" +
                                               "\nm:指多边形的深度斜率(在光栅化阶段计算得出)中的最大值,多边形越是与近裁剪面平行,m值就越接近0。" +
                                               "\nr:表示能产生在窗口坐标系的深度值中可分辨的差异的最小值,r是由具体实现OpenGL的平台指定的一个常量。" +
                                               "\n结论:一个大于0的offset会把模型推远,一个小于0的offset会把模型拉近。");

            ShaderReferenceUtil.DrawTitle("颜色遮罩");
            ShaderReferenceUtil.DrawOneContent("ColorMask RGB | A | 0 | R、G、B、A的任意组合", "颜色遮罩,默认值为:RGBA,表示写入RGBA四个通道。");
            ShaderReferenceUtil.DrawTitle("混合");
            ShaderReferenceUtil.DrawOneContent("说明", "源颜色*SrcFactor + 目标颜色*DstFactor" +
                                               "\n颜色混合,源颜色与目标颜色以给定的公式进行混合出最终的新颜色。" +
                                               "\n源颜色:当前Shader计算出的颜色。" +
                                               "\n目标颜色:已经存在颜色缓存中的颜色。默认值为Blend Off,即表示关闭混合。" +
                                               "\n在混合时可以针对某个RT做混合,比如Blend 3 One One,就是对RenderTarget3做混合。");
            ShaderReferenceUtil.DrawOneContent("Blend SrcFactor DstFactor", "SrcFactor为源颜色因子,DstFactor为目标颜色因子,将两者按Op中指定的操作进行混合。");
            ShaderReferenceUtil.DrawOneContent("Blend SrcFactor DstFactor, SrcFactorA DstFactorA", "对RGB和A通道分别做混合操作。");
            ShaderReferenceUtil.DrawOneContent("BlendOp Op", "混合时的操作运算符,默认值为Add(加法操作)。");
            ShaderReferenceUtil.DrawOneContent("BlendOp OpColor, OpAlpha", "对RGB和A通道分别指定混合运算符。");
            ShaderReferenceUtil.DrawOneContent("AlphaToMask On | Off", "当值为On时,在使用MSAA时,会根据像素结果将alpha值进行修改多重采样覆盖率,对植被和其他经过alpha测试的着色器非常有用。");
            ShaderReferenceUtil.DrawOneContent("Blend factors", "混合因子" +
                                               "\nOne:源或目标的完整值" +
                                               "\nZero:0" +
                                               "\nSrcColor:源的颜色值" +
                                               "\nSrcAlpha:源的Alpha值" +
                                               "\nDstColor:目标的颜色值" +
                                               "\nDstAlpha:目标的Alpha值" +
                                               "\nOneMinusSrcColor:1-源颜色得到的值" +
                                               "\nOneMinusSrcAlpha:1-源Alpha得到的值" +
                                               "\nOneMinusDstColor:1-目标颜色得到的值" +
                                               "\nOneMinusDstAlpha:1-目标Alpha得到的值");
            ShaderReferenceUtil.DrawOneContent("Blend Types", "常用的几种混合类型" +
                                               "\nBlend SrcAlpha OneMinusSrcAlpha// Traditional transparency" +
                                               "\nBlend One OneMinusSrcAlpha// Premultiplied transparency" +
                                               "\nBlend One One" +
                                               "\nBlend OneMinusDstColor One // Soft Additive" +
                                               "\nBlend DstColor Zero // Multiplicative" +
                                               "\nBlend DstColor SrcColor // 2x Multiplicative");
            ShaderReferenceUtil.DrawOneContent("Blend operations", "混合操作的具体运算符" +
                                               "\nAdd:源+目标" +
                                               "\nSub:源-目标" +
                                               "\nRevSub:目标-源" +
                                               "\nMin:源与目标中最小值" +
                                               "\nMax:源与目标中最大值" +
                                               "\n以下仅用于DX11.1中" +
                                               "\nLogicalClear" +
                                               "\nLogicalSet" +
                                               "\nLogicalCopy" +
                                               "\nLogicalCopyInverted" +
                                               "\nLogicalNoop" +
                                               "\nLogicalInvert" +
                                               "\nLogicalAnd" +
                                               "\nLogicalNand" +
                                               "\nLogicalOr" +
                                               "\nLogicalNor" +
                                               "\nLogicalXor" +
                                               "\nLogicalEquiv" +
                                               "\nLogicalAndReverse" +
                                               "\nLogicalAndInverted" +
                                               "\nLogicalOrReverse" +
                                               "\nLogicalOrInverted");
            EditorGUILayout.EndScrollView();
        }
        public void DrawMainGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

            ShaderReferenceUtil.DrawTitle("空间变换(矩阵)");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_MVP", "模型空间>>投影空间");
                ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_MV", "模型空间>>观察空间");
                ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_V", "视图空间");
                ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_P", "投影空间");
                ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_VP", "视图空间>投影空间");
                //ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_T_MV", "");
                //ShaderReferenceUtil.DrawOneContent("UNITY_MATRIX_IT_MV", "");
                ShaderReferenceUtil.DrawOneContent("unity_ObjectToWorld", "本地空间>>世界空间");
                ShaderReferenceUtil.DrawOneContent("unity_WorldToObject", "世界空间>本地空间");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("GetObjectToWorldMatrix()", "本地空间到世界空间的矩阵");
                ShaderReferenceUtil.DrawOneContent("GetWorldToObjectMatrix()", "世界空间到本地空间的矩阵");
                ShaderReferenceUtil.DrawOneContent("GetWorldToViewMatrix()", "世界空间到观察空间的矩阵");
                ShaderReferenceUtil.DrawOneContent("GetWorldToHClipMatrix()", "世界空间到齐次裁剪空间的矩阵");
                ShaderReferenceUtil.DrawOneContent("GetViewToHClipMatrix()", "观察空间到齐次裁剪空间的矩阵");
                break;
            }

            ShaderReferenceUtil.DrawTitle("空间变换(方法)");
            switch (ShaderReferenceEditorWindow.mPipline)
            {
            case ShaderReferenceEditorWindow.Pipline.BuildIn:
                ShaderReferenceUtil.DrawOneContent("UnityObjectToClipPos(v.vertex)", "将模型空间下的顶点转换到齐次裁剪空间");
                ShaderReferenceUtil.DrawOneContent("UnityObjectToWorldNormal(v.normal)", "将模型空间下的法线转换到世界空间(已归一化)");
                ShaderReferenceUtil.DrawOneContent("UnityObjectToWorldDir (v.tangent)", "将模型空间下的切线转换到世界空间(已归一化)");
                ShaderReferenceUtil.DrawOneContent("UnityWorldSpaceLightDir (i.worldPos)", "世界空间下顶点到灯光方向的向量(未归一化)");
                ShaderReferenceUtil.DrawOneContent("UnityWorldSpaceViewDir (i.worldPos)", "世界空间下顶点到视线方向的向量(未归一化)");
                break;

            case ShaderReferenceEditorWindow.Pipline.URP:
                ShaderReferenceUtil.DrawOneContent("float3 TransformObjectToWorld (float3 positionOS)", "从本地空间变换到世界空间");
                ShaderReferenceUtil.DrawOneContent("float3 TransformWorldToObject (float3 positionWS)", "从世界空间变换到本地空间");
                ShaderReferenceUtil.DrawOneContent("float3 TransformWorldToView(float3 positionWS)", "从世界空间变换到视图空间");

                ShaderReferenceUtil.DrawOneContent("float4 TransformObjectToHClip(float3 positionOS)", "将模型空间下的顶点变换到齐次裁剪空间");
                ShaderReferenceUtil.DrawOneContent("float4 TransformWorldToHClip(float3 positionWS)", "将世界空间下的顶点变换到齐次裁剪空间");
                ShaderReferenceUtil.DrawOneContent("float4 TransformWViewToHClip (float3 positionVS)", "将视图空间下的顶点变换到齐次裁剪空间");
                ShaderReferenceUtil.DrawOneContent("float3 TransformObjectToWorldNormal (float3 normalOS)", "将法线从本地空间变换到世界空间(已归一化)");
                break;
            }

            ShaderReferenceUtil.DrawTitle("基础变换矩阵");
            ShaderReferenceUtil.DrawOneContent("平移矩阵", "float4x4 M_translate = float4x4(\n" +
                                               "\t1, 0, 0, T.x,\n" +
                                               "\t0, 1, 0, T.y,\n" +
                                               "\t0, 0, 1, T.z,\n" +
                                               "\t0, 0, 0, 1);");

            ShaderReferenceUtil.DrawOneContent("缩放矩阵", "float4x4 M_scale = float4x4(\n" +
                                               "\tS.x, 0, 0, 0,\n" +
                                               "\t0, S.y, 0, 0,\n" +
                                               "\t0, 0, S.z, 0,\n" +
                                               "\t0, 0, 0, 1);");

            ShaderReferenceUtil.DrawOneContent("旋转矩阵(X轴)", "float4x4 M_rotationX = float4x4(\n" +
                                               "\t1, 0, 0, 0,\n" +
                                               "\t0, cos(θ), sin(θ), 0,\n" +
                                               "\t0, -sin(θ), cos(θ), 0,\n" +
                                               "\t0, 0, 0, 1);");

            ShaderReferenceUtil.DrawOneContent("旋转矩阵(Y轴)", "float4x4 M_rotationY = float4x4(\n" +
                                               "\tcos(θ), 0, sin(θ), 0,\n" +
                                               "\t0, 1, 0, 0,\n" +
                                               "\t-sin(θy), 0, cos(θ), 0,\n" +
                                               "\t0, 0, 0, 1);");

            ShaderReferenceUtil.DrawOneContent("旋转矩阵(Z轴)", "float4x4 M_rotationZ = float4x4(\n" +
                                               "\tcos(θ), sin(θ), 0, 0,\n" +
                                               "\t-sin(θ), cos(θ), 0, 0,\n" +
                                               "\t0, 0, 1, 0,\n" +
                                               "\t0, 0, 0, 1);");

            EditorGUILayout.EndScrollView();
        }