diff --git a/source/main.cpp b/source/main.cpp index 577d8cc..2f952df 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -61,8 +61,9 @@ private: static DVLB_s* vshaderDVLB; static shaderProgram_s program; static s8 spheresUniformLocation; +static s8 sphereColorsUniformLocation; -static constexpr unsigned int VERTEX_COUNT_W = 150; +static constexpr unsigned int VERTEX_COUNT_W = 90; static constexpr unsigned int VERTEX_COUNT_H = 10 * VERTEX_COUNT_W / 6; static constexpr unsigned int VERTEX_COUNT = VERTEX_COUNT_W * VERTEX_COUNT_H; @@ -144,6 +145,7 @@ static void sceneInit() C3D_BindProgram(&program); spheresUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "spheres"); + sphereColorsUniformLocation = shaderInstanceGetUniformLocation(program.vertexShader, "sphereColors"); C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); @@ -168,10 +170,16 @@ static void sceneInit() C3D_TexEnvFunc(env, C3D_RGB, GPU_INTERPOLATE); C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); - C3D_FVec* spheres = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, spheresUniformLocation, 3); + constexpr u16 NUM_SPHERES = 3; + C3D_FVec* spheres = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, spheresUniformLocation, NUM_SPHERES); spheres[0] = FVec4_New(0.0f, -100.5f, -1.0f, 100.0f); spheres[1] = FVec4_New(0.5f, 0.0f, -1.0f, 0.5f); spheres[2] = FVec4_New(-0.5f, 0.0f, -1.0f, 0.5f); + + C3D_FVec* sphereColors = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, sphereColorsUniformLocation, NUM_SPHERES); + sphereColors[0] = FVec3_New(0.7f, 0.3f, 0.3f); + sphereColors[1] = FVec3_New(0.3f, 0.7f, 0.3f); + sphereColors[2] = FVec3_New(0.3f, 0.3f, 0.7f); } static void sceneRender() @@ -226,7 +234,7 @@ int main(int argc, char* argv[]) sceneInit(); - C3D_FVec lookFrom = FVec3_New(0, 1.25f, 0); + C3D_FVec lookFrom = FVec3_New(0, 0.6125f, 0); C3D_FVec lookAt = FVec3_New(0, 0, -1.0f); C3D_FVec vup = FVec3_New(0, 1.0f, 0); bool dirty = false; diff --git a/source/vshader.v.pica b/source/vshader.v.pica index 7d38eb9..039e67e 100644 --- a/source/vshader.v.pica +++ b/source/vshader.v.pica @@ -1,14 +1,13 @@ .constf myconst(0.0, 1.0, 0.01, 1000.0) -.constf myconst2(0.5, 0.0, 0.0, 0.0) +.constf myconst2(0.5, 999.0, 0.0, 0.0) .alias zeros myconst.xxxx +.alias halfs myconst2.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 +.alias noHit myconst2.yyyy -.consti bounceLoopParams(0, 0, 1, 0) +.consti bounceLoopParams(4, 0, 1, 0) .consti calcSphereLoopParams(2, 0, 1, 0) .setb b0 true @@ -18,6 +17,9 @@ ; w radius (in world space) .fvec spheres[3] +; material albedo +.fvec sphereColors[3] + .in inOrigin v0 .in inLowerLeftCorner v1 .in inHorizontal v2 @@ -46,10 +48,17 @@ mad r2.xyz, inHorizontal, r3.x, r2.xyz mad r2.xyz, inVertical, r3.y, r2.xyz + ; set initial color to (1, 1, 1) + ; as lights are not implemented yet + mov r4.xyz, ones + ; calculate light bounces for bounceLoopParams - ; r4 = (0, 0, 0, far) - mov r4, myconst.xxxw + ; 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 @@ -138,18 +147,32 @@ 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 + ; multiply color by albedo + mov r10.xyz, sphereColors[aL].xyz ; early exit label calcSphereExit: nop ; done with calculation .end + + ; check if noHit > albedo + cmp noHit.xyz, le, le, r10.xyz + breakc cmp.x + jmpc cmp.x, noHitLabel + + ; multiply color by albedo + mul r4.xyz, r4.xyz, r10.xyz + + ; set r1 to new ray origin + add r1.xyz, r5.xyz, r7.xyz + + ; set r2 to new ray direction + mov r2.xyz, r7.xyz .end + noHitLabel: + ; copy final color to output mov outColor.xyz, r4.xyz ; set alpha to 1 @@ -160,23 +183,24 @@ ; Inputs ; ------ -; r1.xyz: ray origin -; r2.xyz: ray direction -; r3.xyzw: sphere info -; r4.w: min distance +; r1.xyz: ray origin +; r2.xyz: ray direction +; r3.xyz: sphere origin +; r3.w: sphere radius +; r4.w: min distance ; ; Outputs ; ------- -; r4.w: new min distance -; r4.xyz: new color +; r4.w: new min distance +; r10.xyz: albedo ; ; Temporaries ; ----------- -; r5.xyz: new origin -; r6.xyz: new direction -; r7.xyz: hit normal -; r8 -; r9 +; r5.xyz: new origin +; r6.xyz: new direction +; r7.xyz: hit normal +; r8.xyzw: used for calculations +; r9.xyzw: used for calculations ; ;.proc calcSphere ;.end \ No newline at end of file