mirror of
https://git.shylie.info/shylie/rt3DS.git
synced 2024-12-22 14:40:04 +00:00
Improved random sample quality
This commit is contained in:
parent
dceb378111
commit
3b64e9e8aa
@ -18,6 +18,7 @@ struct vertex
|
||||
float st[2];
|
||||
float coords[3];
|
||||
float uv[2];
|
||||
float rand[3];
|
||||
};
|
||||
|
||||
static DVLB_s* vshaderDVLB;
|
||||
@ -26,9 +27,10 @@ static s8 spheresUniformLocation;
|
||||
static s8 sphereColorsUniformLocation;
|
||||
static s8 sphereLightsUniformLocation;
|
||||
static s8 randUniformLocation;
|
||||
static s8 sampleRandUniformLocation;
|
||||
static s8 calcSphereLoopParamsUniformLocation;
|
||||
|
||||
static constexpr unsigned int VERTEX_COUNT_W = 150;
|
||||
static constexpr unsigned int VERTEX_COUNT_W = 50;
|
||||
static constexpr unsigned int VERTEX_COUNT_H = 10 * VERTEX_COUNT_W / 6;
|
||||
static constexpr unsigned int VERTEX_COUNT = VERTEX_COUNT_W * VERTEX_COUNT_H;
|
||||
static constexpr unsigned int INDICES_COUNT = (VERTEX_COUNT * 2 + VERTEX_COUNT_H * 2);
|
||||
@ -135,6 +137,11 @@ static void setupVertices()
|
||||
|
||||
v.uv[0] = s * (240.0f / 256.0f);
|
||||
v.uv[1] = t * (400.0f / 512.0f);
|
||||
|
||||
const C3D_FVec r = randvec();
|
||||
v.rand[0] = r.x;
|
||||
v.rand[1] = r.y;
|
||||
v.rand[2] = r.z;
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,12 +150,19 @@ static void setupVertices()
|
||||
|
||||
static void setupRandom()
|
||||
{
|
||||
constexpr int NUM_RAND = 15; // needs to be the same as rand array length in vshader.v.pica
|
||||
constexpr int NUM_RAND = 10; // needs to be the same as rand array length in vshader.v.pica
|
||||
C3D_FVec* randPtr = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, randUniformLocation, NUM_RAND);
|
||||
for (int i = 0; i < NUM_RAND; i++)
|
||||
{
|
||||
randPtr[i] = randvec();
|
||||
}
|
||||
|
||||
constexpr int NUM_SAMPLE_RAND = 2;
|
||||
C3D_FVec* sampleRandPtr = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, sampleRandUniformLocation, NUM_SAMPLE_RAND);
|
||||
for (int i = 0; i < NUM_SAMPLE_RAND; i++)
|
||||
{
|
||||
sampleRandPtr[i] = randvec();
|
||||
}
|
||||
}
|
||||
|
||||
static void sceneInit()
|
||||
@ -178,6 +192,7 @@ static void sceneInit()
|
||||
sphereColorsUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "sphereColors");
|
||||
sphereLightsUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "sphereLights");
|
||||
randUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "rand");
|
||||
sampleRandUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "sampleRand");
|
||||
calcSphereLoopParamsUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "calcSphereLoopParams");
|
||||
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
@ -189,13 +204,14 @@ static void sceneInit()
|
||||
AttrInfo_AddLoader(attrInfo, 4, GPU_FLOAT, 2);
|
||||
AttrInfo_AddLoader(attrInfo, 5, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 6, GPU_FLOAT, 2);
|
||||
AttrInfo_AddLoader(attrInfo, 7, GPU_FLOAT, 3);
|
||||
|
||||
iboData = linearAlloc(sizeof(vertexIndices));
|
||||
memcpy(iboData, vertexIndices, sizeof(vertexIndices));
|
||||
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vboData, sizeof(vertex), 3, 0x654);
|
||||
BufInfo_Add(bufInfo, vboData, sizeof(vertex), 4, 0x7654);
|
||||
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvInit(env);
|
||||
@ -203,7 +219,7 @@ static void sceneInit()
|
||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_INTERPOLATE);
|
||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE);
|
||||
|
||||
constexpr u16 NUM_SPHERES = 4;
|
||||
constexpr u16 NUM_SPHERES = 5;
|
||||
C3D_IVUnifSet(GPU_VERTEX_SHADER, calcSphereLoopParamsUniformLocation, NUM_SPHERES - 1, 0, 1, 0);
|
||||
|
||||
C3D_FVec* spheres = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, spheresUniformLocation, NUM_SPHERES);
|
||||
@ -211,18 +227,21 @@ static void sceneInit()
|
||||
spheres[1] = FVec4_New(0.6f, 0.0f, 0.0f, 0.5f);
|
||||
spheres[2] = FVec4_New(-0.6f, 0.0f, 0.0f, 0.5f);
|
||||
spheres[3] = FVec4_New(0.0f, 10.0f, 0.0f, 9.0f);
|
||||
spheres[4] = FVec4_New(0.0f, 0.4f, 0.0f, 0.2f);
|
||||
|
||||
C3D_FVec* sphereColors = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, sphereColorsUniformLocation, NUM_SPHERES);
|
||||
sphereColors[0] = FVec4_New(0.9f, 0.3f, 0.3f, 0);
|
||||
sphereColors[1] = FVec4_New(0.3f, 0.9f, 0.3f, 1);
|
||||
sphereColors[2] = FVec4_New(0.3f, 0.3f, 0.9f, 0);
|
||||
sphereColors[3] = FVec4_New(1.0f, 1.0f, 1.0f, -1);
|
||||
sphereColors[4] = FVec4_New(0.8f, 0.6f, 0.1f, 2);
|
||||
|
||||
C3D_FVec* sphereLights = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, sphereLightsUniformLocation, NUM_SPHERES);
|
||||
sphereLights[0] = FVec4_New(0.0f, 0.0f, 0.0f, 0);
|
||||
sphereLights[1] = FVec4_New(0.0f, 0.0f, 0.0f, 0.2f);
|
||||
sphereLights[2] = FVec4_New(0.0f, 0.0f, 0.0f, 0);
|
||||
sphereLights[3] = FVec4_New(0.5f, 0.5f, 0.5f, 0);
|
||||
sphereLights[3] = FVec4_New(2.5f, 2.5f, 2.5f, 0);
|
||||
sphereLights[4] = FVec4_New(0.0f, 0.0f, 0.0f, 0);
|
||||
}
|
||||
|
||||
static void sceneRender()
|
||||
@ -276,9 +295,9 @@ int main(int argc, char* argv[])
|
||||
|
||||
sceneInit();
|
||||
|
||||
C3D_FVec lookFrom = FVec3_New(0, 0.0f, 1.0f);
|
||||
C3D_FVec lookAt = FVec3_New(0, 0, 0.0f);
|
||||
C3D_FVec vup = FVec3_New(0, 1.0f, 0);
|
||||
C3D_FVec lookFrom = FVec3_New(0.0f, 0.0f, 1.0f);
|
||||
C3D_FVec lookAt = FVec3_New(0.0f, 0.0f, 0.0f);
|
||||
C3D_FVec vup = FVec3_New(0.0f, 1.0f, 0.0f);
|
||||
bool dirty = true;
|
||||
|
||||
unsigned int frameNum = 0;
|
||||
@ -346,10 +365,10 @@ int main(int argc, char* argv[])
|
||||
setupVertices();
|
||||
setupRandom();
|
||||
|
||||
C3D_TexEnvColor(C3D_GetTexEnv(0), getFrameNumColor(frameNum));
|
||||
|
||||
if (frameNum < 96 && C3D_FrameBegin(C3D_FRAME_SYNCDRAW))
|
||||
if (frameNum < 32 && C3D_FrameBegin(C3D_FRAME_SYNCDRAW))
|
||||
{
|
||||
C3D_TexEnvColor(C3D_GetTexEnv(0), getFrameNumColor(frameNum));
|
||||
|
||||
setupCam(lookFrom, lookAt, vup);
|
||||
C3D_TexBind(0, &prevFrame);
|
||||
C3D_RenderTargetClear(target, C3D_CLEAR_ALL, 0, 0);
|
||||
@ -366,6 +385,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
frameNum++;
|
||||
}
|
||||
|
||||
C3D_TexEnvColor(C3D_GetTexEnv(0), 0);
|
||||
}
|
||||
|
||||
sceneExit();
|
||||
|
@ -1,5 +1,6 @@
|
||||
.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
|
||||
@ -7,10 +8,14 @@
|
||||
.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 bounceLoopParams(14, 0, 1, 0)
|
||||
.consti sampleLoopParams(4, 0, 1, 0)
|
||||
.consti bounceLoopParams(9, 0, 1, 0)
|
||||
|
||||
; (NUM_SPHERES, 0, 1, 0)
|
||||
.ivec calcSphereLoopParams
|
||||
@ -31,7 +36,8 @@
|
||||
.fvec sphereLights[25]
|
||||
|
||||
; random numbers
|
||||
.fvec rand[15]
|
||||
.fvec rand[10]
|
||||
.fvec sampleRand[5]
|
||||
|
||||
.in inOrigin v0
|
||||
.in inLowerLeftCorner v1
|
||||
@ -40,89 +46,109 @@
|
||||
.in inST v4
|
||||
.in inPos v5
|
||||
.in inUV v6
|
||||
.in inRand v7
|
||||
|
||||
.out outPos position
|
||||
.out outUV texcoord0
|
||||
.out outColor color
|
||||
|
||||
.proc main
|
||||
; r1 = inOrigin
|
||||
mov r1, inOrigin
|
||||
mov r15.xyz, zeros
|
||||
|
||||
; 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
|
||||
for sampleLoopParams
|
||||
; r1 = inOrigin
|
||||
mov r1, inOrigin
|
||||
|
||||
; set initial color multiplier to (1, 1, 1)
|
||||
mov r4.xyz, ones
|
||||
; 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 to (0, 0, 0)
|
||||
mov r13.xyz, zeros
|
||||
; set initial color multiplier to (1, 1, 1)
|
||||
mov r4.xyz, ones
|
||||
|
||||
; calculate light bounces
|
||||
for bounceLoopParams
|
||||
; setup random numbers for this iteration
|
||||
mov r11, rand[aL]
|
||||
; set initial color to (0, 0, 0)
|
||||
mov r13.xyz, zeros
|
||||
|
||||
; reset max ray distance
|
||||
mov r4.w, far
|
||||
mov r14.xyz, sampleRand[aL].xyz
|
||||
|
||||
; set albedo to a large number for sphere hit check
|
||||
mov r10.xyz, far
|
||||
; 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
|
||||
|
||||
; for each sphere
|
||||
for calcSphereLoopParams
|
||||
; r3 = spheres[i]
|
||||
mov r3, spheres[aL]
|
||||
; 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
|
||||
; 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
|
||||
|
||||
; 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
|
||||
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
|
||||
|
||||
; material doesn't reflect light
|
||||
; used mostly for light-emitting objects
|
||||
jmpu true, labl
|
||||
|
||||
materialFound:
|
||||
nop
|
||||
; add final color to output
|
||||
add r15.xyz, r13.xyz, r15.xyz
|
||||
.end
|
||||
|
||||
labl:
|
||||
|
||||
; copy final color to output
|
||||
mov outColor.xyz, r13.xyz
|
||||
; divide by sample count
|
||||
mul outColor.xyz, samplesRCP, r15.xyz
|
||||
|
||||
; set alpha to 1
|
||||
mov outColor.w, ones
|
||||
@ -133,6 +159,7 @@
|
||||
end
|
||||
.end
|
||||
|
||||
; -----------------------------
|
||||
; Calculate Sphere Intersection
|
||||
; -----------------------------
|
||||
; Performs a ray-sphere intersection test.
|
||||
@ -159,6 +186,7 @@
|
||||
; -----------
|
||||
; 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
|
||||
|
||||
@ -253,8 +281,9 @@
|
||||
nop
|
||||
.end
|
||||
|
||||
; All Materials
|
||||
; -------------
|
||||
; ---------
|
||||
; Materials
|
||||
; ---------
|
||||
; Calculates the new ray direction for a given material.
|
||||
;
|
||||
; Inputs
|
||||
@ -274,16 +303,26 @@
|
||||
|
||||
; 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
|
Loading…
Reference in New Issue
Block a user