Skip to content

Conversation

@meisei4
Copy link

@meisei4 meisei4 commented Sep 30, 2025

I have decided to make a PR that I want to use as a way to track my progress in an attempt to revive some of this project again

Currently the goal is to add a simple performant per vertex color (no lighting) path for the renderers.

I have added a WIP per vertex color implementation (it works but seems slow for some reason) and am planning to continue to document the state of current behavior as well as testing techniques one can use with integrating with https://github.com/raylib4Consoles/raylib4PlayStation2 later on

I hope to be updating this along the way to document a clear path (including mistakes) towards how one might help in contributing to this project (as a way to try to help potentially revive it, and for myself to get experience with studying fixed function opengl and ps2 graphical intricacies

@meisei4
Copy link
Author

meisei4 commented Sep 30, 2025

Reminder 1: #26 (comment) There is a Linear Renderer WIP for reference discussion

Reminder 2: It will also be a goal to try studying an effective fallback method for when not using VU1 pipeline

…orking a bit better.

add potential TODOs, pushing to test on raylib cleanly from fork
… i hope to try to also integrate it more throughout the full pipeline, (I havent gotten to the alignment and stride part yet, but i need to study the .i macros i think to be able to understand that)
@rickgaiser
Copy link
Member

Thinking about this issue, does it make sense to even have per vertex colors without lighting?

Normally an entire object has 1 solid color OR 1 solid texture. The per-vertex colors are normally created when the vertex normals interact with light sources. For instance when using phong shading:
image

Besides OpenGL having the option, and the NeHe tutotial triangle using the option. Is there any real usecase for per-vertex colors without lighting? Still it would be nice to be as much compatible with OpenGL as possible, but I do wonder where the usecase is. Does raylib need it?

It will also be a goal to try studying an effective fallback method for when not using VU1 pipeline

The fallback I meant would be to use an existing VU1 pipeline with too many features, but using only a subset. I would expect this scenario to fallback to:

// linear, per-vertex color renderers
{
CRendererProps capabilities = {
PrimType : kPtsLinesStripsFans,
Lighting : 1,
NumDirLights : k3DirLights | k8DirLights,
NumPtLights : k1PtLight | k2PtLights | k8PtLights,
Texture : 1,
Specular : 1,
PerVtxMaterial : kDiffuse,
Clipping : kNonClipped | kClipped,
CullFace : 1,
TwoSidedLighting : 0,
ArrayAccess : kLinear
};
RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralPVDiff), mVsmSize(GeneralPVDiff), capabilities, no_reqs, 4, 3,
kInputStart, kInputBufSize - kInputStart,
"linear, pvc"));
}

Note the PerVtxMaterial : kDiffuse is what is currently needed to get per-vertex colors working. There is currently no PerVtxColors selection criteria.

The workaround is now something like:

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

But instead ps2gl should do this internally (without messing with the OpenGL state) upon detecting that per-vertex colors are needed.

I think as soon as any of the glColor* functions is called within glBegin/glEnd, the per-vertex color rendering should be enabled. But this can become difficult to implement if the glColor* function is called after the first glVertex* call. In that case the previous color would need to be added for all previously created vertices.

get experience with studying fixed function opengl

You might just get experience with vertex shaders as well ;). Since VU1 in ps2gl acts as one. It's also possible to create custom shaders with ps2gl, as the tricked_out example demonstrates. In theory it would be possible to use the VU1 as a GLSL vertex shader. GLSL didn't exist at the time the ps2 and ps2gl where developed. Perhaps it's possible to use some of the functions/techniques used by GLSL in ps2gl with the VU1.

For example (from https://learnopengl.com/getting-started/shaders):

layout (location = 0) in vec3 aPos; // the position variable has attribute position 0
  
out vec4 vertexColor; // specify a color output to the fragment shader

void main()
{
    gl_Position = vec4(aPos, 1.0); // see how we directly give a vec3 to vec4's constructor
    vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // set the output variable to a dark-red color
}

Currently the "fixed function" VU1 programs loop over a list of vertices, then inside the loop does exactly what this GLSL shader does: load input data from some offset location, generate output data from input data.

Some food for thought...

Nice to see someone working on ps2gl!

@meisei4
Copy link
Author

meisei4 commented Oct 2, 2025

Regarding the use case, I am currently working on a very simple graphics effect for opengl1.1 in raylib that is intended to teach people how data is carried through the most simple pipeline of vertices, perspective projection, and how per vertex data gets interpolated, colors being the most intuitive imo. It is almost just a way for me to try to introduce the simple pipeline first before diving into the lighting equations (mostly via these tutorial curriculums that eventually do get to lighting:


Here are some WIP images i have for what im trying to introduce as an official raylib opengl1.1 visualization of the above lectures, ontowards the color

World space, Clip planes, and Image space "intuition" (involves an ugly software renderer i wrote in rust. i hope to move to using this soon: raysan5/raylib#4832)

jugemu3.mp4

NDC space "intuition

jugemu jugemu2

I think there is something special about the whole affine nature of the barymetric coordinates that inspires intuition behind the fundamentals of how fixed function pipeline works (even if ps2 vector processing/VU1 eventually hints more at a opengl2.x/glsl style behavior? I will likely understand this more as time goes on)

So while the current linear, pvc VU1 shader does work as you mentioned (with enabling color material and lighting) it also then requires a repositioning of either the vertex normals and or the direction of the lights every frame in order to achieve a dot product of 1 to get a "true" unlit effect, I wrote a note about this behavior here: meisei4/pvc_no_lights/src/gmanager.cpp#L50 and it is demonstrated with how the behavior of the lit_pvc_box example works: meisei4/pvc_no_lights/examples/pvc_box/lit_pvc_box.cpp#L55 . NeHe would also have to do this, but i was hoping to also get NeHe to work without any of those calls via introducing a simple VU1 shader for no normals, no texcoords, no material/lighting:

Lesson05 behavior described above (fade to black due to normals/lighting direction)

lesson5.mp4

I think as soon as any of the glColor* functions is called within glBegin/glEnd, the per-vertex color rendering should be enabled. But this can become difficult to implement if the glColor* function is called after the first glVertex* call. In that case the previous color would need to be added for all previously created vertices.

I also noticed this yesterday! I think i have introduced a solution via simple backfill in(cant seem to get this to inline in this markdown cleanly like yours did):

https://github.com/meisei4/ps2gl/blob/e6c832eb231146297abaf6aee3902344fe55b4ea/src/immgmanager.cpp#L141-L158

It's also possible to create custom shaders with ps2gl, as the tricked_out example demonstrates. In theory it would be possible to use the VU1 as a GLSL vertex shader. GLSL didn't exist at the time the ps2 and ps2gl where developed. Perhaps it's possible to use some of the functions/techniques used by GLSL in ps2gl with the VU1.

That is interesting, i finally got all the examples to run yesterday after some more fixes to things i broke with the initial commits, and i think i will take a deeper look at the tricked_out examples since it seems most self contained. I might even move my no lights stuff to an example structure rather than having it in the renderermanager for less regression potential

TLDR; this is all still primarily as a practice problem for myself, so even if at the end of all this, the approach becomes what i now think i understand as your idea of a fallback: Account for such ps2gl state without requiring Lighting, Material, etc OpenGL calls - via internal ps2gl handling of the rendering context/VU1 data preparation (giftag? vif? im still learning...) i.e. for fallback cases we just pass EVERYTHING through to the ALL ENCOMPASSING render pass which will just target subsets of the features because it ultimately covers all renderer configurations in the first place ( <- I hope i understand this correctly now haha)

Also I think ps2gl is something that provides a great opportunity for not only studying the existing "solved" behavior of raylib for the example i mentioned at the top, but also being able to contribute to this WIP project as i learn. I also believe it has a lot of potential for raylib integration in the future.

@rickgaiser
Copy link
Member

Lesson05 behavior described above (fade to black due to normals/lighting direction)

How light interacts with material is configurable. I think in order to mimic "no lighting", you would need 100% non-directional light (ambient), and 0% directional light (diffuse and specular).

OpenGL's default for lighting seems to be 100% diffuse lighting.

Perhaps the following works?:

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); // <- NOTE that this is changed
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

// Change Light 0 to be 100% ambient light souce
const GLfloat color_on[] = {1, 1, 1, 1};
const GLfloat color_off[] = {0, 0, 0, 1};
glLightfv(GL_LIGHT0, GL_AMBIENT, color_on);
glLightfv(GL_LIGHT0, GL_DIFFUSE, color_off);
glLightfv(GL_LIGHT0, GL_SPECULAR, color_off);

@meisei4
Copy link
Author

meisei4 commented Oct 14, 2025

@rickgaiser apologies for the late follow up, I imagine that the ambient and diffuse could be worked in to allow for per vertex color, but currently i dont think its implemented at the geometry level yet: https://github.com/ps2dev/ps2gl/blob/master/src/immgmanager.cpp#L425

I have spent a lot of time this last week I think getting things to a position where I can run the following tests with a raylib front end and things are working how i am expecting for the cases where neither Material nor Lighting is enabled.

It is still a Work in progress, and i think with the new examples ive gotten working for me in the raylib front end here:

https://github.com/meisei4/raylib4PlayStation2/tree/main/samples/shapes/cube
https://github.com/meisei4/raylib4PlayStation2/tree/main/samples/models

these all require raylib4Consoles/raylib#12, and the cleaner branch i for pvc no lights that i will carry on from here (perhaps overwriting this PR in the future: https://github.com/meisei4/ps2gl/tree/proper_pvc_no_lights, There is still a lot of work to be done but i have made some progress i believe. it is a rather difficult repository to navigate, but i tried my best to make some things a little more clear. It is possible i made things a little more complex, but i hope that it would at least serve as a reference for things that were important for a lot of my study.

None of the existing examples have been altered other than for pvc no lights, and some commented stuff. the examples all work to me as expected

Thank you again for keeping this alive. I hope to come back in the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants