0013-04-01

[][]シャドウマップ関連のメモ シャドウマップ関連のメモ - Nao_uの日記 を含むブックマーク はてなブックマーク - シャドウマップ関連のメモ - Nao_uの日記 シャドウマップ関連のメモ - Nao_uの日記 のブックマークコメント


自前でシャドウマップ生成


シャドウメモ

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のシャドウにして、ここでカスタマイズすべきか、それとも完全に自前で描くべきか。