如何解决x87 - raymarcher 中的问题
下面是我的raymarcher,大部分改编自https://www.shadertoy.com/view/llt3R4#
预期的行为是一个球体在屏幕上的投影,而是投影
空白区域(由黄色像素表示,而不是紫色像素)。
这是我使用 x87 协处理器编写的第一个程序,所以我不确定是否有任何遗漏。 我认识的几个程序员都看过了,没有发现问题,所以我不知道该怎么办。
macro bareintro {
org 0x7c00
jmp 0x0:boot
boot:
xor ax,ax
mov ds,ax
mov ss,ax
}
macro zerob b {
times b db 0
}
bareintro
mov ax,0x13
int 0x10
mov ax,0xA000
mov es,ax
xor di,di
y_loop:
mov word [ix],0
mov bx,[iy]
inc bx
cmp bx,200
je y_end
mov [iy],bx
x_loop:
; first calculate the raymarching direction:
; vec3 rayDirection(float fieldOfView,vec2 size,vec2 fragCoord) {
; vec2 xy = fragCoord - size / 2.0;
; float z = size.y / tan(radians(fieldOfView) / 2.0);
; return normalize(vec3(xy,-z));
; }
fld qword [h]
fld qword [z_diri]
fmulp
fld qword [y_diri]
fild word [iy]
faddp
fld qword [x_diri]
fild word [ix]
faddp
; finally,normalize vector
; do a couple dupes
fld st2
fld st2
fld st2
call len
fdiv st1,st0
fdiv st2,st0
fdivp st3,st0
; store in respective memory locations
fstp qword [dir_x]
fstp qword [dir_y]
fstp qword [dir_z]
call sdts
setc al
add al,13
stosb
inc word [ix]
cmp word [ix],319
ja y_loop
jmp x_loop
y_end:
cli
hlt
; int intersect(float rayx,float rayy,float rayz) {
; float depth = MIN_disT;
; for(int i = 0; i < STEPS; i++) {
; float vx = rayx * depth;
; float vy = rayy * depth;
; float vz = rayz * depth + 5.0;
; float dist = sdf(vx,vy,vz);
; if(dist < EPS) {
; return 1;
; }
; depth += dist;
; if(depth >= MAX_disT) {
; return 0;
; }
; }
; return 0;
;}
sdts:
fldz
fstp qword [.depth]
mov cx,255
.loop:
; float dist = scenesDF(eye + depth * marchingDirection);
; load in direction vector
fld qword [dir_z]
fld qword [dir_y]
fld qword [dir_x]
fld qword [.depth]
fmul st1,st0
fmul st2,st0
fmulp st3,st0
fld qword [eyez]
fld qword [eyey]
fld qword [eyex]
faddp st3,st0
faddp st3,st0
.sdf:
; single sphere for Now (len(p) - radius)
call len
; - radius
fld qword [radius]
fsubp st1,st0
.endsdf:
; EPS <=> dist
fld qword [eps]
fcomip st0,st1
jb .nohit
; cowabunga!
clc
ret
.nohit:
fld qword [.depth]
; MAX <=> Total
faddp
fld qword [.max_depth]
fcomip st0,st1
fstp qword[.depth]
ja .alsofine
stc
ret
.alsofine:
loop .loop
.endloop:
stc
ret
.max_depth:
dq 100.0
.depth:
dq 0.0
; st0 <- sqrt(s0^2 + s1^2 + s2^2)
len:
fmul st0,st0
fxch st1
fmul st0,st0
faddp st1,st0
fsqrt
ret
x_diri:
dq -160.000
y_diri:
dq -100.000
z_diri:
dq 482.8427
dir_x:
dq -160.000
dir_y:
dq -100.000
dir_z:
dq -2.4142135623911343
w:
dq 320.0
h:
dq 200.0
radius:
dq 1.0
eps:
dq 0.001
eyex:
dq 0.0
eyey:
dq 0.0
eyez:
dq 5.0
ix:
dw 0
iy:
dw 0
zerob 510 - ($-$$)
dw 0xaa55
(这里是 C 代码的工作版本)
#include <math.h>
#include <SDL2/SDL.h>
const int STEPS = 256;
const float MIN_disT = 0.0;
const float MAX_disT = 100.0;
const float EPS = 0.001;
float sdf(float x,float y,float z) {
float len = sqrt(x*x + y*y + z*z);
return len - 1.0;
}
int intersect(float rayx,float rayz) {
float depth = MIN_disT;
for(int i = 0; i < STEPS; i++) {
float vx = rayx * depth;
float vy = rayy * depth;
float vz = rayz * depth + 5.0;
float dist = sdf(vx,vz);
if(dist < EPS) {
return 1;
}
depth += dist;
if(depth >= MAX_disT) {
return 0;
}
}
return 0;
}
int main() {
SDL_Init(SDL_INIT_EVERYTHING);
uint32_t buff[320*200];
SDL_Window* win;
SDL_Renderer* ren;
SDL_CreateWindowAndRenderer(320,200,&win,&ren);
SDL_Texture* tex = SDL_CreateTexture(ren,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_STATIC,320,200);
for(size_t y = 0; y < 200; y++) {
for(size_t x = 0; x < 320; x++) {
float r_z = -200.0 / 0.41421356237;
float r_y = ((float)y) - 100.0;
float r_x = ((float)x) - 160.0;
float len = sqrt(r_x*r_x + r_y*r_y + r_z*r_z);
r_x /= len;
r_y /= len;
r_z /= len;
buff[y*320 + x] = (-1) * intersect(r_x,r_y,r_z);
}
}
SDL_UpdateTexture(tex,NULL,buff,320*4);
SDL_Rendercopy(ren,tex,NULL);
SDL_RenderPresent(ren);
SDL_Event e;
while(1) {
SDL_WaitEvent(&e);
if(e.type == SDL_QUIT) {
SDL_Quit();
return 0;
}
}
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。