// Code for textured rectangular light ps_2_0 ; ; Inputs ; dcl_2d s0 ; xyz in light space dcl_2d s1 ; "4D" coverage texture dcl t0.xyzw ; screenspace x,y dcl t1.xyz ; EDGE0 in light space dcl t2.xyz ; EDGE1 in light space #define vEDGE0 t1 #define vEDGE1 t2 ; ; Constants ; ; c0-c2 = 3x4 light transform ; c3 = 1/light_extent_x, 0, 1/light_extent_y, 0 ; Constants for munging co-oridiantes for "4D" lookup texture. ; N = the size the edge positions are quantized to. def c4, 16.0, 16.0, 0.015625, 0.015625 ; N/2, N/2, 1/(2*N), 1/(2*N) def c5, 31.0, 31.0, 0.03076171875, 0.03076171875 ; N-1, N-1, 1/N-1/(2*N*N), 1/N-1/(2*N*N) def c6, 0.0, 0.0, 0.00048828125, 0.00048828125 ; 0, 0, 1/(2*N*N), 1/(2*N*N) def c7, 0.03125, 0.0, 0.0, 0.0 ; 1/N def c8, 1.0, 1.0, 0.0, 0.0 #define ZERO c8.z #define vLIGHT_XFORM0 c0 #define vLIGHT_XFORM1 c1 #define vLIGHT_XFORM2 c2 #define ONE_OVER_EXTENT_X c3.x #define ONE_OVER_EXTENT_Y c3.z #define vSCALE1 c4 #define vOFFSET1 c4 #define vMAXCOORD c5 #define vMINCOORD c6 #define SCALE2 c7.x ; Sample postion in world space texldp r11, t0, s0 ; Transform position into light co-ordinates dp4 r0.x, r11, vLIGHT_XFORM0 dp4 r0.y, r11, vLIGHT_XFORM1 dp4 r0.z, r11, vLIGHT_XFORM2 ; Build projection matrix ; -p.z/hx, 0, p.x/hx, 0 ; 0, -p.z/hy, p.y/hy, 0 mul r3.xy, -r0.zxyw, c3.xyzw ; [1/hx, 0] mul r3.z, r0.yzxw, c3.x ; 1/hx mul r4.xy, -r0.yzxw, c3.yzxw ; [0, 1/hy] mul r4.z, r0.zxyw, c3.z ; 1/hy ; Transform edge add r9.xyz, vEDGE0, -r0 ; offset by point add r10.xyz, vEDGE1, -r0 dp3 r9.x, r9, r3 dp3 r9.y, r9, r4 ; r9.x is not used dp3 r10.x, r10, r3 dp3 r10.y, r10, r4 ; r10.x is not used ; Homogenous clipping to each edge (36 instructions) add r1.w, r9.x, r9.z ; w1 + x1 add r2.w, r10.x, r10.z ; w2 + x2 sub r3.w, r1.w, r2.w ; d1-d2 rcp r3.w, r3.w ; 1/(d1-d2) mul r3.w, r1.w, r3.w ; t = d1/(d1-d2) sub r4.xyz, r10, r9 ; E1-E0 mad r5.xyz, r3.w, r4, r9 ; I = E0 + t*(E1-E0) cmp r9.xyz, r1.w, r9, r5 ; clipped edge in r9,r10 cmp r10.xyz, r2.w, r10, r5 add r1.w, -r9.x, r9.z ; w1 - x1 add r2.w, -r10.x, r10.z ; w2 - x2 sub r3.w, r1.w, r2.w rcp r3.w, r3.w mul r3.w, r1.w, r3.w sub r4.xyz, r10, r9 mad r5.xyz, r3.w, r4, r9 cmp r9.xyz, r1.w, r9, r5 cmp r10.xyz, r2.w, r10, r5 add r1.w, r9.y, r9.z ; w1 + y1 add r2.w, r10.y, r10.z ; w2 + y2 sub r3.w, r1.w, r2.w rcp r3.w, r3.w mul r3.w, r1.w, r3.w sub r4.xyz, r10, r9 mad r5.xyz, r3.w, r4, r9 cmp r9.xyz, r1.w, r9, r5 cmp r10.xyz, r2.w, r10, r5 add r1.w, -r9.y, r9.z ; w1 - y1 add r2.w, -r10.y, r10.z ; w2 - y2 sub r3.w, r1.w, r2.w rcp r3.w, r3.w mul r3.w, r1.w, r3.w sub r4.xyz, r10, r9 mad r5.xyz, r3.w, r4, r9 cmp r9.xyz, r1.w, r9, r5 cmp r10.xyz, r2.w, r10, r5 ; Project onto light source plane rcp r9.w, r9.z mul r0.xy, r9, r9.w rcp r10.w, r10.z mul r0.zw, r10.wzyx, r10.w ; x1 y1 y2 x2 ; Compute coverage texture co-ordinates mad r0, r0, vSCALE1, vOFFSET1 ; 0..32, 0..32, 0..1/32, 0..1/32 frc r2.xy, r0 add r0.xy, r0, -r2 ; floor(x1) floor(y1) min r0, r0, vMAXCOORD ; 31, 31, 1/32-1/2048, 1/32-1/2048 max r0, r0, vMINCOORD ; 0, 0, 1/2048, 1/2048 mad r0, r0, SCALE2, r0.wzyx ; x1/32 + x2, y1/32 + y2 texld r0, r0, s1 ; Sample coverage texture cmp r1, c9.x, r0.wzyx, r0 ; Add or subtract mov oC0, r0