■ [作業履歴][unity]シャドウマップ関連のメモ
- UNITYシェーダーメモ01 シャドウマップ
- Adding shadows to custom shader (vert - frag)
- How do I sample a shadowmap in a custom shader?
- TransparentShadowReceiver
- メモ
- Shader編 その2 ShaderLabでUnityシェーダの下地作り
- 影を使ってるシェーダーのコード
自前でシャドウマップ生成
シャドウメモ
C:\Program Files (x86)\Unity\Editor\Data\CGIncludes/AutoLight.cginc
#define LIGHT_ATTENUATION(a) SHADOW_ATTENUATION(a)
#define SHADOW_ATTENUATION(a) unitySampleShadow(a._ShadowCoord)
inline fixed unitySampleShadow (float4 shadowCoord)
{
#if defined (SHADOWS_SOFT)
// 4-tap shadows
float3 coord = shadowCoord.xyz / shadowCoord.w;
#if defined (SHADOWS_NATIVE) && !defined (SHADER_API_OPENGL)
half4 shadows;
shadows.x = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, coord + _ShadowOffsets[0]);
shadows.y = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, coord + _ShadowOffsets[1]);
shadows.z = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, coord + _ShadowOffsets[2]);
shadows.w = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, coord + _ShadowOffsets[3]);
shadows = _LightShadowData.rrrr + shadows * (1-_LightShadowData.rrrr);
#else
float4 shadowVals;
shadowVals.x = UNITY_SAMPLE_DEPTH (tex2D( _ShadowMapTexture, coord + _ShadowOffsets[0].xy ));
shadowVals.y = UNITY_SAMPLE_DEPTH (tex2D( _ShadowMapTexture, coord + _ShadowOffsets[1].xy ));
shadowVals.z = UNITY_SAMPLE_DEPTH (tex2D( _ShadowMapTexture, coord + _ShadowOffsets[2].xy ));
shadowVals.w = UNITY_SAMPLE_DEPTH (tex2D( _ShadowMapTexture, coord + _ShadowOffsets[3].xy ));
half4 shadows = (shadowVals < coord.zzzz) ? _LightShadowData.rrrr : 1.0f;
#endif
// average-4 PCF
half shadow = dot (shadows, 0.25f);
#else
// 1-tap shadows
// Native sampling of depth textures is broken on Intel 10.4.8, and does not exist on PPC. So sample manually :(
#if defined (SHADOWS_NATIVE) && !defined (SHADER_API_OPENGL)
half shadow = UNITY_SAMPLE_SHADOW_PROJ(_ShadowMapTexture, shadowCoord);
shadow = _LightShadowData.r + shadow * (1-_LightShadowData.r);
#else
half shadow = UNITY_SAMPLE_DEPTH(tex2Dproj (_ShadowMapTexture, UNITY_PROJ_COORD(shadowCoord))) < (shadowCoord.z / shadowCoord.w) ? _LightShadowData.r : 1.0;
#endif
#endif
return shadow;
}
今回のハマりポイント
vertex shader内に TRANSFER_VERTEX_TO_FRAGMENT(o); のコードを含める。
(o)は出力される構造体名。
これがないと、ピクセルシェーダーでSHADOW_ATTENUATION(a) を書いても頂点シェーダー内でa._ShadowCoordが設定されない
- TRANSFER_VERTEX_TO_FRAGMENT(o) にはセミコロン不要! つけると得体のしれないエラーが出てハマる
基本的には、AutoLight.cginc でやってることをそのまま持ってきたら動く。
でも、#if defined (SHADOWS_SCREEN) が常に有効になってるみたいで、
スクリーンに落ちたものをそのまま引っ張るだけで、カスケードシャドウマップへの直アクセスができない。
カスケードシャドウマップの生成部分は見つけられてない。こっちがやりたいのに。
spotのシャドウにして、ここでカスタマイズすべきか、それとも完全に自前で描くべきか。