Unity Standerd Shader(SRP)調査
Standard Shaderのcodeを見るには
ここに置いておく(private)
Shader本体
Foward Base
code: foward
Pass
{
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
// -------------------------------------
#pragma shader_feature_local _NORMALMAP #pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature_fragment _EMISSION #pragma shader_feature_local _METALLICGLOSSMAP #pragma shader_feature_local_fragment _DETAIL_MULX2 #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF #pragma shader_feature_local_fragment _GLOSSYREFLECTIONS_OFF #pragma shader_feature_local _PARALLAXMAP // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#include "UnityStandardCoreForward.cginc" ENDCG
}
Foward Add
code: forward add
Pass
{
Name "FORWARD_DELTA"
Tags { "LightMode" = "ForwardAdd" }
Fog
{
Color(0, 0, 0, 0)
}// in additive pass fog should be black
ZWrite Off
ZTest LEqual
CGPROGRAM
// -------------------------------------
#pragma shader_feature_local _NORMALMAP #pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature_local _METALLICGLOSSMAP #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF #pragma shader_feature_local_fragment _DETAIL_MULX2 #pragma shader_feature_local _PARALLAXMAP #pragma multi_compile_fwdadd_fullshadows // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#include "UnityStandardCoreForward.cginc" ENDCG
}
Vertex
Vertex Shader Output
FowardbaseとAddでちょっと違う
code: UnityStandardCoreForwardSimple
struct VertexOutputBaseSimple
{
UNITY_POSITION(pos);
float4 tex : TEXCOORD0;
half4 eyeVec : TEXCOORD1; // w: grazingTerm
half4 ambientOrLightmapUV : TEXCOORD2; // SH or Lightmap UV
SHADOW_COORDS(3)
UNITY_FOG_COORDS_PACKED(4, half4) // x: fogCoord, yzw: reflectVec
half4 normalWorld : TEXCOORD5; // w: fresnelTerm
half3 tangentSpaceLightDir : TEXCOORD6;
half3 tangentSpaceEyeVec : TEXCOORD7;
#if UNITY_REQUIRE_FRAG_WORLDPOS float3 posWorld : TEXCOORD8;
UNITY_VERTEX_OUTPUT_STEREO
};
code: vertexOutputForwadAdd
struct VertexOutputForwardAddSimple
{
UNITY_POSITION(pos);
float4 tex : TEXCOORD0;
float3 posWorld : TEXCOORD1;
#if !defined(_NORMALMAP) && SPECULAR_HIGHLIGHTS UNITY_FOG_COORDS_PACKED(2, half4) // x: fogCoord, yzw: reflectVec
UNITY_FOG_COORDS_PACKED(2, half1)
half3 lightDir : TEXCOORD3;
half3 tangentSpaceEyeVec : TEXCOORD4;
half3 normalWorld : TEXCOORD4;
UNITY_LIGHTING_COORDS(5, 6)
UNITY_VERTEX_OUTPUT_STEREO
};
Vertex Shader
code: VertexBase
VertexOutputBaseSimple vertForwardBaseSimple(VertexInput v)
{
UNITY_SETUP_INSTANCE_ID(v);
VertexOutputBaseSimple o;
UNITY_INITIALIZE_OUTPUT(VertexOutputBaseSimple, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
o.tex = TexCoords(v);
half3 eyeVec = normalize(posWorld.xyz - _WorldSpaceCameraPos);
half3 normalWorld = UnityObjectToWorldNormal(v.normal);
o.normalWorld.xyz = normalWorld;
o.eyeVec.xyz = eyeVec;
half3 tangentSpaceEyeVec;
TangentSpaceLightingInput(normalWorld, v.tangent, _WorldSpaceLightPos0.xyz, eyeVec, o.tangentSpaceLightDir, tangentSpaceEyeVec);
o.tangentSpaceEyeVec = tangentSpaceEyeVec;
//We need this for shadow receiving
TRANSFER_SHADOW(o);
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
o.fogCoord.yzw = reflect(eyeVec, normalWorld);
o.normalWorld.w = Pow4(1 - saturate(dot(normalWorld, -eyeVec))); // fresnel term
o.eyeVec.w = saturate(_Glossiness + UNIFORM_REFLECTIVITY()); // grazing term
UNITY_TRANSFER_FOG(o, o.pos);
return o;
}
Fogの処理
UnityCGにある
Fog用のcoordinateを決める(単にdepth)、coordinateからカラーブレンディングみたいな感じ
code: Unity.cginc
// 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 // factor = exp(-density*z)
#define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.y * (coord); unityFogFactor = exp2(-unityFogFactor) // factor = exp(-(density*z)^2)
#define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.x * (coord); unityFogFactor = exp2(-unityFogFactor * unityFogFactor) #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = 0.0 #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 #define UNITY_TRANSFER_FOG_COMBINED_WITH_TSPACE(o, outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.tSpace1.y = tangentSign; o.tSpace2.y = unityFogFactor #define UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o, outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.worldPos.w = unityFogFactor #define UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o, outpos) UNITY_CALC_FOG_FACTOR((outpos).z); o.eyeVec.w = unityFogFactor // 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 #define UNITY_TRANSFER_FOG_COMBINED_WITH_TSPACE(o, outpos) o.tSpace2.y = (outpos).z #define UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o, outpos) o.worldPos.w = (outpos).z #define UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o, outpos) o.eyeVec.w = (outpos).z #define UNITY_TRANSFER_FOG(o, outpos) #define UNITY_TRANSFER_FOG_COMBINED_WITH_TSPACE(o, outpos) #define UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o, outpos) #define UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o, outpos) #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) // 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) #define UNITY_EXTRACT_FOG(name) float _unity_fogCoord = name.fogCoord #define UNITY_EXTRACT_FOG_FROM_TSPACE(name) float _unity_fogCoord = name.tSpace2.y #define UNITY_EXTRACT_FOG_FROM_WORLD_POS(name) float _unity_fogCoord = name.worldPos.w #define UNITY_EXTRACT_FOG_FROM_EYE_VEC(name) float _unity_fogCoord = name.eyeVec.w #define UNITY_APPLY_FOG_COLOR(coord, col, fogCol) #define UNITY_EXTRACT_FOG_FROM_TSPACE(name) #define UNITY_EXTRACT_FOG_FROM_WORLD_POS(name) #define UNITY_EXTRACT_FOG_FROM_EYE_VEC(name) #define UNITY_APPLY_FOG(coord, col) UNITY_APPLY_FOG_COLOR(coord, col, fixed4(0, 0, 0, 0)) #define UNITY_APPLY_FOG(coord, col) UNITY_APPLY_FOG_COLOR(coord, col, unity_FogColor)