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 (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...