rt3DS/source/vshader.v.pica

234 lines
4.4 KiB
Plaintext
Raw Normal View History

2023-04-15 15:48:20 +00:00
.constf myconst(0.0, 1.0, 0.001, 1000.0)
.constf myconst2(0.5, 999.0, 1.1, 0.0)
2023-04-08 16:51:11 +00:00
.alias zeros myconst.xxxx
2023-04-10 14:12:45 +00:00
.alias halfs myconst2.xxxx
2023-04-08 16:51:11 +00:00
.alias ones myconst.yyyy
2023-04-15 15:48:20 +00:00
.alias tooclose myconst.zzzz
2023-04-08 16:51:11 +00:00
.alias far myconst.wwww
2023-04-10 14:12:45 +00:00
.alias noHit myconst2.yyyy
2023-04-08 16:51:11 +00:00
2023-04-11 23:54:15 +00:00
.consti bounceLoopParams(9, 0, 1, 0)
.consti calcSphereLoopParams(3, 0, 1, 0)
2023-04-08 16:51:11 +00:00
.setb b0 true
.alias true b0
; xyz center (in world space)
; w radius (in world space)
2023-04-11 23:54:15 +00:00
.fvec spheres[4]
2023-04-08 16:51:11 +00:00
2023-04-10 14:12:45 +00:00
; material albedo
2023-04-11 23:54:15 +00:00
.fvec sphereColors[4]
; material emitted light
.fvec sphereLights[4]
2023-04-10 14:12:45 +00:00
2023-04-10 19:45:27 +00:00
; random numbers
2023-04-11 23:54:15 +00:00
.fvec rand[10]
2023-04-10 19:45:27 +00:00
2023-04-08 16:51:11 +00:00
.in inOrigin v0
2023-04-10 05:14:28 +00:00
.in inLowerLeftCorner v1
.in inHorizontal v2
.in inVertical v3
.in inST v4
.in inPos v5
.in inUV v6
2023-04-08 16:51:11 +00:00
.out outPos position
2023-04-10 05:14:28 +00:00
.out outUV texcoord0
2023-04-08 16:51:11 +00:00
.out outColor color
.proc main
; r1 = inOrigin
mov r1, inOrigin
; r2 = inDirection
2023-04-10 05:14:28 +00:00
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
2023-04-08 16:51:11 +00:00
2023-04-11 23:54:15 +00:00
; set initial color multiplier to (1, 1, 1)
2023-04-10 14:12:45 +00:00
mov r4.xyz, ones
2023-04-11 23:54:15 +00:00
; set initial color to (0, 0, 0)
mov r13.xyz, zeros
2023-04-08 16:51:11 +00:00
; calculate light bounces
for bounceLoopParams
2023-04-10 19:45:27 +00:00
; setup random numbers for this iteration
mov r11, rand[aL]
2023-04-10 14:12:45 +00:00
; reset max ray distance
mov r4.w, far
; set albedo to a large number for sphere hit check
mov r10.xyz, far
2023-04-08 16:51:11 +00:00
; for each sphere
for calcSphereLoopParams
; r3 = spheres[i]
mov r3, spheres[aL]
; do calculation
call calcSphere
2023-04-08 16:51:11 +00:00
.end
2023-04-10 14:12:45 +00:00
2023-04-11 23:54:15 +00:00
; check if noHit < albedo
; and exit early if true
; as albedo has not been set
; after the initial set
; which only happens when
; a ray does not hit any spheres
2023-04-11 23:54:15 +00:00
cmp noHit.xyz, lt, lt, r10.xyz
; not using breakc. it behaves weird.
2023-04-15 15:48:20 +00:00
jmpc cmp.x, labl
2023-04-10 14:12:45 +00:00
; multiply color by albedo
mul r4.xyz, r4.xyz, r10.xyz
; add emitted light
2023-04-11 23:54:15 +00:00
mad r13.xyz, r4.xyz, r12.xyz, r13.xyz
2023-04-10 14:12:45 +00:00
; set r1 to new ray origin
2023-04-10 19:45:27 +00:00
mov r1.xyz, r5.xyz
2023-04-10 14:12:45 +00:00
; set r2 to new ray direction
call diffuse
2023-04-08 16:51:11 +00:00
.end
2023-04-15 15:48:20 +00:00
labl:
2023-04-08 16:51:11 +00:00
; copy final color to output
2023-04-11 23:54:15 +00:00
mov outColor.xyz, r13.xyz
2023-04-08 16:51:11 +00:00
; set alpha to 1
mov outColor.w, ones
2023-04-15 15:48:20 +00:00
mov outPos, inPos
mov outUV, inUV
2023-04-08 16:51:11 +00:00
end
.end
2023-04-10 19:45:27 +00:00
; Calculate Sphere Intersection
; -----------------------------
;
2023-04-08 16:51:11 +00:00
; Inputs
; ------
2023-04-10 19:45:27 +00:00
; r1.xyz: ray origin
; r2.xyz: ray direction
; r3.xyz: sphere origin
; r3.w: sphere radius
; r4.w: min distance
2023-04-11 23:54:15 +00:00
; r11.xyz: random unit vector
; r11.w: random number
2023-04-08 16:51:11 +00:00
;
; Outputs
; -------
2023-04-10 19:45:27 +00:00
; r4.w: new min distance
; r10.xyz: albedo
2023-04-11 23:54:15 +00:00
; r12.xyz: light emitted
2023-04-08 16:51:11 +00:00
;
; Temporaries
; -----------
2023-04-10 19:45:27 +00:00
; r5.xyz: new origin
; r6.xyz: new direction
; r7.xyz: hit normal
; r8.xyzw: used for calculations
; r9.xyzw: used for calculations
.proc 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
2023-04-15 15:48:20 +00:00
cmp tooclose, 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
2023-04-15 15:48:20 +00:00
cmp tooclose, 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
2023-04-15 15:48:20 +00:00
mad r5.xyz, r2.xyz, r9.zzz, r1.xyz
; calculate normal
add r7.xyz, r5.xyz, -r3.xyz
rcp r3.w, r3.w
mul r7.xyz, r7.xyz, r3.w
; set albedo
mov r10.xyz, sphereColors[aL].xyz
; set light emitted
mov r12.xyz, sphereLights[aL].xyz
; early exit label
calcSphereExit:
nop
.end
.proc diffuse
add r2.xyz, r7.xyz, r11.xyz
.end