diff --git a/programs/demos/ray/dataray.inc b/programs/demos/ray/dataray.inc index c40c9ff5bf..cdbd81e0c8 100644 --- a/programs/demos/ray/dataray.inc +++ b/programs/demos/ray/dataray.inc @@ -1,47 +1,76 @@ + non_rot_light: ;light: -dd 0.9, 0.9, 1.0 +dd 0.5, 0.5, 1.9 ;light2: -dd 0.1, 0.05, 0.5 +dd 1.1, 1.05, 0.5 ;light3: -dd 0.9, 0.1, 0.3 +dd 1.9, 0.1, 3.3 +dd 0.5, 0.5, -4.0 +;light2: +dd 0.2, 0.2, -5.0 +;light3: +dd 0.1, 0.9, -3.93 ;sph_max dd 2 non_rot_sphere: - dd 0.7 - dd 0.3 - dd 0.4 ;, 0.0 - - dd 0.2 - dd 0.7 - dd 0.3 ;, 0.0 - - dd 0.1 - dd 0.1 - dd 0.1 ;, 0.0 + dd 0.05 + dd 0.05 + dd 0.05 ;, 0.0 dd 0.7 dd 0.7 - dd 0.1 ;, 0.0 + dd 0.7 ;, 0.0 + + dd 0.5 + dd 0.5 + dd 0.41 ;, 0.0 + + dd 0.7 + dd 0.7 + dd -4.1 ;, 0.0 dd 0.5 dd 0.2 dd 0.1 ;, 0.0 + + dd 0.3 + dd 0.2 + dd 0.1 ;, 0.0 + + dd 0.4 + dd 0.7 + dd 0.5 ;, 0.0 + + dd 0.05 + dd 0.25 + dd 0.8 ;, 0.0 + sph_radius: -R dd 0.25 +R dd 0.09 R2 dd 0.22 r3 dd 0.1 r4 dd 0.25 r5 dd 0.1 +r6 dd 0.19 +r7 dd 0.1 + dd 0.17 + + align 16 +surface: +dd 0.1, -1.0, 0.0 ; A B C constans in Ax+BY+Cz+D=0 surface equation + ; make sure if normalized +dd 0.4 ; D element of equation above + camera: x0 dd 0.5 y0 dd 0.5 -z0 dd - 12.0 , 0.0 +z0 dd - 6.0 , 0.0 ;x1 dd ;y1 dd @@ -52,6 +81,8 @@ float4: dd 4.0, 4.0, 4.0, 4.0 float255: dd 255.0, 255.0, 255.0, 255.0 +zero: +dd 0.0, 0.0, 0.0, 0.0 ;correct_tex: ;dd 64.0, 64.0, 64.0, 64.0 ;light: @@ -61,18 +92,29 @@ dd 255.0, 255.0, 255.0, 255.0 ;light3: ;dd 0.9, 0.1, 0.3, 0.0 lights_color: -dd 250.0, 255.0, 255.0, 0.0 -dd 232.0, 254.0, 220.0, 0.0 -dd 225.0,37.0, 247.0, 0.0 +dd 250.0, 255.0, 155.0, 0.0 +dd 200.0, 254.0, 0.0, 0.0 +dd 255.0,37.0, 247.0, 0.0 -light_factor dd 0.33 -tex_x dd 128 +dd 250.0, 255.0, 255.0, 0.0 +dd 120.0, 54.0, 199.0, 0.0 +dd 25.0,137.0, 247.0, 0.0 +shadow_factor: + dd 50.0, 50.0, 50.0, 50.0 +positive_mask: + dd 0x7fffffff, 0x7fffffff, 0x7fffffff, 0.0 +ambient_col: +db 30, 20, 25, 20 +;light_factor dd 0.33 +;tex_x dd 128 align 16 nearest_sphere: rd 4 nearest_radius dd ? smalest_t dd ? align 16 +surface_without_d: + rd 4 light: rd 4 * MAX_LIGHTS sphere: diff --git a/programs/demos/ray/ray.asm b/programs/demos/ray/ray.asm index 108cebc82e..4455463750 100644 --- a/programs/demos/ray/ray.asm +++ b/programs/demos/ray/ray.asm @@ -6,8 +6,6 @@ ; email : macgub3@wp.pl ; web : http://macgub.hekko.pl -include "../../macros.inc" - timeout equ 3 XRES equ 500 ; window size YRES equ 500 @@ -171,7 +169,13 @@ still: call main_loop - mcall 7,screen,,<0,0> + mov eax,7 + mov ebx,screen + mov ecx,maxx*65536+maxy + xor edx,edx + int 0x40 + + @@ -179,28 +183,37 @@ jmp still -include 'ray.inc' +include 'RAY.INC' ; ********************************************* ; ******* WINDOW DEFINITIONS AND DRAW ******** ; ********************************************* draw_window: + mov eax,12 ; function 12:tell os about windowdraw + mov ebx,1 ; 2, end of draw + int 0x40 - mcall 12,1 + mov eax,48 ; get skin height + mov ebx,4 + int 0x40 - mcall 48,4 ; get skin height - lea ecx,[eax + (100 shl 16) + maxy+4] - mov edi,title - mcall 0,<100,maxx+9>,,0x74000000 + lea ecx,[eax + (100 shl 16) + maxy+4] + mov edi,title + xor eax,eax + mov ebx,100*65536+maxx+9 ; [x start] *65536 + [x size] + mov edx,0x74000000 ; window type + int 0x40 - mcall 12,2 + mov eax,12 ; function 12:tell os about windowdraw + mov ebx,2 ; 2, end of draw + int 0x40 ret title db 'Ray tracing',0 xo dd 0.5 yo dd 0.5 -zo dd 0.1 +zo dd 0.5 deg_counter dw 0 one_deg dd 0.017453 include 'dataray.inc' diff --git a/programs/demos/ray/ray.inc b/programs/demos/ray/ray.inc index da93741a9e..f83f8b304f 100644 --- a/programs/demos/ray/ray.inc +++ b/programs/demos/ray/ray.inc @@ -1,8 +1,8 @@ -MAX_SPHERES = 5 -MAX_LIGHTS = 3 -;ray +MAX_SPHERES = 4 ;8 +MAX_LIGHTS = 6 main_loop: + call normalize_surface xor eax,eax ; y .next_line: xor ebx,ebx ; x @@ -10,6 +10,9 @@ main_loop: @@: push eax push ebx + + + call find_intersection pop ebx pop eax @@ -22,16 +25,33 @@ main_loop: jnz .next_line ret -init_calc: ; do some intial calculations +normalize_surface: + movss xmm0,[surface+8] + movlhps xmm0,xmm0 + movlps xmm0,[surface] + movaps xmm1,xmm0 + mulps xmm0,xmm0 + haddps xmm0,xmm0 + haddps xmm0,xmm0 + sqrtss xmm0,xmm0 + shufps xmm0,xmm0,0 + divps xmm1,xmm0 + movaps xmm2,xmm1 + pslldq xmm2,4 + psrldq xmm2,4 + movaps [surface_without_d],xmm2 + movlps [surface],xmm1 + movhlps xmm1,xmm1 + movss [surface+8],xmm1 ret -find_intersection: ;with for now single sphere +find_intersection: ; eax - y ; ebx - x push ebp mov ebp,esp - sub esp,128 + sub esp,256 and ebp,0xfffffff0 .dz equ dword[ebp-8] .dy equ dword[ebp-12] @@ -48,12 +68,21 @@ find_intersection: ;with for now single sphere .sph_xyz equ [ebp-80] .one_write equ byte [ebp-81] ;tells if sth written in 'nearest' data .sph_counter equ dword [ebp-85] - + .dx_sh equ [ebp-96] + .a_sh equ [ebp-100] + .b_sh equ [ebp-104] + .c_sh equ [ebp-108] + .delta_sh equ [ebp-112] + .sph_counter_sh equ dword[ebp-116] + .shadow_mark equ dword [ebp-120] + .nearest_surface equ [ebp-144] + .vd equ [ebp-148] ; denominator in plane inters. equation mov .iy,eax mov .ix,ebx mov .one_write,0 + mov .shadow_mark,0 xorps xmm0,xmm0 cvtpi2ps xmm0,.ix mov ecx,XRES @@ -68,31 +97,26 @@ find_intersection: ;with for now single sphere haddps xmm1,xmm1 movss .a,xmm1 mov .sph_counter,0 - .next_sph: - xorps xmm5,xmm5 + .next_sph: ; intersection with sphere movaps xmm5,[camera] mov edx,.sph_counter shl edx,4 add edx,sphere - subps xmm5,[edx] ;[sphere] ;;[edx] + subps xmm5,[edx] mulps xmm5,[float2] - movaps xmm0,.dx - mulps xmm5,xmm0 + mulps xmm5,.dx haddps xmm5,xmm5 haddps xmm5,xmm5 movss .b,xmm5 - movaps xmm4,[edx] ;[sphere] ; [edx] + movaps xmm4,[edx] mulps xmm4,xmm4 - ; haddps xmm4,xmm4 - ; haddps xmm4,xmm4 movaps xmm5,[camera] mulps xmm5,xmm5 addps xmm4,xmm5 haddps xmm4,xmm4 haddps xmm4,xmm4 - ; addss xmm4,xmm5 movaps xmm5,[edx] ;;[sphere] ;; [edx] mulps xmm5,[camera] haddps xmm5,xmm5 @@ -115,14 +139,10 @@ find_intersection: ;with for now single sphere movss .delta,xmm5 xorps xmm6,xmm6 cmpnltss xmm5,xmm6 - movd ecx,xmm5 ; ecx = -1 greater than 0.0 + movd ecx,xmm5 ; ecx = -1 => greater than 0.0 cmp ecx,0 jnz @f jmp .next_s ; no intersection - ; add .sph_counter,1 - ; cmp .sph_counter,MAX_SPHERES - ; jnz .next_sph - ; jmp .put_pixel @@: @@ -139,44 +159,66 @@ find_intersection: ;with for now single sphere divss xmm4,[float2] divss xmm4,.a movss .t2,xmm4 - movss xmm5,xmm4 - - cmpnltss xmm4,.t1 - movd ecx,xmm4 - or ecx,ecx - jne @f - movss xmm5,.t2 - @@: + maxss xmm6,xmm4 cmp .one_write,0 ; test if sth in 'nearest' data is written jz @f - movss xmm4,xmm5 + movss xmm4,xmm6 ;5 cmpnltss xmm4,[smalest_t] movd ecx,xmm4 or ecx,ecx jz .next_s @@: - movss [smalest_t],xmm5 -; push .a -; pop [smalest_a] -; push .b -; pop [smalest_b] -; push .c -; pop [smalest_c] -; push .delta -; pop [smalest_delta] + movss [smalest_t],xmm6 ;5 movaps xmm0,[edx] movaps [nearest_sphere],xmm0 push dword[ebx] pop dword[nearest_radius] - mov .one_write,1 - + mov .one_write,1 ; one_write - object index -> 1 = sphere .next_s: add .sph_counter,1 cmp .sph_counter,MAX_SPHERES jnz .next_sph +if 1 + movaps xmm0,[surface_without_d] ; find with plane intersection + mulps xmm0,[camera] ; only one surface is computed + haddps xmm0,xmm0 + haddps xmm0,xmm0 + addss xmm0,[surface+12] + movaps xmm1,[surface_without_d] + mulps xmm1,.dx + haddps xmm1,xmm1 + haddps xmm1,xmm1 + xorps xmm2,xmm2 + cmpnless xmm2,xmm1 + movd ecx,xmm2 + cmp ecx,0 ;-1 + je .put_pixel ; denominator equal 'zero' - no intersection + xorps xmm2,xmm2 ; denominator > 0 -> inters. not in screen area + movss .vd,xmm1 ; write to memory this denom. + divss xmm0,xmm1 + subss xmm2,xmm0 + cmp .one_write,0 + jz @f + movss xmm0,xmm2 + cmpnltss xmm2,[smalest_t] + movd ecx,xmm2 + cmp ecx,0 + je .put_pixel + @@: + movss [smalest_t],xmm0 +; test [smalest_t],0x80000000 +; jz @f +; and [smalest_t],0x7fffffff +; @@: + movaps xmm2,[surface] + movaps .nearest_surface,xmm2 + mov .one_write,2 ; nearest object -> 2 = flat plane + +end if + .put_pixel: - cmp .one_write,0 + cmp .one_write,0 ; end if no intersection je .end movss xmm5,[smalest_t] @@ -184,34 +226,146 @@ find_intersection: ;with for now single sphere movaps xmm6,.dx mulps xmm6,xmm5 movaps xmm4,[camera] - addps xmm4,xmm6 ; xmm4 - x,y,z on the sphere + addps xmm4,xmm6 ; xmm4 - x,y,z on the sphere or on surface + movaps .sph_xyz,xmm4 +if 1 + cmp .one_write,2 + jne .shadow +; movaps xmm4,.sph_xyz + movaps xmm7,xmm4 + lea ebx,.nearest_surface + movss xmm4,[ebx+8] + movlhps xmm4,xmm4 + movlps xmm4,[ebx] ; xmm4 - normal to surface vector + test dword .vd,0x80000000 + jz @f + andps xmm4,[positive_mask] ;0x7fffffff + @@: + + jmp .calc_pix + +end if + .shadow: +if 1 +; to find shadow intersect: +; P0 - point on sphere +; P1 - light +; with every other sphere in scene if any intersection occured - +; - point is in shadow + ; next_sph_shad: + mov ecx,MAX_LIGHTS + .next_light_sh: + push ecx + shl ecx,4 + movaps xmm0,[ecx+light] ;xmm4 - point on nearest sphere + subps xmm0,xmm4 + movaps .dx_sh,xmm0 + + mulps xmm0,xmm0 + haddps xmm0,xmm0 + haddps xmm0,xmm0 + movss .a_sh,xmm0 + + mov .sph_counter_sh,0 + .next_sph_sh: ; be sure you not intersect nearest sphere with itself + movaps xmm5,.sph_xyz ;[light] + mov edx,.sph_counter_sh + shl edx,4 + add edx,sphere + movaps xmm7,[edx] + cmpeqps xmm7,[nearest_sphere] + movmskps ecx,xmm7 + and ecx,0111b + cmp ecx,0 + jne .next_s_sh + + subps xmm5,[edx] ; [edx] - cur sph + mulps xmm5,[float2] + mulps xmm5,.dx_sh + haddps xmm5,xmm5 + haddps xmm5,xmm5 + movss .b_sh,xmm5 + + movaps xmm4,[edx] + mulps xmm4,xmm4 + movaps xmm5,.sph_xyz + mulps xmm5,xmm5 + addps xmm4,xmm5 + haddps xmm4,xmm4 + haddps xmm4,xmm4 + movaps xmm5,.sph_xyz + mulps xmm5,[edx] + haddps xmm5,xmm5 + haddps xmm5,xmm5 + mulss xmm5,[float2] + subss xmm4,xmm5 + mov ebx,.sph_counter_sh + shl ebx,2 + add ebx,sph_radius + movss xmm5,[ebx] + mulss xmm5,xmm5 + subss xmm4,xmm5 + movss .c_sh,xmm4 + + movss xmm5,.b_sh + mulss xmm5,xmm5 + mulss xmm4,.a_sh + mulss xmm4,[float4] + subss xmm5,xmm4 + movss .delta_sh,xmm5 + xorps xmm6,xmm6 + cmpnltss xmm5,xmm6 + movd ecx,xmm5 ; ecx = -1 greater than 0.0 + cmp ecx,0 + jnz @f + jmp .next_s_sh ; no intersection + @@: + add .shadow_mark,1 ; mark ->point in shadow + pop ecx + sub ecx,1 + jnz .next_light_sh + jmp .put_pix + .next_s_sh: + add .sph_counter_sh,1 + cmp .sph_counter_sh,MAX_SPHERES + jnz .next_sph_sh + pop ecx + sub ecx,1 + jnz .next_light_sh + +end if + + + + + + + .put_pix: + movaps xmm4,.sph_xyz movaps xmm7,xmm4 subps xmm4,[nearest_sphere] - ; movaps xmm6,xmm7 - ; addps xmm6,[nearest_sphere] - ; movaps .sph_xyz,xmm6 movss xmm0,[nearest_radius] shufps xmm0,xmm0,0 divps xmm4,xmm0 ; xmm4 - normal to surface vector + .calc_pix: ; normal computed movaps xmm1,xmm4 ; copy of normal in xmm1 xor eax,eax xorps xmm3,xmm3 - movss xmm2,[light_factor] - shufps xmm2,xmm2,0 + ; movss xmm2,[light_factor] ; other model of lighting + ; shufps xmm2,xmm2,0 .next_light: - ; push eax mov ebx,eax shl ebx,4 - ;add eax,light - movaps xmm5,[light+ebx];[light] ;; [eax] + movaps xmm5,[light+ebx] subps xmm5,xmm7 ; calc light unit vector movaps xmm6,xmm5 mulps xmm5,xmm5 haddps xmm5,xmm5 haddps xmm5,xmm5 sqrtss xmm5,xmm5 + shufps xmm5,xmm5,0 divps xmm6,xmm5 ; xmm6 - normalized light vector ; dot_product movaps xmm4,xmm1 ; xmm4 - normal to surface @@ -219,54 +373,97 @@ find_intersection: ;with for now single sphere haddps xmm4,xmm4 haddps xmm4,xmm4 shufps xmm4,xmm4,0 -; movaps xmm5,xmm4 -; mulps xmm5,xmm5 -; mulps xmm5,xmm5 -; mulps xmm5,[color] mulps xmm4,[lights_color+ebx] ; xmm4 - computed col. light vector dep. -; addps xmm4,xmm5 - mulps xmm4,xmm2 - addps xmm3,xmm4 - ; pop eax + +; mulps xmm4,xmm2 ; other model of lighting +; addps xmm3,xmm4 + + maxps xmm3,xmm4 ; will be this better ? + add eax,1 cmp eax,MAX_LIGHTS jnz .next_light -if 0 - ; mix with texture - movaps xmm0,.sph_xyz - movss xmm1,[nearest_radius] - shufps xmm1,xmm1,0 - divps xmm0,xmm1 - mulps xmm0,[correct_tex] ; f64 - ; addps xmm0,[correct_tex] - cvtss2si eax,xmm0 - psrldq xmm0,4 - cvtss2si ebx,xmm0 - imul ebx,[tex_x] - add ebx,eax - lea ebx,[ebx*3] - add ebx,bitmap - ;mov eax,[ebx] - movd xmm1,[ebx] - xorps xmm7,xmm7 - punpcklbw xmm1,xmm7 - punpcklwd xmm1,xmm7 - cvtdq2ps xmm1,xmm1 - mulps xmm3,xmm1 - divps xmm3,[float255] - ; divps xmm1,[float2] - ; divps xmm3,[float2] - ; addps xmm3,xmm1 -end if - minps xmm3,[float255] + cmp .shadow_mark,0 + je @f + cvtsi2ss xmm2,.shadow_mark + shufps xmm2,xmm2,0 + mulps xmm2,[shadow_factor] + subps xmm3,xmm2 + xorps xmm0,xmm0 + maxps xmm3,xmm0 + @@: + cvtps2dq xmm3,xmm3 packssdw xmm3,xmm3 packuswb xmm3,xmm3 + paddusb xmm3,[ambient_col] + +if 1 + cmp .one_write,2 + jne .perspective + movaps xmm0,xmm3 ; calc texture on plane + movaps xmm1,.sph_xyz + mov ecx,XRES + cvtsi2ss xmm4,ecx + shufps xmm4,xmm4,0 + mulps xmm1,xmm4 + cvtps2dq xmm1,xmm1 + movd ecx,xmm1 + test ecx,0x8 + jz @f + mov ecx,0xffffffff + jmp .next_tex_test + @@: + xor ecx,ecx + .next_tex_test: + psrldq xmm1,8 + movd ebx,xmm1 + test ebx,0x20 + jz @f + mov ebx,0xffffffff + jmp .set_tex + @@: + xor ebx,ebx + .set_tex: + xor ebx,ecx + shr ebx,28 + mov bh,bl + movd xmm7,ebx + paddusb xmm3,xmm7 + +end if +.perspective: + movaps xmm0,.sph_xyz ; perspective correction + subps xmm0,[camera] + movss xmm1,[camera] + movss xmm2,xmm0 + movaps xmm4,xmm0 + shufps xmm4,xmm4,00000010b + divss xmm2,xmm4 + mulss xmm2,[camera+8] + subss xmm1,xmm2 ; xmm1 - x + movaps xmm2,xmm0 + shufps xmm2,xmm2,00000001b + movaps xmm4,xmm0 + shufps xmm4,xmm4,00000010b + divss xmm2,xmm4 + mulss xmm2,[camera+8] + movss xmm4,[camera+4] + subss xmm4,xmm2 ; xmm4 - y + + mov ebx,XRES + cvtsi2ss xmm2,ebx + mulss xmm1,xmm2 + mulss xmm4,xmm2 + cvtss2si ecx,xmm1 + mov .ix,ecx + cvtss2si edx,xmm4 + mov .iy,edx mov edi,screen mov ecx,XRES @@ -275,9 +472,8 @@ end if lea ecx,[ecx*3] add edi,ecx movd [edi],xmm3 - .end: - add esp,128 + add esp,256 pop ebp ret