; Perform spotlight calculations #pragma screenspace xvs.1.1 ; Calculate light to geo vertex vector sub r0.xyz, r10.xyz, c[a0.x + LIGHT_POSITION].xyz ; Get magnitude of light to vertex vector for ; range attenuation and to normalize the vector mul r1.xyz, r0.xyz, r0.xyz add r2.x, r1.x, r1.y add r3.x, r2.x, r1.z rsq r5.x, r3.x ;r5.x = 1/range ; Normalize light to vertex vector mul r6.xyz, r0.xyz, r5.x ; Dot light-to-vertex vector with spotlight direction vector ; Clamp to 0 if negative dp3 r7.xyz, r6.xyz, c[a0.x + LIGHT_DIRECTION].xyz max r8.xyz, r7.xyz, ZERO.xyz ; Check dot product against spotlight angles ; alpha = dot product result ; theta = inner angle ; phi = outer angle ; cos(alpha) - cos(phi) / cos(theta) - cos(phi) sub r1.x, r8.x, c[a0.x + LIGHT_ANGLES].y sub r2.x, c[a0.x + LIGHT_ANGLES].x, c[a0.x + LIGHT_ANGLES].y rcp r3.x, r2.x mul r7.x, r1.x, r3.x ; Test result of above ratio max r1.xyz, r7.x, ZERO.x min r2.xyz, r1.xyz, ONE.xyz ; Scale light colors with dot product mul r4.xyz, c[a0.x + LIGHT_COLOR].xyz, r2.xyz ; Perform range attenuation mul r0.x, r5.x, c[a0.x + LIGHT_DIRECTION].w rcp r1.x, r0.x ;r1 = range/maxRange sub r2.x, ONE.x, r1.x max r3.xyz, r2.x, ZERO.x ;r3 = 1 - r/maxR mul r6.xyz, r4.xyz, r3.xyz ; Dot light direction vector with vertex normals dp3 r1, r9, -c[a0.x + LIGHT_DIRECTION] max r2.xyz, r1.xyz, ZERO.xyz ; Combine vertex normal light with spotlight attenuation mul r3.xyz, r2.xyz, r6.xyz mov r4.xyz, r3.xyz ; Sum in this light's contribution in running rgb ; Clamp to 1.0. add r8.xyz, r11.xyz, r4.xyz min r11.xyz, r8.xyz, ONE.xyz ; Add in alpha value. Clamp to 1.0. add r8.w, r11.w, c[a0.x + LIGHT_COLOR].w min r4.w, ONE.w, r8.w mov r11.w, r4.w ; Set a0.x to next light (if any) mov r5.x, c[a0.x + LIGHT_SIZE].w mov a0.x, r5.x