rt3DS/source/vshader.v.pica
2023-04-10 01:14:28 -04:00

182 lines
3.6 KiB
Plaintext

.constf myconst(0.0, 1.0, 0.01, 1000.0)
.constf myconst2(0.5, 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 inLowerLeftCorner v1
.in inHorizontal v2
.in inVertical v3
.in inST v4
.in inPos v5
.in inUV v6
.out outPos position
.out outUV texcoord0
.out outColor color
.proc main
; outPos = inPos
mov outPos, inPos
; outUV = inUV
mov outUV, inUV
; r1 = inOrigin
mov r1, inOrigin
; r2 = inDirection
mov r2.xyz, inLowerLeftCorner
mov r3.xy, inST.xy
mad r2.xyz, inHorizontal, r3.x, r2.xyz
mad r2.xyz, inVertical, r3.y, r2.xyz
; 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