rt3DS/source/vshader.v.pica

328 lines
6.5 KiB
Plaintext
Raw Normal View History

2023-04-15 15:48:20 +00:00
.constf myconst(0.0, 1.0, 0.001, 1000.0)
2024-02-19 00:12:44 +00:00
.constf myconst2(0.5, 999.0, 1.1, 2.0)
2024-04-28 12:27:25 +00:00
.constf myconst3(0.5, 0.0, 0.0, 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
2024-02-19 00:12:44 +00:00
.alias twos myconst2.wwww
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
2024-04-28 12:27:25 +00:00
.alias samplesRCP myconst3.xxxx
.alias diffuseID myconst.xxxx
.alias metallicID myconst.yyyy
2024-04-28 12:27:25 +00:00
.alias dielectricID myconst2.wwww
2023-04-08 16:51:11 +00:00
2024-04-28 12:27:25 +00:00
.consti sampleLoopParams(4, 0, 1, 0)
.consti bounceLoopParams(9, 0, 1, 0)
; (NUM_SPHERES, 0, 1, 0)
.ivec calcSphereLoopParams
2023-04-08 16:51:11 +00:00
.setb b0 true
.alias true b0
; xyz center (in world space)
; w radius (in world space)
.fvec spheres[25]
2023-04-08 16:51:11 +00:00
; material albedo (xyz)
; material id (w)
.fvec sphereColors[25]
2023-04-11 23:54:15 +00:00
; material emitted light (xyz)
; extra material params (w)
.fvec sphereLights[25]
2023-04-10 14:12:45 +00:00
2023-04-10 19:45:27 +00:00
; random numbers
2024-04-28 12:27:25 +00:00
.fvec rand[10]
.fvec sampleRand[5]
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
2024-04-28 12:27:25 +00:00
.in inRand v7
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
2024-04-28 12:27:25 +00:00
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]
2023-04-08 16:51:11 +00:00
2024-04-28 12:27:25 +00:00
; 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
2023-04-08 16:51:11 +00:00
.end
2023-04-10 14:12:45 +00:00
2024-04-28 12:27:25 +00:00
labl:
2023-04-08 16:51:11 +00:00
2024-04-28 12:27:25 +00:00
; add final color to output
add r15.xyz, r13.xyz, r15.xyz
.end
2023-04-15 15:48:20 +00:00
2024-04-28 12:27:25 +00:00
; divide by sample count
mul outColor.xyz, samplesRCP, r15.xyz
2023-04-11 23:54:15 +00:00
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
2024-04-28 12:27:25 +00:00
; -----------------------------
2023-04-10 19:45:27 +00:00
; Calculate Sphere Intersection
; -----------------------------
; Performs a ray-sphere intersection test.
2023-04-10 19:45:27 +00:00
;
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
; r10.w: material id
2023-04-11 23:54:15 +00:00
; r12.xyz: light emitted
; r12.w: extra material info
2023-04-08 16:51:11 +00:00
;
; Temporaries
; -----------
2023-04-10 19:45:27 +00:00
; r5.xyz: new origin
; r7.xyz: hit normal
2024-04-28 12:27:25 +00:00
; r7.w: ray is outside sphere (1) or inside sphere (0)
2023-04-10 19:45:27 +00:00
; 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 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
2024-04-28 12:27:25 +00:00
; ---------
; 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
; ----------------
2024-04-28 12:27:25 +00:00
.proc diffuse
add r2.xyz, r7.xyz, r11.xyz
2024-02-19 00:12:44 +00:00
.end
; Metallic Material
; -----------------
2024-04-28 12:27:25 +00:00
2024-02-19 00:12:44 +00:00
.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
2024-04-28 12:27:25 +00:00
.end
; Dielectric Material
; -------------------
.proc dielectric
; currently diffuse material, implement fr later
add r2.xyz, r7.xyz, r11.xyz
.end