// CRC32: 05F7E52C | Matched 65 variants of 2 shaders: Hidden/Internal-DeferredShading, Hidden/Internal-PrePassLighting
// 
//          Unity headers extracted from Internal-DeferredShading.shader
//          Shader "Hidden/Internal-DeferredShading" {
//            Properties {
//             _LightTexture0 ("", any) = "" { }
//             _LightTextureB0 ("", 2D) = "" { }
//             _ShadowMapTexture ("", any) = "" { }
//             _SrcBlend ("", Float) = 1
//             _DstBlend ("", Float) = 1
//            }
//            Fallback Off
//            SubShader 1/1 {
//              Pass 1/2 {
//                Tags { "SHADOWSUPPORT"="true" }
//                ZWrite Off
//                Blend [_SrcBlend] [_DstBlend]
//                GpuProgramID 36028
//                Program "vp" {
//                  SubProgram "d3d9 " {
// 0004000:           Keywords { "DIRECTIONAL" "SHADOWS_OFF" "UNITY_HDR_ON" }
// 0000002:           Keywords { "DIRECTIONAL" "SHADOWS_OFF" }
// 0080000:           Keywords { "DIRECTIONAL" "SHADOWS_SCREEN" "UNITY_HDR_ON" }
// 0000040:           Keywords { "DIRECTIONAL" "SHADOWS_SCREEN" }
// 0020000:           Keywords { "DIRECTIONAL_COOKIE" "SHADOWS_OFF" "UNITY_HDR_ON" }
// 0000010:           Keywords { "DIRECTIONAL_COOKIE" "SHADOWS_OFF" }
// 0100000:           Keywords { "DIRECTIONAL_COOKIE" "SHADOWS_SCREEN" "UNITY_HDR_ON" }
// 0000080:           Keywords { "DIRECTIONAL_COOKIE" "SHADOWS_SCREEN" }
// 1000000:           Keywords { "POINT" "SHADOWS_CUBE" "SHADOWS_SOFT" "UNITY_HDR_ON" }
// 0000800:           Keywords { "POINT" "SHADOWS_CUBE" "SHADOWS_SOFT" }
// 0200000:           Keywords { "POINT" "SHADOWS_CUBE" "UNITY_HDR_ON" }
// 0000100:           Keywords { "POINT" "SHADOWS_CUBE" }
// 0002000:           Keywords { "POINT" "SHADOWS_OFF" "UNITY_HDR_ON" }
// 0000001:           Keywords { "POINT" "SHADOWS_OFF" }
// 2000000:           Keywords { "POINT_COOKIE" "SHADOWS_CUBE" "SHADOWS_SOFT" "UNITY_HDR_ON" }
// 0001000:           Keywords { "POINT_COOKIE" "SHADOWS_CUBE" "SHADOWS_SOFT" }
// 0400000:           Keywords { "POINT_COOKIE" "SHADOWS_CUBE" "UNITY_HDR_ON" }
// 0000200:           Keywords { "POINT_COOKIE" "SHADOWS_CUBE" }
// 0010000:           Keywords { "POINT_COOKIE" "SHADOWS_OFF" "UNITY_HDR_ON" }
// 0000008:           Keywords { "POINT_COOKIE" "SHADOWS_OFF" }
// 0800000:           Keywords { "SHADOWS_DEPTH" "SHADOWS_NATIVE" "SHADOWS_SOFT" "SPOT" "UNITY_HDR_ON" }
// 0000400:           Keywords { "SHADOWS_DEPTH" "SHADOWS_NATIVE" "SHADOWS_SOFT" "SPOT" }
// 0040000:           Keywords { "SHADOWS_DEPTH" "SHADOWS_NATIVE" "SPOT" "UNITY_HDR_ON" }
// 0000020:           Keywords { "SHADOWS_DEPTH" "SHADOWS_NATIVE" "SPOT" }
// 0008000:           Keywords { "SHADOWS_OFF" "SPOT" "UNITY_HDR_ON" }
// 0000004:           Keywords { "SHADOWS_OFF" "SPOT" }
//                    Bind "vertex" Vertex
//                    Bind "normal" Normal
//                    Matrix 4 [glstate_matrix_modelview0] 3
//                    Matrix 0 [glstate_matrix_mvp]
//                    Float 9 [_LightAsQuad]
//                    Vector 7 [_ProjectionParams]
//                    Vector 8 [_ScreenParams]
//                  }
//                }
//              }
//            }
//          }
// 
//             Unity headers extracted from Internal-PrePassLighting.shader
//             Shader "Hidden/Internal-PrePassLighting" {
//               Properties {
//                _LightTexture0 ("", any) = "" { }
//                _LightTextureB0 ("", 2D) = "" { }
//                _ShadowMapTexture ("", any) = "" { }
//               }
//               Fallback Off
//               SubShader 1/1 {
// 0000001fff:     Pass 1/3 {
// 0003ffe000:     Pass 2/3 {
// 7ffc000000:     Pass 3/3 {
//                   Tags { "SHADOWSUPPORT"="true" }
//                   ZWrite Off
// 0000001fff:       Blend DstColor Zero
// 7fffffe000:       Blend One One
// 0003ffe000:       GpuProgramID 113408
// 7ffc000000:       GpuProgramID 155461
// 0000001fff:       GpuProgramID 57115
//                   Program "vp" {
//                     SubProgram "d3d9 " {
// 0008004002:           Keywords { "DIRECTIONAL" "SHADOWS_OFF" }
// 0100080040:           Keywords { "DIRECTIONAL" "SHADOWS_SCREEN" }
// 0040020010:           Keywords { "DIRECTIONAL_COOKIE" "SHADOWS_OFF" }
// 0200100080:           Keywords { "DIRECTIONAL_COOKIE" "SHADOWS_SCREEN" }
// 2001000800:           Keywords { "POINT" "SHADOWS_CUBE" "SHADOWS_SOFT" }
// 0400200100:           Keywords { "POINT" "SHADOWS_CUBE" }
// 0004002001:           Keywords { "POINT" "SHADOWS_OFF" }
// 4002001000:           Keywords { "POINT_COOKIE" "SHADOWS_CUBE" "SHADOWS_SOFT" }
// 0800400200:           Keywords { "POINT_COOKIE" "SHADOWS_CUBE" }
// 0020010008:           Keywords { "POINT_COOKIE" "SHADOWS_OFF" }
// 1000800400:           Keywords { "SHADOWS_DEPTH" "SHADOWS_NATIVE" "SHADOWS_SOFT" "SPOT" }
// 0080040020:           Keywords { "SHADOWS_DEPTH" "SHADOWS_NATIVE" "SPOT" }
// 0010008004:           Keywords { "SHADOWS_OFF" "SPOT" }
//                       Bind "vertex" Vertex
//                       Bind "normal" Normal
//                       Matrix 4 [glstate_matrix_modelview0] 3
//                       Matrix 0 [glstate_matrix_mvp]
//                       Float 9 [_LightAsQuad]
//                       Vector 7 [_ProjectionParams]
//                       Vector 8 [_ScreenParams]
//                     }
//                   }
//                 }
//               }
//             }
// 
// Headers extracted with DarkStarSword's extract_unity_shaders.py
// https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/extract_unity_shaders.py

    vs_3_0
    def c10, 0.5, -1, 1, 0
    dcl_position v0
    dcl_normal v1
    dcl_position o0
    dcl_texcoord o1
    dcl_texcoord1 o2.xyz

// Extra output to pass the FOV to pixel shaders:
dcl_texcoord5 o5.x

def c220, 0, 1, 0.0625, 1
dcl_2d s0

    // Rearranged to simplify shader:
    dp4 r0.x, c0, v0
    dp4 r0.y, c1, v0
    dp4 r0.z, c2, v0
    dp4 r0.w, c3, v0
    mov o0, r0 // moved up before the stereo correction

// Determine if drawing a full screen quad by testing if output position w == 1.
// Seems to be more reliable than an input position test:
if_eq r0.w, c220.y
	mov r23.x, c220.y // Set flag to indicate we are drawing a full-screen quad

	// Our projection matrix will not be valid, so we use the matrices
	// copied from a different shader:
	mov r25, c180 // MV[0]
	mov r26, c181 // MV[1]
	mov r27, c182 // MV[2]
	mov r28, c190 // MVP[0]
else
	mov r23.x, c220.x // Clear flag to indicate we are drawing a light in the scene

	// Our projection matrix will be valid, so we can use the matrices
	// passed into this shader:
	mov r25, c4 // MV[0]
	mov r26, c5 // MV[1]
	mov r27, c6 // MV[2]
	mov r28, c0 // MVP[0]
endif

mov r24, c200
if_eq r24.w, c220.y
	// Use inverse projection matrix is valid, so use it directly:
	mov r30.x, c170.x
else
	// We can't use Helix mod to invert the MV matrix since we are either
	// using the matrix passed directily into this shader, or a 3x4 matrix
	// copied from a different shader (Helix mod expects a 4x4 matrix).
	// So let's do it directly in assembly instead! It sounds complicated,
	// but we can make some large simplifications based on assumptions
	// about the MV and MVP matrices and the fact we only need one cell of
	// the (inverse) projection matrix, which means it is actually possible
	// to do in a farily small number of instructions :)

	// 1. Calculate 1/determinant of the MV matrix, simplifying by assuming the
	//    4th column of the MV matrix is 0,0,0,1
	//
	// mathomatic simplified it to:
	// 1 / ((m12*((m20*m01) - (m21*m00))) + (m02*((m21*m10) - (m20*m11))) + (m22*((m00*m11) - (m01*m10))));
	//
	// Replace row numbers with register components (assumes column-major order):
	//   (mv2.x*((mv0.y*mv1.z) - (mv0.z*mv1.y)))
	// + (mv2.y*((mv0.z*mv1.x) - (mv0.x*mv1.z)))
	// + (mv2.z*((mv0.x*mv1.y) - (mv0.y*mv1.x)))

	// Do some multiplications in parallel with SIMD instructions:
	mul r20.xyz, r25.yzx, r26.zxy	// mv0.y*mv1.z, mv0.z*mv1.x, mv0.x*mv1.y
	mul r21.xyz, r25.zxy, r26.yzx	// mv0.z*mv1.y, mv0.x*mv1.z, mv0.y*mv1.x
	// Do the subtractions:
	add r20.xyz, r20.xyz, -r21.xyz	// mv0.y*mv1.z - mv0.z*mv1.y, mv0.z*mv1.x - mv0.x*mv1.z, mv0.x*mv1.y - mv0.y*mv1.x
	// Now the multiplications:
	mul r20.xyz, r20.xyz, r27.xyz
	// Sum it together to get the determinant:
	add r22.w, r20.x, r20.y
	add r22.w, r22.w, r20.z
	if_eq r22.w, c220.x
		mov r30.x, c220.w // One of the inputs was zero, use a hardcoded FOV
	else
		// And finally get 1/determinant:
		rcp r22.w, r22.w

		// 2. Calculate the 1st row of the inverted MV matrix, simplifying by assuimg
		//    the 4th column of the MV matrix is 0,0,0,1
		//
		// m00 = (mv1.y*mv2.z - mv1.z*mv2.y) / determinant
		// m01 = (mv1.z*mv2.x - mv1.x*mv2.z) / determinant
		// m02 = (mv1.x*mv2.y - mv1.y*mv2.x) / determinant

		// Do some multiplications in parallel with SIMD instructions:
		mul r20.xyz, r26.yzx, r27.zxy	// mv1.y*mv2.z, mv1.z*mv2.x, mv1.x*mv2.y
		mul r21.xyz, r26.zxy, r27.yzx	// mv1.z*mv2.y, mv1.x*mv2.z, mv1.y*mv2.x
		// Do the subtractions:
		add r20.xyz, r20.xyz, -r21.xyz	// mv1.y*mv2.z - mv1.z*mv2.y, mv1.z*mv2.x - mv1.x*mv2.z, mv1.x*mv2.y - mv1.y*mv2.x
		// Multiply against 1/determinant:
		mul r20.xyz, r20.xyz, r22.www

		// 3. Multiply the first row of the inverted MV matrix with the 1st column of
		//    the MVP matrix (MV.I[0,3] is 0, so only worry about the 1st three):
		dp3 r30.x, r20.xyz, r28.xyz

		if_eq r30.x, c220.x
			mov r30.x, c220.w // One of the inputs was zero, use a hardcoded FOV
		else
			rcp r30.x, r30.x // Calculate P.I[0,0]
		endif
	endif
endif

mov o5.x, r30.x // Copy P.I[0,0] to pixel shaders

if_eq r23.x, c220.x
	// Apply stereo correction to screen coords stored in texcoord:
	texldl r31, c220.z, s0
	add r31.w, r0.w, -r31.y
	mul r31.w, r31.w, r31.x
	add r0.x, r0.x, r31.w
endif

    mul r1.x, r0.y, c7.x
    mul r1.w, r1.x, c10.x
    mul r1.xz, r0.xyww, c10.x
    mad o1.xy, r1.z, c8.zwzw, r1.xwzw
    dp4 r1.x, c4, v0
    dp4 r1.y, c5, v0
    dp4 r1.z, c6, v0

if_eq r23.x, c220.x
	// Apply view-space stereo correction to ray:
	mad r1.x, r31.w, r30.x, r1.x
endif

    mul r2.xyz, r1, c10.yyzw
    mad r1.xyz, r1, -c10.yyzw, v1
    mad o2.xyz, c9.x, r1, r2
    mov o1.zw, r0
