mirror of
https://git.shylie.info/shylie/rt3DS.git
synced 2024-12-22 14:40:04 +00:00
328 lines
6.5 KiB
Plaintext
328 lines
6.5 KiB
Plaintext
.constf myconst(0.0, 1.0, 0.001, 1000.0)
|
|
.constf myconst2(0.5, 999.0, 1.1, 2.0)
|
|
.constf myconst3(0.5, 0.0, 0.0, 0.0)
|
|
.alias zeros myconst.xxxx
|
|
.alias halfs myconst2.xxxx
|
|
.alias ones myconst.yyyy
|
|
.alias twos myconst2.wwww
|
|
.alias tooclose myconst.zzzz
|
|
.alias far myconst.wwww
|
|
.alias noHit myconst2.yyyy
|
|
.alias samplesRCP myconst3.xxxx
|
|
|
|
.alias diffuseID myconst.xxxx
|
|
.alias metallicID myconst.yyyy
|
|
.alias dielectricID myconst2.wwww
|
|
|
|
.consti sampleLoopParams(4, 0, 1, 0)
|
|
.consti bounceLoopParams(9, 0, 1, 0)
|
|
|
|
; (NUM_SPHERES, 0, 1, 0)
|
|
.ivec calcSphereLoopParams
|
|
|
|
.setb b0 true
|
|
.alias true b0
|
|
|
|
; xyz center (in world space)
|
|
; w radius (in world space)
|
|
.fvec spheres[25]
|
|
|
|
; material albedo (xyz)
|
|
; material id (w)
|
|
.fvec sphereColors[25]
|
|
|
|
; material emitted light (xyz)
|
|
; extra material params (w)
|
|
.fvec sphereLights[25]
|
|
|
|
; random numbers
|
|
.fvec rand[10]
|
|
.fvec sampleRand[5]
|
|
|
|
.in inOrigin v0
|
|
.in inLowerLeftCorner v1
|
|
.in inHorizontal v2
|
|
.in inVertical v3
|
|
.in inST v4
|
|
.in inPos v5
|
|
.in inUV v6
|
|
.in inRand v7
|
|
|
|
.out outPos position
|
|
.out outUV texcoord0
|
|
.out outColor color
|
|
|
|
.proc main
|
|
mov r15.xyz, zeros
|
|
|
|
for sampleLoopParams
|
|
; 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
|
|
|
|
; set initial color multiplier to (1, 1, 1)
|
|
mov r4.xyz, ones
|
|
|
|
; set initial color to (0, 0, 0)
|
|
mov r13.xyz, zeros
|
|
|
|
mov r14.xyz, sampleRand[aL].xyz
|
|
|
|
; calculate light bounces
|
|
for bounceLoopParams
|
|
; setup random numbers for this iteration
|
|
mov r11, rand[aL]
|
|
add r11.xyz, r11.xyz, r14.xyz
|
|
add r11.xyz, r11.xyz, inRand.xyz
|
|
dp3 r14.w, r11.xyz, r11.xyz
|
|
rsq r14.w, r14.w
|
|
mul r11.xyz, r11.xyz, r14.w
|
|
|
|
; reset max ray distance
|
|
mov r4.w, far
|
|
|
|
; set albedo to a large number for sphere hit check
|
|
mov r10.xyz, far
|
|
|
|
; for each sphere
|
|
for calcSphereLoopParams
|
|
; r3 = spheres[i]
|
|
mov r3, spheres[aL]
|
|
|
|
; do calculation
|
|
call calcSphere
|
|
.end
|
|
|
|
; 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
|
|
cmp noHit.xyz, lt, lt, r10.xyz
|
|
; not using breakc. it behaves weird.
|
|
jmpc cmp.x, labl
|
|
|
|
; multiply color by albedo
|
|
mul r4.xyz, r4.xyz, r10.xyz
|
|
|
|
; add emitted light
|
|
mad r13.xyz, r4.xyz, r12.xyz, r13.xyz
|
|
|
|
; set r1 to new ray origin
|
|
mov r1.xyz, r5.xyz
|
|
|
|
; set r2 to new ray direction
|
|
; try diffuse material
|
|
cmp diffuseID.w, eq, eq, r10.w
|
|
callc cmp.x, diffuse
|
|
jmpc cmp.x, materialFound
|
|
|
|
; try metallic material
|
|
cmp metallicID.w, eq, eq, r10.w
|
|
callc cmp.x, metallic
|
|
jmpc cmp.x, materialFound
|
|
|
|
; try dielectric material
|
|
cmp dielectricID.w, eq, eq, r10.w
|
|
callc cmp.x, dielectric
|
|
jmpc cmp.x, materialFound
|
|
|
|
; material doesn't reflect light
|
|
; used mostly for light-emitting objects
|
|
jmpu true, labl
|
|
|
|
materialFound:
|
|
nop
|
|
.end
|
|
|
|
labl:
|
|
|
|
; add final color to output
|
|
add r15.xyz, r13.xyz, r15.xyz
|
|
.end
|
|
|
|
; divide by sample count
|
|
mul outColor.xyz, samplesRCP, r15.xyz
|
|
|
|
; set alpha to 1
|
|
mov outColor.w, ones
|
|
|
|
mov outPos, inPos
|
|
mov outUV, inUV
|
|
|
|
end
|
|
.end
|
|
|
|
; -----------------------------
|
|
; Calculate Sphere Intersection
|
|
; -----------------------------
|
|
; Performs a ray-sphere intersection test.
|
|
;
|
|
; Inputs
|
|
; ------
|
|
; r1.xyz: ray origin
|
|
; r2.xyz: ray direction
|
|
; r3.xyz: sphere origin
|
|
; r3.w: sphere radius
|
|
; r4.w: min distance
|
|
; r11.xyz: random unit vector
|
|
; r11.w: random number
|
|
;
|
|
; Outputs
|
|
; -------
|
|
; r4.w: new min distance
|
|
; r10.xyz: albedo
|
|
; r10.w: material id
|
|
; r12.xyz: light emitted
|
|
; r12.w: extra material info
|
|
;
|
|
; Temporaries
|
|
; -----------
|
|
; r5.xyz: new origin
|
|
; r7.xyz: hit normal
|
|
; r7.w: ray is outside sphere (1) or inside sphere (0)
|
|
; 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
|
|
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
|
|
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
|
|
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 and material type
|
|
mov r10.xyzw, sphereColors[aL].xyzw
|
|
|
|
; set light emitted and extra material info
|
|
mov r12.xyzw, sphereLights[aL].xyzw
|
|
|
|
; early exit label
|
|
calcSphereExit:
|
|
nop
|
|
.end
|
|
|
|
; ---------
|
|
; Materials
|
|
; ---------
|
|
; Calculates the new ray direction for a given material.
|
|
;
|
|
; Inputs
|
|
; ------
|
|
; r1.xyz: ray origin
|
|
; r2.xyz: ray direction
|
|
; r3.xyz: sphere origin
|
|
; r3.w: sphere radius
|
|
; r4.w: min distance
|
|
; r11.xyz: random unit vector
|
|
; r11.w: random number
|
|
;
|
|
; Outputs
|
|
; -------
|
|
; r2.xyz: new ray direction
|
|
|
|
|
|
; Diffuse Material
|
|
; ----------------
|
|
|
|
.proc diffuse
|
|
add r2.xyz, r7.xyz, r11.xyz
|
|
.end
|
|
|
|
; Metallic Material
|
|
; -----------------
|
|
|
|
.proc metallic
|
|
dp3 r6.xyz, r2, r7
|
|
mul r6.xyz, twos, r6.xyz
|
|
mad r2.xyz, -r6.xyz, r7.xyz, r2.xyz
|
|
; add a bit of random "fuzziness" to the metal
|
|
mad r2.xyz, r11.xyz, r12.w, r2.xyz
|
|
.end
|
|
|
|
; Dielectric Material
|
|
; -------------------
|
|
|
|
.proc dielectric
|
|
; currently diffuse material, implement fr later
|
|
add r2.xyz, r7.xyz, r11.xyz
|
|
.end |