// 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

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

// Apply texcoord correction only when not drawing a full screen quad:
if_ne r0.w, c220.y
	// 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

// Apply view-space ray correction only when not drawing a full screen quad:
if_ne r0.w, c220.y

	// This technique has changed a little starting with the Unity 5 update
	// of Dreamfall Chapters. The old technique still works just fine, but
	// I wanted to adjust _WorldSpaceCameraPos in a number of shaders and
	// my quest to find a way to solve both problems reliably (by script)
	// led me to find a way to fix the lighting shaders using world-space
	// coordinates instead of view-space coordinates - that way, I could
	// keep the number of matrices I needed to copy with Helix Mod down to
	// 2 (the limit).
	//
	// This is the one part of the lighting fix that still needs a
	// view-space correction, but fortunately we only need to do this when
	// the shader has valid MV and MVP matrices so we can still derive the
	// inverse projection matrix to get the FOV like usual.

	// We can't use Helix mod to invert the MV matrix since we are already
	// using both matrix copy slots for the inverse MVP and _Object2World
	// matrices, and the MV matrix in Unity 5 is only a 3x4 matrix, while
	// 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 :)

	// Use a temporary register for MV[1] to get around the fact that some
	// of the below instructions need to read from more constant registers
	// than there are available read ports:
	mov r26, c5

	// 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, c4.yzx, r26.zxy	// mv0.y*mv1.z, mv0.z*mv1.x, mv0.x*mv1.y
	mul r21.xyz, c4.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 final three multiplications and the two additions:
	dp3 r22.w, r20.xyz, c6.xyz
	// 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, c6.zxy	// mv1.y*mv2.z, mv1.z*mv2.x, mv1.x*mv2.y
	mul r21.xyz, r26.zxy, c6.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, c0.xyz

	rcp r30.x, r30.x // Calculate P.I[0,0]

	// 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
