エラーが発生しています。

レイトレーサー

by mj, at 2015年6月30日 00:54:16

powered by hsp3dish.js / OpenHSP

コメント
説明

操作方法

キー 役割
十字キー カメラの操作
Spaceキー 荒くレンダリング
Enterキー 詳細にレンダリング(10分ほどかかるかもしれないです)

ソースコードはこちら。

HSPでレイトレーシング - Devlion Memo

#include "hsp3dish.as"

#module m

#define global INF expf(1000)

// Vector
#enum global X = 0
#enum global Y
#enum global Z

#define global let_vec(%1,%2,%3,%4) %1.X=%2:%1.Y=%3:%1.Z=%4
#define global copy_vec(%1,%2) let_vec %1,%2.X,%2.Y,%2.Z
#define global ret_vec(%1) let_vec %1,rx@m,ry@m,rz@m
#define global log_vec(%1,%2="Vec") logmes %2+strf("(%%f,%%f,%%f)",%1.X,%1.Y,%1.Z)

#define global plus_vec(%1,%2) _plus_vec %1.X,%1.Y,%1.Z,%2.X,%2.Y,%2.Z
#deffunc _plus_vec double x1,double y1,double z1,double x2,double y2,double z2
    rx=x1+x2
    ry=y1+y2
    rz=z1+z2
return

#define global minus_vec(%1,%2) _minus_vec %1.X,%1.Y,%1.Z,%2.X,%2.Y,%2.Z
#deffunc _minus_vec double x1,double y1,double z1,double x2,double y2,double z2
    rx=x1-x2
    ry=y1-y2
    rz=z1-z2
return


#define global cross_vec(%1,%2) _cross_vec %1.X,%1.Y,%1.Z,%2.X,%2.Y,%2.Z
#deffunc _cross_vec double x1,double y1,double z1,double x2,double y2,double z2
    rx=y1*z2-z1*y2
    ry=z1*x2-x1*z2
    rz=x1*y2-y1*x2
return

#define global ctype dot_vec(%1,%2) _dot_vec(%1.X,%1.Y,%1.Z,%2.X,%2.Y,%2.Z)
#defcfunc _dot_vec double x1,double y1,double z1,double x2,double y2,double z2
return x1*x2+y1*y2+z1*z2

#define global ctype mag_vec(%1) _mag_vec(%1.X,%1.Y,%1.Z)
#defcfunc _mag_vec double x1,double y1,double z1
return sqrt(_dot_vec(x1,y1,z1,x1,y1,z1))

#define global times_vec(%1,%2) _times_vec %1.X,%1.Y,%1.Z,%2
#deffunc _times_vec double x1,double y1,double z1,double n
    rx=n*x1
    ry=n*y1
    rz=n*z1
return

#define global norm_vec(%1) _norm_vec %1.X,%1.Y,%1.Z
#deffunc _norm_vec double x1,double y1,double z1
    mag = _mag_vec(x1,y1,z1)
    if (mag == 0) { div = INF }else{ div = 1.0 / mag }
    _times_vec x1,y1,z1, div
return


// Color
#enum global R = 0
#enum global G
#enum global B

#define global let_col(%1,%2,%3,%4) %1.R=%2:%1.G=%3:%1.B=%4
#define global copy_col(%1,%2) let_col %1,%2.R,%2.G,%2.B
#define global ret_col(%1) let_col %1,rr@m,rg@m,rb@m
#define global setDraw_col(%1) color limit(int(%1.R*255),0,255),limit(int(%1.G*255),0,255),limit(int(%1.B*255),0,255)
#define global log_col(%1,%2="Col") logmes %2+strf("(%%f,%%f,%%f)",%1.R,%1.G,%1.B)

#define global plus_col(%1,%2) _plus_col %1.R,%1.G,%1.B,%2.R,%2.G,%2.B
#deffunc _plus_col double r1,double g1,double b1,double r2,double g2,double b2
    rr=r1+r2
    rg=g1+g2
    rb=b1+b2
    _norm_result_col
return

#define global times_col(%1,%2) _times_col %1.R,%1.G,%1.B,%2
#deffunc _times_col double r1,double g1,double b1,double n
    rr=n*r1
    rg=n*g1
    rb=n*b1
    _norm_result_col
return

#define global cross_col(%1,%2) _cross_col %1.R,%1.G,%1.B,%2.R,%2.G,%2.B
#deffunc _cross_col double r1,double g1,double b1,double r2,double g2,double b2
    rr=r1*r2
    rg=g1*g2
    rb=b1*b2
    _norm_result_col
return

#deffunc _norm_result_col
    rr=limitf(rr,0,1.0):rg=limitf(rg,0,1.0):rb=limitf(rb,0,1.0)
return

#global

// Initialize
let_vec zero, 0.0,  0.0, 0.0  
let_vec right, 1.0, 0.0, 0.0  
let_vec left, -1.0, 0.0, 0.0  
let_vec forward, 0.0, 0.0, 1.0  
let_vec backward, 0.0, 0.0, -1.0  
let_vec down, 0.0, -1.0, 0.0  
let_vec up,   0.0,  1.0, 0.0

let_col white,1.0, 1.0, 1.0  
let_col black,0.0, 0.0, 0.0  
let_col grey, 0.5, 0.5, 0.5  
let_col red,  1.0, 0.0, 0.0  
let_col green,0.0, 1.0, 0.0  
let_col blue, 0.0, 0.0, 1.0

// Camera
let_vec camera,      3.0, 2.0, 4.0  
let_vec cameraLook, -1.0, 0.5, 0.0

// Light
ddim light, 4, 3  
ddim lightColor, 4, 3  
let_vec light.0,    -2.0, 2.5, 0.0  
let_vec light.1,     0.0, 3.5, 0.0  
let_vec light.2,     1.5, 2.5, -1.5  
let_vec light.3,     1.5, 2.5, 1.5  
copy_col lightColor.0, white  
copy_col lightColor.1, red  
copy_col lightColor.2, blue  
copy_col lightColor.3, green

// Sphere
ddim sphere, 2, 3  
let_vec sphere.0,  0.0,  1.0, -0.25  
let_vec sphere.1,  -1.0, 0.5, 1.5

// Ground
let_vec ground, 0.0, -1.0, 0.0

// Background Color
copy_col bgColor,  black

// Default Color
copy_col defColor, black

div   = 20

gosub *render

// Main Loop
*main

    gosub *keyCheck

    await 60

goto *main


*render

gosub *cameraInit

//if (div > 1) :redraw 0
redraw 0

repeat dw

    dx = cnt

    //if (div == 1) :redraw 0, dx*div, 0, (dx+1)*div, ginfo_winy

    repeat dh

        dy = cnt

        screenX =  (double(dx) - w/2.0) / 2.0 / w
        screenY = (-(double(dy) - h/2.0) / 2.0 / h) * aspect

        copy_vec cameraRayStart, camera

        times_vec cameraRgt, screenX      :ret_vec cameraRayDir
        times_vec cameraUp,  screenY      :ret_vec tmp

        plus_vec cameraRayDir, tmp        :ret_vec cameraRayDir
        plus_vec cameraRayDir, cameraFor  :ret_vec cameraRayDir

        norm_vec cameraRayDir             :ret_vec cameraRayDir

        gosub *trace

        setDraw_col cl
        boxf dx*div, dy*div, (dx+1)*div, (dy+1)*div
    loop

    //if (div == 1) :redraw 1, dx*div, 0, (dx+1)*div, ginfo_winy

loop

//if (div > 1) :redraw 1
redraw 1

return


*keyCheck

    stick key, 1+2+4+8

    // no needs to redraw
    if ((key & (1+2+4+8+16+32)) == 0) :return

    // initialize cameraDelta
    copy_vec cameraDelta, zero

    if (key & 1) {
        copy_vec cameraDelta, left
        div = 20
    }
    if (key & 2) {
        copy_vec cameraDelta, backward
        div = 20
    }
    if (key & 4) {
        copy_vec cameraDelta, right
        div = 20
    }
    if (key & 8) {
        copy_vec cameraDelta, forward
        div = 20
    }
    plus_vec camera, cameraDelta  :ret_vec camera

	if (key & 16) {
	
		div = 4
		
	}

    if (key & 32) {

        div = 1

    }

    gosub *render

return

*cameraInit

    // initialize
    copy_vec cameraFor, zero
    copy_vec cameraRgt, zero
    copy_vec cameraUp , zero

    // determine axis of camera
    minus_vec cameraLook, camera   :ret_vec cameraFor
    norm_vec  cameraFor            :ret_vec cameraFor

    cross_vec cameraFor,  down     :ret_vec cameraRgt
    norm_vec  cameraRgt            :ret_vec cameraRgt

    cross_vec cameraFor,  cameraRgt:ret_vec cameraUp
    norm_vec  cameraUp             :ret_vec cameraUp


    dw = ginfo_winx / div
    dh = ginfo_winy / div

    w = double(dw)
    h = double(dh)

    aspect = h / w

return

*trace

    copy_col cl, bgColor

    repeat 5

        // setup ray
        copy_vec rayStart, cameraRayStart
        copy_vec rayDir,   cameraRayDir

        trace_mode = 1
        gosub *traceRay

        // doesn't hit
        if (distance >= INF) :break

        // Reflection
        times_vec normal, dot_vec(normal, rayDir) :ret_vec reflection
        times_vec reflection,   2.0               :ret_vec reflection
        minus_vec rayDir, reflection              :ret_vec reflection
        norm_vec  reflection                      :ret_vec reflection

        copy_vec  rayStart, rayPosition 

        // Lighting
        repeat length(light)
            minus_vec light.cnt,          rayStart     :ret_vec lightPosition
            norm_vec  lightPosition                    :ret_vec lightDir

            copy_vec rayDir,   lightDir

            trace_mode = 0
            gosub *traceRay

            // is in shadow
            if (distance <= mag_vec(lightPosition)) {
                continue
            }

            illum = dot_vec(lightDir, normal)
            spec  = dot_vec(lightDir, reflection)

            copy_col illumColor, defColor
            copy_col specColor,  defColor

            if (illum > 0) {
                times_col lightColor.cnt, illum             :ret_col illumColor
            }
            if (spec > 0) {
                times_col lightColor.cnt, powf(spec,250.0)  :ret_col specColor
            }

            cross_col illumColor, intersected     :ret_col illumColor
            cross_col specColor,  lightColor.cnt  :ret_col specColor
            plus_col  illumColor, specColor       :ret_col illumColor
            plus_col  cl, illumColor              :ret_col cl
        loop

        // setup next ray
        copy_vec cameraRayStart, rayStart
        copy_vec cameraRayDir,   reflection

    loop


return

*traceRay

    distance = INF

    // Sphere Intersection
    repeat length(sphere)
        minus_vec sphere.cnt, rayStart  :ret_vec eo
        v = dot_vec(eo, rayDir)

        if (v >= 0) {
            tmp_dist1 = 0.5 - (dot_vec(eo,eo) - v*v)
            if (tmp_dist1 >= 0) {

                tmp_dist2 = v - sqrt(tmp_dist1)

                if (distance > tmp_dist2) {
                    distance = tmp_dist2

                    times_vec rayDir,       distance     :ret_vec rayPosition
                    plus_vec  rayStart,     rayPosition  :ret_vec rayPosition

                    if (trace_mode == 1) {
                        copy_col intersected, grey

                        // normal
                        minus_vec rayPosition, sphere.cnt :ret_vec normal
                        norm_vec  normal                  :ret_vec normal
                    }
                }
            }
        }
    loop

    // Ground Intersection
    d = dot_vec(up, rayDir)
    if (d < 0) {
        tmp_dist1 = (dot_vec(up, rayStart) - ground.Y) / -d
        if (distance > tmp_dist1) {
            distance = tmp_dist1

            if (trace_mode == 1) {
                times_vec rayDir,       distance     :ret_vec rayPosition
                plus_vec  rayStart,     rayPosition  :ret_vec rayPosition

                if ((int(rayPosition.X) + int(rayPosition.Z)) \ 2 != 0) {
                    copy_col intersected, white
                } else {
                    copy_col intersected, black
                }

                // normal
                copy_vec normal, up
            }
        }
    }

return

作成者
icon

mj

ここはユーザの紹介文

詳しく...


関連プログラム