From 1c1e7483a727237cf5c61567624dbe430d60db2e Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 4 Nov 2025 12:57:27 -0600 Subject: [PATCH] matrix_cubesphere: use separate light shader --- src/light.fs.asm | 6 + src/light.fs.bin | Bin 0 -> 24 bytes src/light.vs.asm | 13 ++ src/light.vs.bin | Bin 0 -> 96 bytes src/matrix_cubesphere.cpp | 245 ++++++++++++++++++++++++++++--------- src/r500/indirect_buffer.c | 21 ++++ src/r500/indirect_buffer.h | 1 + 7 files changed, 226 insertions(+), 60 deletions(-) create mode 100644 src/light.fs.asm create mode 100644 src/light.fs.bin create mode 100644 src/light.vs.asm create mode 100644 src/light.vs.bin diff --git a/src/light.fs.asm b/src/light.fs.asm new file mode 100644 index 0000000..3b46092 --- /dev/null +++ b/src/light.fs.asm @@ -0,0 +1,6 @@ +-- temp[0] -- color + +OUT TEX_SEM_WAIT +src0.rgb = temp[0] : + out[0].a = MAX src0.1 src0.1 , + out[0].rgb = MAX src0.rgb src0.rgb ; diff --git a/src/light.fs.bin b/src/light.fs.bin new file mode 100644 index 0000000000000000000000000000000000000000..00e7fc9210752fef328d4d8767e969d593712317 GIT binary patch literal 24 ccmZQ=U}s=pVB%;1Vg)7_2Ihu?46HyA03u2P&;S4c literal 0 HcmV?d00001 diff --git a/src/light.vs.asm b/src/light.vs.asm new file mode 100644 index 0000000..6b052d5 --- /dev/null +++ b/src/light.vs.asm @@ -0,0 +1,13 @@ +-- input[0] -- position +-- input[1] -- color + +-- position clip space +temp[1].x = VE_DOT const[0].xyzw input[0].xyzw ; +temp[1].y = VE_DOT const[1].xyzw input[0].xyzw ; +temp[1].z = VE_DOT const[2].xyzw input[0].xyzw ; +temp[1].w = VE_DOT const[3].xyzw input[0].xyzw ; + +-- position (clip space) +out[0].xyzw = VE_ADD temp[1].xyzw const[0].0000 ; +-- color +out[1].xyzw = VE_ADD const[4].xyzw const[4].0000 ; diff --git a/src/light.vs.bin b/src/light.vs.bin new file mode 100644 index 0000000000000000000000000000000000000000..7306065a2f8cc6e04f14b59d8c4ce77dbd43ec51 GIT binary patch literal 96 zcmZQn5MW?pxX8c=!Vms4GAbxAD53Bj7@Sb}4Gc+0d}gK(3<^L#Q-ca46Hq_1(g%hn LAioL7ZvyfGbf_Aw literal 0 HcmV?d00001 diff --git a/src/matrix_cubesphere.cpp b/src/matrix_cubesphere.cpp index 49e9374..cd60745 100644 --- a/src/matrix_cubesphere.cpp +++ b/src/matrix_cubesphere.cpp @@ -28,17 +28,20 @@ #include "../model/model2.h" #include "../model/cubesphere.h" -#define CUBESPHERE_SHADER 0 -#define CLEAR_SHADER 1 +#define CLEAR_SHADER 0 +#define CUBESPHERE_SHADER 1 +#define LIGHT_SHADER 2 const char * vertex_shader_paths[] = { - "matrix_cubesphere.vs.bin", "clear.vs.bin", + "matrix_cubesphere.vs.bin", + "light.vs.bin", }; const int vertex_shader_paths_length = (sizeof (vertex_shader_paths)) / (sizeof (vertex_shader_paths[0])); const char * fragment_shader_paths[] = { - "matrix_cubesphere.fs.bin", "clear.fs.bin", + "matrix_cubesphere.fs.bin", + "light.fs.bin" }; const int fragment_shader_paths_length = (sizeof (fragment_shader_paths)) / (sizeof (fragment_shader_paths[0])); @@ -60,7 +63,7 @@ void _3d_clear(struct shaders& shaders) T0V(VAP_OUT_VTX_FMT_0 , VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1)); T0V(VAP_OUT_VTX_FMT_1 - , 0x0); + , 0); // @@ -107,10 +110,6 @@ void _3d_clear(struct shaders& shaders) , VAP_CNTL_STATUS__PVS_BYPASS(0) ); - T0V(VAP_VTX_SIZE - , VAP_VTX_SIZE__DWORDS_PER_VTX(2) - ); - ////////////////////////////////////////////////////////////////////////////// // GA POINT SIZE ////////////////////////////////////////////////////////////////////////////// @@ -124,17 +123,24 @@ void _3d_clear(struct shaders& shaders) // 3D_DRAW ////////////////////////////////////////////////////////////////////////////// + const int dwords_per_vtx = 2; + + T0V(VAP_VTX_SIZE + , VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx) + ); + const float center[] = { 800.0f, 600.0f, }; - T3(_3D_DRAW_IMMD_2, (1 + 2) - 1); + const int vertex_count = 1; + T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1); TU( VAP_VF_CNTL__PRIM_TYPE(1) // point list | VAP_VF_CNTL__PRIM_WALK(3) | VAP_VF_CNTL__INDEX_SIZE(0) | VAP_VF_CNTL__VTX_REUSE_DIS(0) | VAP_VF_CNTL__DUAL_INDEX_MODE(0) | VAP_VF_CNTL__USE_ALT_NUM_VERTS(0) - | VAP_VF_CNTL__NUM_VERTICES(1) + | VAP_VF_CNTL__NUM_VERTICES(vertex_count) ); for (int i = 0; i < 2; i++) { TF(center[i]); @@ -200,7 +206,13 @@ void _3d_cube_inner(mat4x4 trans, const int triangle_count = obj->triangle_count; const int vertex_count = triangle_count * 3; - T3(_3D_DRAW_IMMD_2, (1 + vertex_count * 8) - 1); + const int dwords_per_vtx = 8; + + T0V(VAP_VTX_SIZE + , VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx) + ); + + T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1); TU( VAP_VF_CNTL__PRIM_TYPE(4) | VAP_VF_CNTL__PRIM_WALK(3) | VAP_VF_CNTL__INDEX_SIZE(0) @@ -228,8 +240,152 @@ void _3d_cube_inner(mat4x4 trans, } } +void _3d_light_inner(mat4x4 trans) +{ + T0V(VAP_PVS_STATE_FLUSH_REG, 0x00000000); + + ////////////////////////////////////////////////////////////////////////////// + // VAP_PVS + ////////////////////////////////////////////////////////////////////////////// + + const vec4 color = {1, 1, 0, 1}; + + const float consts[] = { + // 0 + trans[0][0], trans[0][1], trans[0][2], trans[0][3], + trans[1][0], trans[1][1], trans[1][2], trans[1][3], + trans[2][0], trans[2][1], trans[2][2], trans[2][3], + trans[3][0], trans[3][1], trans[3][2], trans[3][3], + + // 4 + color[0], color[1], color[2], color[2], + }; + ib_vap_pvs_const_cntl(consts, (sizeof (consts))); + + ////////////////////////////////////////////////////////////////////////////// + // 3D_DRAW + ////////////////////////////////////////////////////////////////////////////// + + const model * model = &cubesphere_model; + const object * obj = model->object[0]; + const int triangle_count = obj->triangle_count; + const int vertex_count = triangle_count * 3; + + int dwords_per_vtx = 3; + + T0V(VAP_VTX_SIZE + , VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx) + ); + + T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1); + TU( VAP_VF_CNTL__PRIM_TYPE(4) + | VAP_VF_CNTL__PRIM_WALK(3) + | VAP_VF_CNTL__INDEX_SIZE(0) + | VAP_VF_CNTL__VTX_REUSE_DIS(0) + | VAP_VF_CNTL__DUAL_INDEX_MODE(0) + | VAP_VF_CNTL__USE_ALT_NUM_VERTS(0) + | VAP_VF_CNTL__NUM_VERTICES(vertex_count) + ); + + for (int i = 0; i < triangle_count; i++) { + for (int j = 0; j < 3; j++) { + vec3 p = model->position[obj->triangle[i][j].position]; + + TF(p.x); + TF(p.y); + TF(p.z); + } + } +} + +vec3 _3d_light(struct shaders& shaders, + const mat4x4& view_to_clip, + float theta) +{ + ib_rs_instructions(1); + + ////////////////////////////////////////////////////////////////////////////// + // VAP OUT + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_OUT_VTX_FMT_0 + , VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1)); + T0V(VAP_OUT_VTX_FMT_1 + , VAP_OUT_VTX_FMT_1__TEX_0_COMP_CNT(4)); + + // + + ib_zbuffer(ZBUFFER_RELOC_INDEX, 1); // less + + ib_texture__0(); + + ib_vap_stream_cntl__3(); + + // shaders + T0V(US_PIXSIZE + , US_PIXSIZE__PIX_SIZE(1) + ); + ib_ga_us(&shaders.fragment[LIGHT_SHADER]); + ib_vap_pvs(&shaders.vertex[LIGHT_SHADER]); + + ////////////////////////////////////////////////////////////////////////////// + // VAP + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_CLIP_CNTL + , VAP_CLIP_CNTL__PS_UCP_MODE(3) + ); + + T0V(VAP_VTE_CNTL + , VAP_VTE_CNTL__VPORT_X_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_X_OFFSET_ENA(1) + | VAP_VTE_CNTL__VPORT_Y_SCALE_ENA(1) + | VAP_VTE_CNTL__VPORT_Y_OFFSET_ENA(1) + | VAP_VTE_CNTL__VPORT_Z_SCALE_ENA(0) + | VAP_VTE_CNTL__VPORT_Z_OFFSET_ENA(0) + | VAP_VTE_CNTL__VTX_XY_FMT(0) // enable W division + | VAP_VTE_CNTL__VTX_Z_FMT(1) // disable W division + | VAP_VTE_CNTL__VTX_W0_FMT(1) + | VAP_VTE_CNTL__SERIAL_PROC_ENA(0) + ); + + T0V(VAP_CNTL_STATUS + , VAP_CNTL_STATUS__PVS_BYPASS(0) + ); + + ////////////////////////////////////////////////////////////////////////////// + // VAP INDEX + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_INDEX_OFFSET, 0); + + T0V(VAP_VF_MAX_VTX_INDX + , VAP_VF_MAX_VTX_INDX__MAX_INDX(0) + ); + T0V(VAP_VF_MIN_VTX_INDX + , VAP_VF_MIN_VTX_INDX__MIN_INDX(0) + ); + + // light + mat4x4 t1 = translate(vec3(1, 0, 0)); + mat4x4 s = scale(0.1f); + mat4x4 rz = rotate_y(theta * 2.f); + + mat4x4 world_trans = rz * t1 * s; + + mat4x4 trans = view_to_clip * world_trans; + + _3d_light_inner(trans); + + vec3 light_pos = world_trans * light_pos; + + return light_pos; +} + void _3d_cube(struct shaders& shaders, - float theta) + const mat4x4& view_to_clip, + float theta, + const vec3& light_pos) { ib_rs_instructions(4); @@ -264,10 +420,6 @@ void _3d_cube(struct shaders& shaders, // VAP ////////////////////////////////////////////////////////////////////////////// - T0V(VAP_VTX_SIZE - , VAP_VTX_SIZE__DWORDS_PER_VTX(8) - ); - T0V(VAP_CLIP_CNTL , VAP_CLIP_CNTL__PS_UCP_MODE(3) ); @@ -306,51 +458,16 @@ void _3d_cube(struct shaders& shaders, // matrix ////////////////////////////////////////////////////////////////////////////// - float theta1 = theta; - float theta2 = theta; + // cube + mat4x4 rx = rotate_x(1 * theta * 0.5f); + mat4x4 ry = rotate_y(0 * theta * 0.8f + 1.4f); + mat4x4 s = scale(0.9f); - mat4x4 aspect = scale(vec3(3.0f/4.0f, 1, 1)); + mat4x4 world_trans = rx * ry * s; - mat4x4 p = perspective(0.01f, 5.0f, - 0.001f, 0.999f, - 0.5f, 2.0f); + mat4x4 trans = view_to_clip * world_trans; - vec4 light_pos = vec4(0, 0, 0, 1.0f); - - // light - if (1) { - mat4x4 t = translate(vec3(0, 0, 3)); - mat4x4 t1 = translate(vec3(1, 0, 0)); - mat4x4 s = scale(0.1f); - mat4x4 rz = rotate_y(theta * 2.f); - - mat4x4 world_trans = rz * t1 * s; - - //mat3x3 normal_trans = transpose(inverse(submatrix(world_trans, 3, 3))); - - mat4x4 trans = aspect * p * t * world_trans; - - light_pos = world_trans * light_pos; - - _3d_cube_inner(trans, world_trans, light_pos); - } - - - // object - if (1) { - mat4x4 t = translate(vec3(0, 0, 3)); - mat4x4 rx = rotate_x(1 * theta1 * 0.5f); - mat4x4 ry = rotate_y(0 * theta2 * 0.8f + 1.4f); - mat4x4 s = scale(0.9f); - - mat4x4 world_trans = rx * ry * s; - - //mat3x3 normal_trans = transpose(inverse(submatrix(world_trans, 3, 3))); - - mat4x4 trans = aspect * p * t * world_trans; - - _3d_cube_inner(trans, world_trans, light_pos); - } + _3d_cube_inner(trans, world_trans, light_pos); } int indirect_buffer(shaders& shaders, @@ -387,8 +504,16 @@ int indirect_buffer(shaders& shaders, // DRAW ////////////////////////////////////////////////////////////////////////////// + mat4x4 aspect = scale(vec3(3.0f/4.0f, 1, 1)); + mat4x4 p = perspective(0.01f, 5.0f, + 0.001f, 0.999f, + 0.5f, 2.0f); + mat4x4 t = translate(vec3(0, 0, 3)); + mat4x4 view_to_clip = aspect * p * t; + _3d_clear(shaders); - _3d_cube(shaders, theta); + vec3 light_pos = _3d_light(shaders, view_to_clip, theta); + _3d_cube(shaders, view_to_clip, theta, light_pos); ////////////////////////////////////////////////////////////////////////////// // padding diff --git a/src/r500/indirect_buffer.c b/src/r500/indirect_buffer.c index f691a78..9cdd37a 100644 --- a/src/r500/indirect_buffer.c +++ b/src/r500/indirect_buffer.c @@ -650,6 +650,27 @@ void ib_vap_stream_cntl__2() ); } +void ib_vap_stream_cntl__3() +{ + ////////////////////////////////////////////////////////////////////////////// + // VAP_PROG_STREAM_CNTL + ////////////////////////////////////////////////////////////////////////////// + + T0V(VAP_PROG_STREAM_CNTL_0 + , VAP_PROG_STREAM_CNTL__DATA_TYPE_0__FLOAT_3 + | VAP_PROG_STREAM_CNTL__SKIP_DWORDS_0(0) + | VAP_PROG_STREAM_CNTL__DST_VEC_LOC_0(0) + | VAP_PROG_STREAM_CNTL__LAST_VEC_0(1) + ); + T0V(VAP_PROG_STREAM_CNTL_EXT_0 + , VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_X_0__SELECT_X + | VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_Y_0__SELECT_Y + | VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_Z_0__SELECT_Z + | VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_W_0__SELECT_FP_ONE + | VAP_PROG_STREAM_CNTL_EXT__WRITE_ENA_0(0b1111) + ); +} + void ib_vap_stream_cntl__323() { ////////////////////////////////////////////////////////////////////////////// diff --git a/src/r500/indirect_buffer.h b/src/r500/indirect_buffer.h index 44c68c1..87db0c7 100644 --- a/src/r500/indirect_buffer.h +++ b/src/r500/indirect_buffer.h @@ -64,6 +64,7 @@ void ib_vap_pvs(struct shader_offset * offset); void ib_ga_us(struct shader_offset * offset); void ib_vap_pvs_const_cntl(const float * consts, int size); void ib_vap_stream_cntl__2(); +void ib_vap_stream_cntl__3(); void ib_vap_stream_cntl__323(); #ifdef __cplusplus