Unity Standerd Shader(SRP)調査
Standard Shaderのcodeを見るには
https://docs.unity3d.com/Manual/StandardShaderMakeYourOwn.html
ここに置いておく(private)
https://github.com/kinakomoti-321/unity_shader_research/tree/main/BuilinShader/builtin_shaders
Shader本体
Foward Base
code: foward
Pass
{
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
Blend _SrcBlend _DstBlend
ZWrite _ZWrite
CGPROGRAM
#pragma target 3.0
// -------------------------------------
#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
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
#pragma multi_compile_instancing
// 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
#pragma vertex vertBase
#pragma fragment fragBase
#include "UnityStandardCoreForward.cginc"
ENDCG
}
Foward Add
code: forward add
Pass
{
Name "FORWARD_DELTA"
Tags { "LightMode" = "ForwardAdd" }
Blend _SrcBlend One
Fog
{
Color(0, 0, 0, 0)
}// in additive pass fog should be black
ZWrite Off
ZTest LEqual
CGPROGRAM
#pragma target 3.0
// -------------------------------------
#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
#pragma multi_compile_fog
// 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
#pragma vertex vertAdd
#pragma fragment fragAdd
#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
#ifdef _NORMALMAP
half3 tangentSpaceLightDir : TEXCOORD6;
#if SPECULAR_HIGHLIGHTS
half3 tangentSpaceEyeVec : TEXCOORD7;
#endif
#endif
#if UNITY_REQUIRE_FRAG_WORLDPOS
float3 posWorld : TEXCOORD8;
#endif
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
#else
UNITY_FOG_COORDS_PACKED(2, half1)
#endif
half3 lightDir : TEXCOORD3;
#if defined(_NORMALMAP)
#if SPECULAR_HIGHLIGHTS
half3 tangentSpaceEyeVec : TEXCOORD4;
#endif
#else
half3 normalWorld : TEXCOORD4;
#endif
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;
#ifdef _NORMALMAP
half3 tangentSpaceEyeVec;
TangentSpaceLightingInput(normalWorld, v.tangent, _WorldSpaceLightPos0.xyz, eyeVec, o.tangentSpaceLightDir, tangentSpaceEyeVec);
#if SPECULAR_HIGHLIGHTS
o.tangentSpaceEyeVec = tangentSpaceEyeVec;
#endif
#endif
//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
#if !GLOSSMAP
o.eyeVec.w = saturate(_Glossiness + UNIFORM_REFLECTIVITY()); // grazing term
#endif
UNITY_TRANSFER_FOG(o, o.pos);
return o;
}
Fogの処理
UnityCGにある
Fog用のcoordinateを決める(単にdepth)、coordinateからカラーブレンディングみたいな感じ
code: Unity.cginc
#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
#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
#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
#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
#endif
#else
#define UNITY_FOG_COORDS(idx)
#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)
#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
#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
#else
#define UNITY_APPLY_FOG_COLOR(coord, col, fogCol)
#define UNITY_EXTRACT_FOG(name)
#define UNITY_EXTRACT_FOG_FROM_TSPACE(name)
#define UNITY_EXTRACT_FOG_FROM_WORLD_POS(name)
#define UNITY_EXTRACT_FOG_FROM_EYE_VEC(name)
#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