Shader学习基础之六UsePass和#include
来源:互联网 发布:java整形转换为字符串 编辑:程序博客网 时间:2024/06/05 16:45
昨天,有位同学在群里面问了shader如何继承,一开始我想是不能和c#中一样的继承,但是我发现还是有方法的,这里我来探讨一下这两个方法。
方法一:
使用UsePass:
我们需要写出两个shader文件,shader中肯定会有子着色器和pass通道,这是众所周知的,这里我先列举两个简单的shader代码:
shader1:被引用的shader
Shader "Unlit/myshader1"{ Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Name "Mypass" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata_full v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } }}
shader2:引用上面的pass
Shader "Unlit/myshader2"{ Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 UsePass "Unlit/myshader1/MYPASS" }}
注意:这里我们使用了UsePass这个命令来引用Unlit/myshader1这个shader里面的Mypass这个pass,但是值得注意的是,UsePass命令使用的时候,必须使用大写形式的名字。
测试效果:
PS:如果我们在shader1中定义了_Color属性,而且在 Name “Mypass”这个通道内有使用,但是我们在shader2中没有定义这个属性的时候,shader2中会给一个默认值。如下图:
可见_Color中给的默认值为(0,0,0,0);
shader1属性定义:
Properties { _MainTex ("Texture", 2D) = "white" {} _Color("Color",Color) = (1,1,1,1) }
shader2属性定义:
Properties { _MainTex ("Texture", 2D) = "white" {} }
方法二:
使用include引用外部库:
shader1:
Shader "Unlit/myshader1"{ Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Name "Mypass" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata_full v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } }}
这其中有一段代码是#include “UnityCG.cginc”,这就是引用了外部库的意思,当然这个我们在界面看不到,但是我们右键我们unity3d的图标,打开文件所在位置unity5.6.2\Editor\Data\CGIncludes这个文件夹就可以看到很多的库文件,我们一次往下找就可以找到,我们打开这个库
#ifndef UNITY_CG_INCLUDED#define UNITY_CG_INCLUDED#define UNITY_PI 3.14159265359f#define UNITY_TWO_PI 6.28318530718f#define UNITY_FOUR_PI 12.56637061436f#define UNITY_INV_PI 0.31830988618f#define UNITY_INV_TWO_PI 0.15915494309f#define UNITY_INV_FOUR_PI 0.07957747155f#define UNITY_HALF_PI 1.57079632679f#define UNITY_INV_HALF_PI 0.636619772367f#include "UnityShaderVariables.cginc"#include "UnityShaderUtilities.cginc"#include "UnityInstancing.cginc"#ifdef UNITY_COLORSPACE_GAMMA#define unity_ColorSpaceGrey fixed4(0.5, 0.5, 0.5, 0.5)#define unity_ColorSpaceDouble fixed4(2.0, 2.0, 2.0, 2.0)#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)#define unity_ColorSpaceLuminance half4(0.22, 0.707, 0.071, 0.0) // Legacy: alpha is set to 0.0 to specify gamma mode#else // Linear values#define unity_ColorSpaceGrey fixed4(0.214041144, 0.214041144, 0.214041144, 0.5)#define unity_ColorSpaceDouble fixed4(4.59479380, 4.59479380, 4.59479380, 2.0)#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) // standard dielectric reflectivity coef at incident angle (= 4%)#define unity_ColorSpaceLuminance half4(0.0396819152, 0.458021790, 0.00609653955, 1.0) // Legacy: alpha is set to 1.0 to specify linear mode#endif// -------------------------------------------------------------------// helper functions and macros used in many standard shaders#if defined (DIRECTIONAL) || defined (DIRECTIONAL_COOKIE) || defined (POINT) || defined (SPOT) || defined (POINT_NOATT) || defined (POINT_COOKIE)#define USING_LIGHT_MULTI_COMPILE#endif#define SCALED_NORMAL v.normal// These constants must be kept in sync with RGBMRanges.h#define LIGHTMAP_RGBM_SCALE 5.0#define EMISSIVE_RGBM_SCALE 97.0// Should SH (light probe / ambient) calculations be performed?// - Presence of *either* of static or dynamic lightmaps means that diffuse indirect ambient is already in them, so no need for SH.// - Passes that don't do ambient (additive, shadowcaster etc.) should not do SH either.#define UNITY_SHOULD_SAMPLE_SH (!defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON) && !defined(UNITY_PASS_FORWARDADD) && !defined(UNITY_PASS_PREPASSBASE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(UNITY_PASS_META))struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID};struct appdata_tan { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID};struct appdata_full { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 texcoord2 : TEXCOORD2; float4 texcoord3 : TEXCOORD3; fixed4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID};// Legacy for compatibility with existing shadersinline bool IsGammaSpace(){ #ifdef UNITY_COLORSPACE_GAMMA return true; #else return false; #endif}inline float GammaToLinearSpaceExact (float value){ if (value <= 0.04045F) return value / 12.92F; else if (value < 1.0F) return pow((value + 0.055F)/1.055F, 2.4F); else return pow(value, 2.2F);}inline half3 GammaToLinearSpace (half3 sRGB){ // Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1 return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h); // Precise version, useful for debugging. //return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));}inline float LinearToGammaSpaceExact (float value){ if (value <= 0.0F) return 0.0F; else if (value <= 0.0031308F) return 12.92F * value; else if (value < 1.0F) return 1.055F * pow(value, 0.4166667F) - 0.055F; else return pow(value, 0.45454545F);}inline half3 LinearToGammaSpace (half3 linRGB){ linRGB = max(linRGB, half3(0.h, 0.h, 0.h)); // An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1 return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h); // Exact version, useful for debugging. //return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));}// Tranforms position from world to homogenous spaceinline float4 UnityWorldToClipPos( in float3 pos ){ return mul(UNITY_MATRIX_VP, float4(pos, 1.0));}// Tranforms position from view to homogenous spaceinline float4 UnityViewToClipPos( in float3 pos ){ return mul(UNITY_MATRIX_P, float4(pos, 1.0));}// Tranforms position from object to camera spaceinline float3 UnityObjectToViewPos( in float3 pos ){ return mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, float4(pos, 1.0))).xyz;}inline float3 UnityObjectToViewPos(float4 pos) // overload for float4; avoids "implicit truncation" warning for existing shaders{ return UnityObjectToViewPos(pos.xyz);}// Tranforms position from world to camera spaceinline float3 UnityWorldToViewPos( in float3 pos ){ return mul(UNITY_MATRIX_V, float4(pos, 1.0)).xyz;}// Transforms direction from object to world spaceinline float3 UnityObjectToWorldDir( in float3 dir ){ return normalize(mul((float3x3)unity_ObjectToWorld, dir));}// Transforms direction from world to object spaceinline float3 UnityWorldToObjectDir( in float3 dir ){ return normalize(mul((float3x3)unity_WorldToObject, dir));}// Transforms normal from object to world spaceinline float3 UnityObjectToWorldNormal( in float3 norm ){#ifdef UNITY_ASSUME_UNIFORM_SCALING return UnityObjectToWorldDir(norm);#else // mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)} return normalize(mul(norm, (float3x3)unity_WorldToObject));#endif}// Computes world space light direction, from world space positioninline float3 UnityWorldSpaceLightDir( in float3 worldPos ){ #ifndef USING_LIGHT_MULTI_COMPILE return _WorldSpaceLightPos0.xyz - worldPos * _WorldSpaceLightPos0.w; #else #ifndef USING_DIRECTIONAL_LIGHT return _WorldSpaceLightPos0.xyz - worldPos; #else return _WorldSpaceLightPos0.xyz; #endif #endif}// Computes world space light direction, from object space position// *Legacy* Please use UnityWorldSpaceLightDir insteadinline float3 WorldSpaceLightDir( in float4 localPos ){ float3 worldPos = mul(unity_ObjectToWorld, localPos).xyz; return UnityWorldSpaceLightDir(worldPos);}// Computes object space light directioninline float3 ObjSpaceLightDir( in float4 v ){ float3 objSpaceLightPos = mul(unity_WorldToObject, _WorldSpaceLightPos0).xyz; #ifndef USING_LIGHT_MULTI_COMPILE return objSpaceLightPos.xyz - v.xyz * _WorldSpaceLightPos0.w; #else #ifndef USING_DIRECTIONAL_LIGHT return objSpaceLightPos.xyz - v.xyz; #else return objSpaceLightPos.xyz; #endif #endif}// Computes world space view direction, from object space positioninline float3 UnityWorldSpaceViewDir( in float3 worldPos ){ return _WorldSpaceCameraPos.xyz - worldPos;}// Computes world space view direction, from object space position// *Legacy* Please use UnityWorldSpaceViewDir insteadinline float3 WorldSpaceViewDir( in float4 localPos ){ float3 worldPos = mul(unity_ObjectToWorld, localPos).xyz; return UnityWorldSpaceViewDir(worldPos);}// Computes object space view directioninline float3 ObjSpaceViewDir( in float4 v ){ float3 objSpaceCameraPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz, 1)).xyz; return objSpaceCameraPos - v.xyz;}// Declares 3x3 matrix 'rotation', filled with tangent space basis#define TANGENT_SPACE_ROTATION \ float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) ) * v.tangent.w; \ float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal )// Used in ForwardBase pass: Calculates diffuse lighting from 4 point lights, with data packed in a special way.float3 Shade4PointLights ( float4 lightPosX, float4 lightPosY, float4 lightPosZ, float3 lightColor0, float3 lightColor1, float3 lightColor2, float3 lightColor3, float4 lightAttenSq, float3 pos, float3 normal){ // to light vectors float4 toLightX = lightPosX - pos.x; float4 toLightY = lightPosY - pos.y; float4 toLightZ = lightPosZ - pos.z; // squared lengths float4 lengthSq = 0; lengthSq += toLightX * toLightX; lengthSq += toLightY * toLightY; lengthSq += toLightZ * toLightZ; // don't produce NaNs if some vertex position overlaps with the light lengthSq = max(lengthSq, 0.000001); // NdotL float4 ndotl = 0; ndotl += toLightX * normal.x; ndotl += toLightY * normal.y; ndotl += toLightZ * normal.z; // correct NdotL float4 corr = rsqrt(lengthSq); ndotl = max (float4(0,0,0,0), ndotl * corr); // attenuation float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq); float4 diff = ndotl * atten; // final color float3 col = 0; col += lightColor0 * diff.x; col += lightColor1 * diff.y; col += lightColor2 * diff.z; col += lightColor3 * diff.w; return col;}// Used in Vertex pass: Calculates diffuse lighting from lightCount lights. Specifying true to spotLight is more expensive// to calculate but lights are treated as spot lights otherwise they are treated as point lights.float3 ShadeVertexLightsFull (float4 vertex, float3 normal, int lightCount, bool spotLight){ float3 viewpos = UnityObjectToViewPos (vertex); float3 viewN = normalize (mul ((float3x3)UNITY_MATRIX_IT_MV, normal)); float3 lightColor = UNITY_LIGHTMODEL_AMBIENT.xyz; for (int i = 0; i < lightCount; i++) { float3 toLight = unity_LightPosition[i].xyz - viewpos.xyz * unity_LightPosition[i].w; float lengthSq = dot(toLight, toLight); // don't produce NaNs if some vertex position overlaps with the light lengthSq = max(lengthSq, 0.000001); toLight *= rsqrt(lengthSq); float atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[i].z); if (spotLight) { float rho = max (0, dot(toLight, unity_SpotDirection[i].xyz)); float spotAtt = (rho - unity_LightAtten[i].x) * unity_LightAtten[i].y; atten *= saturate(spotAtt); } float diff = max (0, dot (viewN, toLight)); lightColor += unity_LightColor[i].rgb * (diff * atten); } return lightColor;}float3 ShadeVertexLights (float4 vertex, float3 normal){ return ShadeVertexLightsFull (vertex, normal, 4, false);}// normal should be normalized, w=1.0half3 SHEvalLinearL0L1 (half4 normal){ half3 x; // Linear (L1) + constant (L0) polynomial terms x.r = dot(unity_SHAr,normal); x.g = dot(unity_SHAg,normal); x.b = dot(unity_SHAb,normal); return x;}// normal should be normalized, w=1.0half3 SHEvalLinearL2 (half4 normal){ half3 x1, x2; // 4 of the quadratic (L2) polynomials half4 vB = normal.xyzz * normal.yzzx; x1.r = dot(unity_SHBr,vB); x1.g = dot(unity_SHBg,vB); x1.b = dot(unity_SHBb,vB); // Final (5th) quadratic (L2) polynomial half vC = normal.x*normal.x - normal.y*normal.y; x2 = unity_SHC.rgb * vC; return x1 + x2;}// normal should be normalized, w=1.0// output in active color spacehalf3 ShadeSH9 (half4 normal){ // Linear + constant polynomial terms half3 res = SHEvalLinearL0L1 (normal); // Quadratic polynomials res += SHEvalLinearL2 (normal);# ifdef UNITY_COLORSPACE_GAMMA res = LinearToGammaSpace (res);# endif return res;}// OBSOLETE: for backwards compatibility with 5.0half3 ShadeSH3Order(half4 normal){ // Quadratic polynomials half3 res = SHEvalLinearL2 (normal);# ifdef UNITY_COLORSPACE_GAMMA res = LinearToGammaSpace (res);# endif return res;}#if UNITY_LIGHT_PROBE_PROXY_VOLUME// normal should be normalized, w=1.0half3 SHEvalLinearL0L1_SampleProbeVolume (half4 normal, float3 worldPos){ const float transformToLocal = unity_ProbeVolumeParams.y; const float texelSizeX = unity_ProbeVolumeParams.z; //The SH coefficients textures and probe occlusion are packed into 1 atlas. //------------------------- //| ShR | ShG | ShB | Occ | //------------------------- float3 position = (transformToLocal == 1.0f) ? mul(unity_ProbeVolumeWorldToObject, float4(worldPos, 1.0)).xyz : worldPos; float3 texCoord = (position - unity_ProbeVolumeMin.xyz) * unity_ProbeVolumeSizeInv.xyz; texCoord.x = texCoord.x * 0.25f; // We need to compute proper X coordinate to sample. // Clamp the coordinate otherwize we'll have leaking between RGB coefficients float texCoordX = clamp(texCoord.x, 0.5f * texelSizeX, 0.25f - 0.5f * texelSizeX); // sampler state comes from SHr (all SH textures share the same sampler) texCoord.x = texCoordX; half4 SHAr = UNITY_SAMPLE_TEX3D_SAMPLER(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord); texCoord.x = texCoordX + 0.25f; half4 SHAg = UNITY_SAMPLE_TEX3D_SAMPLER(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord); texCoord.x = texCoordX + 0.5f; half4 SHAb = UNITY_SAMPLE_TEX3D_SAMPLER(unity_ProbeVolumeSH, unity_ProbeVolumeSH, texCoord); // Linear + constant polynomial terms half3 x1; x1.r = dot(SHAr, normal); x1.g = dot(SHAg, normal); x1.b = dot(SHAb, normal); return x1;}#endif// normal should be normalized, w=1.0half3 ShadeSH12Order (half4 normal){ // Linear + constant polynomial terms half3 res = SHEvalLinearL0L1 (normal);# ifdef UNITY_COLORSPACE_GAMMA res = LinearToGammaSpace (res);# endif return res;}// Transforms 2D UV by scale/bias property#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)// Deprecated. Used to transform 4D UV by a fixed function texture matrix. Now just returns the passed UV.#define TRANSFORM_UV(idx) v.texcoord.xystruct v2f_vertex_lit { float2 uv : TEXCOORD0; fixed4 diff : COLOR0; fixed4 spec : COLOR1;};inline fixed4 VertexLight( v2f_vertex_lit i, sampler2D mainTex ){ fixed4 texcol = tex2D( mainTex, i.uv ); fixed4 c; c.xyz = ( texcol.xyz * i.diff.xyz + i.spec.xyz * texcol.a ); c.w = texcol.w * i.diff.w; return c;}// Calculates UV offset for parallax bump mappinginline float2 ParallaxOffset( half h, half height, half3 viewDir ){ h = h * height - height/2.0; float3 v = normalize(viewDir); v.z += 0.42; return h * (v.xy / v.z);}// Converts color to luminance (grayscale)inline half Luminance(half3 rgb){ return dot(rgb, unity_ColorSpaceLuminance.rgb);}// Convert rgb to luminance// with rgb in linear space with sRGB primaries and D65 white pointhalf LinearRgbToLuminance(half3 linearRgb){ return dot(linearRgb, half3(0.2126729f, 0.7151522f, 0.0721750f));}half4 UnityEncodeRGBM (half3 color, float maxRGBM){ float kOneOverRGBMMaxRange = 1.0 / maxRGBM; const float kMinMultiplier = 2.0 * 1e-2; float3 rgb = color * kOneOverRGBMMaxRange; float alpha = max(max(rgb.r, rgb.g), max(rgb.b, kMinMultiplier)); alpha = ceil(alpha * 255.0) / 255.0; // Division-by-zero warning from d3d9, so make compiler happy. alpha = max(alpha, kMinMultiplier); return half4(rgb / alpha, alpha);}// Decodes HDR textures// handles dLDR, RGBM formatsinline half3 DecodeHDR (half4 data, half4 decodeInstructions){ // Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels) half alpha = decodeInstructions.w * (data.a - 1.0) + 1.0; // If Linear mode is not supported we can skip exponent part #if defined(UNITY_COLORSPACE_GAMMA) return (decodeInstructions.x * alpha) * data.rgb; #else # if defined(UNITY_USE_NATIVE_HDR) return decodeInstructions.x * data.rgb; // Multiplier for future HDRI relative to absolute conversion. # else return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * data.rgb; # endif #endif}// Decodes HDR textures// handles dLDR, RGBM formats// Called by DecodeLightmap when UNITY_NO_RGBM is not defined.inline half3 DecodeLightmapRGBM (half4 data, half4 decodeInstructions){ // If Linear mode is not supported we can skip exponent part #if defined(UNITY_COLORSPACE_GAMMA) # if defined(UNITY_FORCE_LINEAR_READ_FOR_RGBM) return (decodeInstructions.x * data.a) * sqrt(data.rgb); # else return (decodeInstructions.x * data.a) * data.rgb; # endif #else return (decodeInstructions.x * pow(data.a, decodeInstructions.y)) * data.rgb; #endif}// Decodes doubleLDR encoded lightmaps.inline half3 DecodeLightmapDoubleLDR( fixed4 color ){ return 2.0 * color.rgb;}inline half3 DecodeLightmap( fixed4 color, half4 decodeInstructions){#if defined(UNITY_NO_RGBM) return DecodeLightmapDoubleLDR( color );#else return DecodeLightmapRGBM( color, decodeInstructions );#endif}half4 unity_Lightmap_HDR;inline half3 DecodeLightmap( fixed4 color ){ return DecodeLightmap( color, unity_Lightmap_HDR );}half4 unity_DynamicLightmap_HDR;// Decodes Enlighten RGBM encoded lightmaps// NOTE: Enlighten dynamic texture RGBM format is _different_ from standard Unity HDR textures// (such as Baked Lightmaps, Reflection Probes and IBL images)// Instead Enlighten provides RGBM texture in _Linear_ color space with _different_ exponent.// WARNING: 3 pow operations, might be very expensive for mobiles!inline half3 DecodeRealtimeLightmap( fixed4 color ){ //@TODO: Temporary until Geomerics gives us an API to convert lightmaps to RGBM in gamma space on the enlighten thread before we upload the textures.#if defined(UNITY_FORCE_LINEAR_READ_FOR_RGBM) return pow ((unity_DynamicLightmap_HDR.x * color.a) * sqrt(color.rgb), unity_DynamicLightmap_HDR.y);#else return pow ((unity_DynamicLightmap_HDR.x * color.a) * color.rgb, unity_DynamicLightmap_HDR.y);#endif}inline half3 DecodeDirectionalLightmap (half3 color, fixed4 dirTex, half3 normalWorld){ // In directional (non-specular) mode Enlighten bakes dominant light direction // in a way, that using it for half Lambert and then dividing by a "rebalancing coefficient" // gives a result close to plain diffuse response lightmaps, but normalmapped. // Note that dir is not unit length on purpose. Its length is "directionality", like // for the directional specular lightmaps. half halfLambert = dot(normalWorld, dirTex.xyz - 0.5) + 0.5; return color * halfLambert / max(1e-4h, dirTex.w);}// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. Note that 1.0 will not be encoded properly.inline float4 EncodeFloatRGBA( float v ){ float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0); float kEncodeBit = 1.0/255.0; float4 enc = kEncodeMul * v; enc = frac (enc); enc -= enc.yzww * kEncodeBit; return enc;}inline float DecodeFloatRGBA( float4 enc ){ float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0); return dot( enc, kDecodeDot );}// Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.inline float2 EncodeFloatRG( float v ){ float2 kEncodeMul = float2(1.0, 255.0); float kEncodeBit = 1.0/255.0; float2 enc = kEncodeMul * v; enc = frac (enc); enc.x -= enc.y * kEncodeBit; return enc;}inline float DecodeFloatRG( float2 enc ){ float2 kDecodeDot = float2(1.0, 1/255.0); return dot( enc, kDecodeDot );}// Encoding/decoding view space normals into 2D 0..1 vectorinline float2 EncodeViewNormalStereo( float3 n ){ float kScale = 1.7777; float2 enc; enc = n.xy / (n.z+1); enc /= kScale; enc = enc*0.5+0.5; return enc;}inline float3 DecodeViewNormalStereo( float4 enc4 ){ float kScale = 1.7777; float3 nn = enc4.xyz*float3(2*kScale,2*kScale,0) + float3(-kScale,-kScale,1); float g = 2.0 / dot(nn.xyz,nn.xyz); float3 n; n.xy = g*nn.xy; n.z = g-1; return n;}inline float4 EncodeDepthNormal( float depth, float3 normal ){ float4 enc; enc.xy = EncodeViewNormalStereo (normal); enc.zw = EncodeFloatRG (depth); return enc;}inline void DecodeDepthNormal( float4 enc, out float depth, out float3 normal ){ depth = DecodeFloatRG (enc.zw); normal = DecodeViewNormalStereo (enc);}inline fixed3 UnpackNormalDXT5nm (fixed4 packednormal){ fixed3 normal; normal.xy = packednormal.wy * 2 - 1; normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy))); return normal;}inline fixed3 UnpackNormal(fixed4 packednormal){#if defined(UNITY_NO_DXT5nm) return packednormal.xyz * 2 - 1;#else return UnpackNormalDXT5nm(packednormal);#endif}// Z buffer to linear 0..1 depthinline float Linear01Depth( float z ){ return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);}// Z buffer to linear depthinline float LinearEyeDepth( float z ){ return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w);}inline float2 UnityStereoScreenSpaceUVAdjustInternal(float2 uv, float4 scaleAndOffset){ return uv.xy * scaleAndOffset.xy + scaleAndOffset.zw;}inline float4 UnityStereoScreenSpaceUVAdjustInternal(float4 uv, float4 scaleAndOffset){ return float4(UnityStereoScreenSpaceUVAdjustInternal(uv.xy, scaleAndOffset), UnityStereoScreenSpaceUVAdjustInternal(uv.zw, scaleAndOffset));}#define UnityStereoScreenSpaceUVAdjust(x, y) UnityStereoScreenSpaceUVAdjustInternal(x, y)#if defined(UNITY_SINGLE_PASS_STEREO)float2 TransformStereoScreenSpaceTex(float2 uv, float w){ float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex]; return uv.xy * scaleOffset.xy + scaleOffset.zw * w;}inline float2 UnityStereoTransformScreenSpaceTex(float2 uv){ return TransformStereoScreenSpaceTex(saturate(uv), 1.0);}inline float4 UnityStereoTransformScreenSpaceTex(float4 uv){ return float4(UnityStereoTransformScreenSpaceTex(uv.xy), UnityStereoTransformScreenSpaceTex(uv.zw));}#else#define TransformStereoScreenSpaceTex(uv, w) uv#define UnityStereoTransformScreenSpaceTex(uv) uv#endif// Depth render texture helpers#define DECODE_EYEDEPTH(i) LinearEyeDepth(i)#define COMPUTE_EYEDEPTH(o) o = -UnityObjectToViewPos( v.vertex ).z#define COMPUTE_DEPTH_01 -(UnityObjectToViewPos( v.vertex ).z * _ProjectionParams.w)#define COMPUTE_VIEW_NORMAL normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal))// Helpers used in image effects. Most image effects use the same// minimal vertex shader (vert_img).struct appdata_img{ float4 vertex : POSITION; half2 texcoord : TEXCOORD0;};struct v2f_img{ float4 pos : SV_POSITION; half2 uv : TEXCOORD0;};float2 MultiplyUV (float4x4 mat, float2 inUV) { float4 temp = float4 (inUV.x, inUV.y, 0, 0); temp = mul (mat, temp); return temp.xy;}v2f_img vert_img( appdata_img v ){ v2f_img o; o.pos = UnityObjectToClipPos (v.vertex); o.uv = v.texcoord; return o;}// Projected screen position helpers#define V2F_SCREEN_TYPE float4inline float4 ComputeNonStereoScreenPos(float4 pos) { float4 o = pos * 0.5f; o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w; o.zw = pos.zw; return o;}inline float4 ComputeScreenPos(float4 pos) { float4 o = ComputeNonStereoScreenPos(pos);#if defined(UNITY_SINGLE_PASS_STEREO) o.xy = TransformStereoScreenSpaceTex(o.xy, pos.w);#endif return o;}inline float4 ComputeGrabScreenPos (float4 pos) { #if UNITY_UV_STARTS_AT_TOP float scale = -1.0; #else float scale = 1.0; #endif float4 o = pos * 0.5f; o.xy = float2(o.x, o.y*scale) + o.w;#ifdef UNITY_SINGLE_PASS_STEREO o.xy = TransformStereoScreenSpaceTex(o.xy, pos.w);#endif o.zw = pos.zw; return o;}// snaps post-transformed position to screen pixelsinline float4 UnityPixelSnap (float4 pos){ float2 hpc = _ScreenParams.xy * 0.5f; float2 pixelPos = round ((pos.xy / pos.w) * hpc); pos.xy = pixelPos / hpc * pos.w; return pos;}inline float2 TransformViewToProjection (float2 v) { return mul((float2x2)UNITY_MATRIX_P, v);}inline float3 TransformViewToProjection (float3 v) { return mul((float3x3)UNITY_MATRIX_P, v);}// Shadow caster pass helpersfloat4 UnityEncodeCubeShadowDepth (float z){ #ifdef UNITY_USE_RGBA_FOR_POINT_SHADOWS return EncodeFloatRGBA (min(z, 0.999)); #else return z; #endif}float UnityDecodeCubeShadowDepth (float4 vals){ #ifdef UNITY_USE_RGBA_FOR_POINT_SHADOWS return DecodeFloatRGBA (vals); #else return vals.r; #endif}float4 UnityClipSpaceShadowCasterPos(float4 vertex, float3 normal){ float4 wPos = mul(unity_ObjectToWorld, vertex); if (unity_LightShadowBias.z != 0.0) { float3 wNormal = UnityObjectToWorldNormal(normal); float3 wLight = normalize(UnityWorldSpaceLightDir(wPos.xyz)); // apply normal offset bias (inset position along the normal) // bias needs to be scaled by sine between normal and light direction // (http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/) // // unity_LightShadowBias.z contains user-specified normal offset amount // scaled by world space texel size. float shadowCos = dot(wNormal, wLight); float shadowSine = sqrt(1-shadowCos*shadowCos); float normalBias = unity_LightShadowBias.z * shadowSine; wPos.xyz -= wNormal * normalBias; } return mul(UNITY_MATRIX_VP, wPos);}// Legacy, not used anymore; kept around to not break existing user shadersfloat4 UnityClipSpaceShadowCasterPos(float3 vertex, float3 normal){ return UnityClipSpaceShadowCasterPos(float4(vertex, 1), normal);}float4 UnityApplyLinearShadowBias(float4 clipPos){#if defined(UNITY_REVERSED_Z) // We use max/min instead of clamp to ensure proper handling of the rare case // where both numerator and denominator are zero and the fraction becomes NaN. clipPos.z += max(-1, min(unity_LightShadowBias.x / clipPos.w, 0)); float clamped = min(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);#else clipPos.z += saturate(unity_LightShadowBias.x/clipPos.w); float clamped = max(clipPos.z, clipPos.w*UNITY_NEAR_CLIP_VALUE);#endif clipPos.z = lerp(clipPos.z, clamped, unity_LightShadowBias.y); return clipPos;}#ifdef SHADOWS_CUBE // Rendering into point light (cubemap) shadows #define V2F_SHADOW_CASTER_NOPOS float3 vec : TEXCOORD0; #define TRANSFER_SHADOW_CASTER_NOPOS_LEGACY(o,opos) o.vec = mul(unity_ObjectToWorld, v.vertex).xyz - _LightPositionRange.xyz; opos = UnityObjectToClipPos(v.vertex); #define TRANSFER_SHADOW_CASTER_NOPOS(o,opos) o.vec = mul(unity_ObjectToWorld, v.vertex).xyz - _LightPositionRange.xyz; opos = UnityObjectToClipPos(v.vertex); #define SHADOW_CASTER_FRAGMENT(i) return UnityEncodeCubeShadowDepth ((length(i.vec) + unity_LightShadowBias.x) * _LightPositionRange.w);#else // Rendering into directional or spot light shadows #define V2F_SHADOW_CASTER_NOPOS // Let embedding code know that V2F_SHADOW_CASTER_NOPOS is empty; so that it can workaround // empty structs that could possibly be produced. #define V2F_SHADOW_CASTER_NOPOS_IS_EMPTY #define TRANSFER_SHADOW_CASTER_NOPOS_LEGACY(o,opos) \ opos = UnityObjectToClipPos(v.vertex.xyz); \ opos = UnityApplyLinearShadowBias(opos); #define TRANSFER_SHADOW_CASTER_NOPOS(o,opos) \ opos = UnityClipSpaceShadowCasterPos(v.vertex, v.normal); \ opos = UnityApplyLinearShadowBias(opos); #define SHADOW_CASTER_FRAGMENT(i) return 0;#endif// Declare all data needed for shadow caster pass output (any shadow directions/depths/distances as needed),// plus clip space position.#define V2F_SHADOW_CASTER V2F_SHADOW_CASTER_NOPOS float4 pos : SV_POSITION// Vertex shader part, with support for normal offset shadows. Requires// position and normal to be present in the vertex input.#define TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) TRANSFER_SHADOW_CASTER_NOPOS(o,o.pos)// Vertex shader part, legacy. No support for normal offset shadows - because// that would require vertex normals, which might not be present in user-written shaders.#define TRANSFER_SHADOW_CASTER(o) TRANSFER_SHADOW_CASTER_NOPOS_LEGACY(o,o.pos)// ------------------------------------------------------------------// Alpha helper#define UNITY_OPAQUE_ALPHA(outputAlpha) outputAlpha = 1.0// ------------------------------------------------------------------// Fog helpers//// multi_compile_fog Will compile fog variants.// UNITY_FOG_COORDS(texcoordindex) Declares the fog data interpolator.// UNITY_TRANSFER_FOG(outputStruct,clipspacePos) Outputs fog data from the vertex shader.// UNITY_APPLY_FOG(fogData,col) Applies fog to color "col". Automatically applies black fog when in forward-additive pass.// Can also use UNITY_APPLY_FOG_COLOR to supply your own fog color.// In case someone by accident tries to compile fog code in one of the g-buffer or shadow passes:// treat it as fog is off.#if defined(UNITY_PASS_PREPASSBASE) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_SHADOWCASTER)#undef FOG_LINEAR#undef FOG_EXP#undef FOG_EXP2#endif#if defined(UNITY_REVERSED_Z) //D3d with reversed Z => z clip range is [near, 0] -> remapping to [0, far] //max is required to protect ourselves from near plane not being correct/meaningfull in case of oblique matrices. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0)#elif UNITY_UV_STARTS_AT_TOP //D3d without reversed z => z clip range is [0, far] -> nothing to do #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)#else //Opengl => z clip range is [-near, far] -> should remap in theory but dont do it in practice to save some perf (range is close enought) #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)#endif#if defined(FOG_LINEAR) // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start)) #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = (coord) * unity_FogParams.z + unity_FogParams.w#elif defined(FOG_EXP) // factor = exp(-density*z) #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.y * (coord); unityFogFactor = exp2(-unityFogFactor)#elif defined(FOG_EXP2) // factor = exp(-(density*z)^2) #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.x * (coord); unityFogFactor = exp2(-unityFogFactor*unityFogFactor)#else #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = 0.0#endif#define UNITY_CALC_FOG_FACTOR(coord) UNITY_CALC_FOG_FACTOR_RAW(UNITY_Z_0_FAR_FROM_CLIPSPACE(coord))#define UNITY_FOG_COORDS_PACKED(idx, vectype) vectype fogCoord : TEXCOORD##idx;#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2) #define UNITY_FOG_COORDS(idx) UNITY_FOG_COORDS_PACKED(idx, float1) #if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE) // mobile or SM2.0: calculate fog factor per-vertex #define UNITY_TRANSFER_FOG(o,outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.fogCoord.x = unityFogFactor #else // SM3.0 and PC/console: calculate fog distance per-vertex, and fog factor per-pixel #define UNITY_TRANSFER_FOG(o,outpos) o.fogCoord.x = (outpos).z #endif#else #define UNITY_FOG_COORDS(idx) #define UNITY_TRANSFER_FOG(o,outpos)#endif#define UNITY_FOG_LERP_COLOR(col,fogCol,fogFac) col.rgb = lerp((fogCol).rgb, (col).rgb, saturate(fogFac))#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2) #if (SHADER_TARGET < 30) || defined(SHADER_API_MOBILE) // mobile or SM2.0: fog factor was already calculated per-vertex, so just lerp the color #define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_FOG_LERP_COLOR(col,fogCol,(coord).x) #else // SM3.0 and PC/console: calculate fog factor and lerp fog color #define UNITY_APPLY_FOG_COLOR(coord,col,fogCol) UNITY_CALC_FOG_FACTOR((coord).x); UNITY_FOG_LERP_COLOR(col,fogCol,unityFogFactor) #endif#else #define UNITY_APPLY_FOG_COLOR(coord,col,fogCol)#endif#ifdef UNITY_PASS_FORWARDADD #define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,fixed4(0,0,0,0))#else #define UNITY_APPLY_FOG(coord,col) UNITY_APPLY_FOG_COLOR(coord,col,unity_FogColor)#endif// ------------------------------------------------------------------// LOD cross fade helpers#ifdef LOD_FADE_CROSSFADE #define UNITY_DITHER_CROSSFADE_COORDS half3 ditherScreenPos; #define UNITY_DITHER_CROSSFADE_COORDS_IDX(idx) half3 ditherScreenPos : TEXCOORD##idx; #define UNITY_TRANSFER_DITHER_CROSSFADE(o,v) o.ditherScreenPos = ComputeDitherScreenPos(UnityObjectToClipPos(v)); #define UNITY_TRANSFER_DITHER_CROSSFADE_HPOS(o,hpos) o.ditherScreenPos = ComputeDitherScreenPos(hpos); half3 ComputeDitherScreenPos(float4 hPos) { half3 screenPos = ComputeScreenPos(hPos).xyw; screenPos.xy *= _ScreenParams.xy * 0.25; return screenPos; } #define UNITY_APPLY_DITHER_CROSSFADE(i) ApplyDitherCrossFade(i.ditherScreenPos); sampler2D _DitherMaskLOD2D; void ApplyDitherCrossFade(half3 ditherScreenPos) { half2 projUV = ditherScreenPos.xy / ditherScreenPos.z; projUV.y = frac(projUV.y) * 0.0625 /* 1/16 */ + unity_LODFade.y; // quantized lod fade by 16 levels clip(tex2D(_DitherMaskLOD2D, projUV).a - 0.5); }#else #define UNITY_DITHER_CROSSFADE_COORDS #define UNITY_DITHER_CROSSFADE_COORDS_IDX(idx) #define UNITY_TRANSFER_DITHER_CROSSFADE(o,v) #define UNITY_TRANSFER_DITHER_CROSSFADE_HPOS(o,hpos) #define UNITY_APPLY_DITHER_CROSSFADE(i)#endif// ------------------------------------------------------------------// Deprecated things: these aren't used; kept here// just so that various existing shaders still compile, more or less.// Note: deprecated shadow collector pass helpers#ifdef SHADOW_COLLECTOR_PASS#if !defined(SHADOWMAPSAMPLER_DEFINED)UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture);#endif// Note: V2F_SHADOW_COLLECTOR and TRANSFER_SHADOW_COLLECTOR are deprecated#define V2F_SHADOW_COLLECTOR float4 pos : SV_POSITION; float3 _ShadowCoord0 : TEXCOORD0; float3 _ShadowCoord1 : TEXCOORD1; float3 _ShadowCoord2 : TEXCOORD2; float3 _ShadowCoord3 : TEXCOORD3; float4 _WorldPosViewZ : TEXCOORD4#define TRANSFER_SHADOW_COLLECTOR(o) \ o.pos = UnityObjectToClipPos(v.vertex); \ float4 wpos = mul(unity_ObjectToWorld, v.vertex); \ o._WorldPosViewZ.xyz = wpos; \ o._WorldPosViewZ.w = -UnityObjectToViewPos(v.vertex).z; \ o._ShadowCoord0 = mul(unity_WorldToShadow[0], wpos).xyz; \ o._ShadowCoord1 = mul(unity_WorldToShadow[1], wpos).xyz; \ o._ShadowCoord2 = mul(unity_WorldToShadow[2], wpos).xyz; \ o._ShadowCoord3 = mul(unity_WorldToShadow[3], wpos).xyz;// Note: SAMPLE_SHADOW_COLLECTOR_SHADOW is deprecated#define SAMPLE_SHADOW_COLLECTOR_SHADOW(coord) \ half shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTexture,coord); \ shadow = _LightShadowData.r + shadow * (1-_LightShadowData.r);// Note: COMPUTE_SHADOW_COLLECTOR_SHADOW is deprecated#define COMPUTE_SHADOW_COLLECTOR_SHADOW(i, weights, shadowFade) \ float4 coord = float4(i._ShadowCoord0 * weights[0] + i._ShadowCoord1 * weights[1] + i._ShadowCoord2 * weights[2] + i._ShadowCoord3 * weights[3], 1); \ SAMPLE_SHADOW_COLLECTOR_SHADOW(coord) \ float4 res; \ res.x = saturate(shadow + shadowFade); \ res.y = 1.0; \ res.zw = EncodeFloatRG (1 - i._WorldPosViewZ.w * _ProjectionParams.w); \ return res;// Note: deprecated#if defined (SHADOWS_SPLIT_SPHERES)#define SHADOW_COLLECTOR_FRAGMENT(i) \ float3 fromCenter0 = i._WorldPosViewZ.xyz - unity_ShadowSplitSpheres[0].xyz; \ float3 fromCenter1 = i._WorldPosViewZ.xyz - unity_ShadowSplitSpheres[1].xyz; \ float3 fromCenter2 = i._WorldPosViewZ.xyz - unity_ShadowSplitSpheres[2].xyz; \ float3 fromCenter3 = i._WorldPosViewZ.xyz - unity_ShadowSplitSpheres[3].xyz; \ float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3)); \ float4 cascadeWeights = float4(distances2 < unity_ShadowSplitSqRadii); \ cascadeWeights.yzw = saturate(cascadeWeights.yzw - cascadeWeights.xyz); \ float sphereDist = distance(i._WorldPosViewZ.xyz, unity_ShadowFadeCenterAndType.xyz); \ float shadowFade = saturate(sphereDist * _LightShadowData.z + _LightShadowData.w); \ COMPUTE_SHADOW_COLLECTOR_SHADOW(i, cascadeWeights, shadowFade)#else#define SHADOW_COLLECTOR_FRAGMENT(i) \ float4 viewZ = i._WorldPosViewZ.w; \ float4 zNear = float4( viewZ >= _LightSplitsNear ); \ float4 zFar = float4( viewZ < _LightSplitsFar ); \ float4 cascadeWeights = zNear * zFar; \ float shadowFade = saturate(i._WorldPosViewZ.w * _LightShadowData.z + _LightShadowData.w); \ COMPUTE_SHADOW_COLLECTOR_SHADOW(i, cascadeWeights, shadowFade)#endif#endif // #ifdef SHADOW_COLLECTOR_PASS// Legacy; used to do something on platforms that had to emulate depth textures manually. Now all platforms have native depth textures.#define UNITY_TRANSFER_DEPTH(oo)// Legacy; used to do something on platforms that had to emulate depth textures manually. Now all platforms have native depth textures.#define UNITY_OUTPUT_DEPTH(i) return 0#endif // UNITY_CG_INCLUDED
我们看到了很多的代码,有结构体和各种方法比如appdata_full 结构体,我们为啥可以在我们的shader脚本直接引用这个结构体,就是引用了这个外部库,所以可见我们可以书写自己的cginc外部库文件,然后直接引用,和c++调用库的方式一样。
- Shader学习基础之六UsePass和#include
- Shader 使用UsePass
- Shader之学习笔记六
- unity shader学习笔记(六)——Unity中的基础纹理之渐变纹理
- [Unity3D]Shader学习笔记之ShaderLab基础
- Shader学习基础之七双面材质
- shader学习之基础纹理透明效果
- Shader学习基础之二数学基础(向量和矩阵)
- Unity3D Shader官方教程翻译(十五)----Shader语法 UsePass
- Unity3D Shader官方教程翻译(十五)----Shader语法 UsePass
- Unity3D Shader官方教程翻译(十五)----Shader语法 UsePass
- Unity3D Shader官方教程翻译(十五)----Shader语法 UsePass
- Unity3D Shader官方教程翻译(十五)----Shader语法 UsePass
- Shader学习基础之三(CG语言基础)
- shader基础之练习题
- Shader山下(二十三)GrabPass与UsePass
- php学习笔记之require()和include()
- PHP学习笔记之include和require
- [JAVAWEB]10.JSP中的JavaBean和动作元素(三)
- ACM 1392 Surround the Trees
- 程序员必须掌握的8大排序算法(一):直接插入排序
- (百度百科)CSS盒子模型
- 572. Subtree of Another Tree
- Shader学习基础之六UsePass和#include
- HDU 4283 You Are the One(区间DP)
- oracle按章报错
- 一张图搞懂android事件分发机制
- http1.0 和 http1.1区别?
- 关于mysql中使用枚举类型还是int类型存取有限个固定值
- java大数算法完成五则运算之加减
- spark-streaming 读取kafka的方式
- 51Nod-1085-背包问题