Math::ViewMatrix( vec3( 0.0f, 0.0f, 1.0f ), vec3( 0.0f, 1.0f, 0.0f ), vec3( -1.0f, 0.0f, 0.0f ), P ); Math::ViewMatrix( vec3( 0.0f, 0.0f, -1.0f ), vec3( 0.0f, 1.0f, 0.0f ), vec3( 1.0f, 0.0f, 0.0f ), P ); Math::ViewMatrix( vec3( 1.0f, 0.0f, 0.0f ), vec3( 0.0f, 0.0f, 1.0f ), vec3( 0.0f, -1.0f, 0.0f ), P ); Math::ViewMatrix( vec3( 1.0f, 0.0f, 0.0f ), vec3( 0.0f, 0.0f, -1.0f ), vec3( 0.0f, 1.0f, 0.0f ), P ); Math::ViewMatrix( vec3( -1.0f, 0.0f, 0.0f ), vec3( 0.0f, 1.0f, 0.0f ), vec3( 0.0f, 0.0f, -1.0f ), P ); Math::ViewMatrix( vec3( 1.0f, 0.0f, 0.0f ), vec3( 0.0f, 1.0f, 0.0f ), vec3( 0.0f, 0.0f, 1.0f ), P ); LMatrix4 ViewMatrix( const LVector3& X, const LVector3& Y, const LVector3& Z, const LVector3& Position ) { LMatrix4 Matrix; Matrix[0][0] = Xx; Matrix[1][0] = Xy; Matrix[2][0] = Xz; Matrix[3][0] = -X.Dot( Position ); Matrix[0][1] = Yx; Matrix[1][1] = Yy; Matrix[2][1] = Yz; Matrix[3][1] = -Y.Dot( Position ); Matrix[0][2] = Zx; Matrix[1][2] = Zy; Matrix[2][2] = Zz; Matrix[3][2] = -Z.Dot( Position ); Matrix[0][3] = 0.0f; Matrix[1][3] = 0.0f; Matrix[2][3] = 0.0f; Matrix[3][3] = 1.0f; return Matrix; }
float NearCP = 0.5f; float FarCP = 512.0f; Math::Perspective( 90.0f, 1.0f, NearCP, FarCP );
void main() { float D = distance( v_WorldPosition, u_LightPosition.xyz ); out_FragColor = Pack( D / 512.0 ); } vec4 Pack(float Value) { const vec4 BitSh = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0); const vec4 BitMsk = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 ); vec4 Comp = fract( Value * BitSh ); Comp -= Comp.xxyz * BitMsk; return Comp; }
LRectDivider( int Size, int NumSubRects ) : FSize( Size ) , FNumSubRects( NumSubRects ) , FCurrentX( 0 ) , FCurrentY( 0 ) { float Sqrt = sqrt( float( FNumSubRects ) ); FNumSlotsWidth = ( int )ceil( Sqrt ); FNumSlotsHeight = ( int )Sqrt; FSlotWidth = FSize / FNumSlotsWidth; FSlotHeight = FSize / FNumSlotsHeight; } void GetNextRect( int* X, int* Y, int* W, int* H ) { if ( X ) { *X = FCurrentX * FSlotWidth; } if ( Y ) { *Y = FCurrentY * FSlotHeight; } if ( W ) { *W = FSlotWidth; } if ( H ) { *H = FSlotHeight; } NextRect(); } private: void NextRect() { if ( ++FCurrentX >= FNumSlotsWidth ) { FCurrentX = 0; FCurrentY++; } }
Major Axis Direction | Target | Sc | Tc | Ma |
+ Rx | POSITIVE_X | -Rz | -Ry | Rx |
-Rx | NEGATIVE_X | Rz | -Ry | Rx |
+ Ry | POSITIVE_Y | Rx | Rz | Ry |
-Ry | NEGATIVE_Y | Rx | -Rz | Ry |
+ Rz | POSITIVE_Z | Rx | -Ry | Rz |
-Rz | NEGATIVE_Z | -Rx | -Ry | Rz |
s = 0.5 * ( Sc / abs(Ma) + 1 ) t = 0.5 * ( Tc / abs(Ma) + 1 )
vec2 GetShadowTC( vec3 Dir ) { float Sc; float Tc; float Ma; float FaceIndex; float rx = Dir.x; float ry = Dir.y; float rz = Dir.z; vec3 adir = abs(Dir); Ma = max( max( adir.x, adir.y ), adir.z ); if ( adir.x > adir.y && adir.x > adir.z ) { Sc = ( rx > 0.0 ) ? rz : -rz; Tc = ry; FaceIndex = ( rx > 0.0 ) ? 0.0 : 1.0; } else if ( adir.y > adir.x && adir.y > adir.z ) { Sc = rx; Tc = ( ry > 0.0 ) ? rz : -rz; FaceIndex = ( ry > 0.0 ) ? 2.0 : 3.0; } else { Sc = ( rz > 0.0 ) ? -rx : rx; Tc = ry; FaceIndex = ( rz > 0.0 ) ? 4.0 : 5.0; } float s = 0.5 * ( Sc / Ma + 1.0 ); float t = 0.5 * ( Tc / Ma + 1.0 ); // s = s / 3.0; t = t / 2.0; float Flr = floor(FaceIndex / 3.0); float Rmd = FaceIndex - (3.0 * Flr); s += Rmd / 3.0; t += Flr / 2.0; return vec2( s, t ); }
float ComputePointLightShadow() { vec3 LightDirection = v_WorldPosition - u_LightPosition.xyz; vec2 IndirectTC = GetShadowTC( normalize( LightDirection ) ); vec4 Light = texture( Texture7, IndirectTC ); float LightD = Unpack( Light ) * 512.0; if ( LightD < length( LightDirection ) + u_ShadowDepthBias ) return u_ShadowIntensity; return 1.0; } float Unpack(vec4 Value) { const vec4 BitShifts = vec4( 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0 ); return dot( Value, BitShifts ); }
Source: https://habr.com/ru/post/219327/
All Articles