mirror of
https://git.shylie.info/shylie/rt3DS.git
synced 2024-12-22 22:50:05 +00:00
171 lines
3.3 KiB
Plaintext
171 lines
3.3 KiB
Plaintext
.constf myconst(0.0, 1.0, 0.01, 1000.0)
|
|
.constf myconst2(0.25, 0.0, 0.0, 0.0)
|
|
.alias zeros myconst.xxxx
|
|
.alias ones myconst.yyyy
|
|
.alias near myconst.zzzz
|
|
.alias far myconst.wwww
|
|
.alias defaultMissColor myconst.xxxy
|
|
.alias defaultHitColor myconst.yxxy
|
|
.alias halfs myconst2.xxxx
|
|
|
|
.consti bounceLoopParams(0, 0, 1, 0)
|
|
.consti calcSphereLoopParams(2, 0, 1, 0)
|
|
|
|
.setb b0 true
|
|
.alias true b0
|
|
|
|
; xyz center (in world space)
|
|
; w radius (in world space)
|
|
.fvec spheres[3]
|
|
|
|
.in inOrigin v0
|
|
.in inDirection v1
|
|
.in inPos v2
|
|
|
|
.out outPos position
|
|
.out outColor color
|
|
|
|
.proc main
|
|
; outPos = inPos
|
|
mov outPos, inPos
|
|
|
|
; r1 = inOrigin
|
|
mov r1, inOrigin
|
|
|
|
; r2 = inDirection
|
|
mov r2, inDirection
|
|
|
|
; calculate light bounces
|
|
for bounceLoopParams
|
|
; r4 = (0, 0, 0, far)
|
|
mov r4, myconst.xxxw
|
|
|
|
; for each sphere
|
|
for calcSphereLoopParams
|
|
; r3 = spheres[i]
|
|
mov r3, spheres[aL]
|
|
|
|
; do calculation
|
|
; call calcSphere
|
|
; vec3 oc = origin - center
|
|
add r8.xyz, r1.xyz, -r3.xyz
|
|
|
|
; float a = dot(direction, direction)
|
|
dp3 r9.x, r2.xyz, r2.xyz
|
|
|
|
; float halfB = dot(oc, direction)
|
|
dp3 r9.y, r8.xyz, r2.xyz
|
|
|
|
; float radiusSquared = radius * radius
|
|
mul r8.w, r3.w, r3.w
|
|
|
|
; float c = dot(oc, oc) - radius * radius
|
|
dp3 r9.z, r8.xyz, r8.xyz
|
|
add r9.z, r9.z, -r8.w
|
|
|
|
; float halfBSquared = halfB * halfB;
|
|
mul r8.w, r9.y, r9.y
|
|
|
|
; float ac = a * c;
|
|
mul r9.w, r9.x, r9.z
|
|
|
|
; float discriminant = bSquared - ac
|
|
add r8.w, r8.w, -r9.w
|
|
|
|
; if discriminant < 0, exit procedure early
|
|
cmp zeros, gt, gt, r8.w
|
|
jmpc cmp.x, calcSphereExit
|
|
|
|
; calculate t
|
|
; float sqrtDiscriminant = sqrt(discriminant)
|
|
rsq r8.w, r8.w
|
|
rcp r8.w, r8.w
|
|
|
|
; a = 1 / a
|
|
rcp r9.x, r9.x
|
|
|
|
; float root = (-halfB - sqrtDiscriminant) / a
|
|
add r9.z, -r9.y, -r8.w
|
|
mul r9.z, r9.z, r9.x
|
|
|
|
; if root < min distance, check other root
|
|
cmp near, gt, gt, r9.z
|
|
jmpc cmp.x, calcSphereCheckOtherRoot
|
|
|
|
; if root > max distance, check other root
|
|
cmp r9.z, gt, gt, r4.w
|
|
jmpc cmp.x, calcSphereCheckOtherRoot
|
|
|
|
; if root is in range, finalize calculations
|
|
jmpu true, calcSphereFin
|
|
|
|
calcSphereCheckOtherRoot:
|
|
|
|
; float root = (-halfB + sqrtDiscriminant) / a
|
|
add r9.z, -r9.y, r8.w
|
|
mul r9.z, r9.z, r9.x
|
|
|
|
; if root < min distance, check other root
|
|
cmp near, gt, gt, r9.z
|
|
jmpc cmp.x, calcSphereExit
|
|
|
|
; if root > max distance, check other root
|
|
cmp r9.z, gt, gt, r4.w
|
|
jmpc cmp.x, calcSphereExit
|
|
|
|
calcSphereFin:
|
|
|
|
; change max distance to closest hit
|
|
mov r4.w, r9.z
|
|
|
|
; calculate new origin
|
|
mul r5.xyz, r2.xyz, r9.zzz
|
|
add r5.xyz, r5.xyz, r1.xyz
|
|
|
|
; calculate normal
|
|
add r7.xyz, r5.xyz, -r3.xyz
|
|
rcp r3.w, r3.w
|
|
mul r7.xyz, r7.xyz, r3.w
|
|
|
|
; assign color
|
|
mov r4.xyz, r7.xyz
|
|
add r4.xyz, ones, r4.xyz
|
|
mul r4.xyz, halfs, r4.xyz
|
|
|
|
; early exit label
|
|
calcSphereExit:
|
|
nop
|
|
; done with calculation
|
|
.end
|
|
.end
|
|
|
|
; copy final color to output
|
|
mov outColor.xyz, r4.xyz
|
|
; set alpha to 1
|
|
mov outColor.w, ones
|
|
|
|
end
|
|
.end
|
|
|
|
; Inputs
|
|
; ------
|
|
; r1.xyz: ray origin
|
|
; r2.xyz: ray direction
|
|
; r3.xyzw: sphere info
|
|
; r4.w: min distance
|
|
;
|
|
; Outputs
|
|
; -------
|
|
; r4.w: new min distance
|
|
; r4.xyz: new color
|
|
;
|
|
; Temporaries
|
|
; -----------
|
|
; r5.xyz: new origin
|
|
; r6.xyz: new direction
|
|
; r7.xyz: hit normal
|
|
; r8
|
|
; r9
|
|
;
|
|
;.proc calcSphere
|
|
;.end |