-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modularize PBRLighting.frag #2191
base: master
Are you sure you want to change the base?
Conversation
Addresses this issue: jMonkeyEngine#2122 To re-summarize: This PR extracts all of the texture reads and basematParam assignment into a .glslib file (currently named PBRLightingParamReads.glsllib) And then it also extracts all of the lighting calculation into a .glslib file (currently named PBRLighting.glsllib) I also fixed alot of formatting and indentation mistakes, and overall reorganized the shader. This should now make it as easy as possible for jme devs to fork PBRLighting to make changes, and they will no longer have to update the lighting or texReads to stay on par with master, as all future changes will all be in the glsllibs. This also reduces the chances that a lesser-skilled shader dev (or even skilled shader devs on a bad day) mistakenly mess up the lighting calculations when forking the shader. Any feedback and review is greatly appreciated.
Once approved, I will also update the PBRTerrain shaders to create 2 new glsllibs titled "AdvancedPBRTerrainParamReads.glsllibs" and "PBRTerrainParamReads.glsllib" so that those will be modularized as well. Both of those shaders will also be able to use PBRLighting.glslib for the final lighting calculation, ensuring that PBRLighting and PBRTerrain shaders always share the same lighting code and this will greatly reduce code redundancy. It will also make shader development waaay easier for devs like myself who have 10 forks of PBRLighting all with minor differences. |
I have also placed both of the glslllibs in Common/ShaderLib/ for now... However I am not sure if that is the right place for these, as there is also a PBRLighting.glslib that contains the deeper pbr lighting equations (which are referenced and used in the new PBRLighting.glsllib) and the two could be easily confused. So maybe we should make a new shaderLib directory for modular PBR glsllibs? I'm open to hearing others input on this (for now I don't have the correct reference to the glsllib in PbrLighting.frag, but I will update the import to be correct once a final location has been determined for these new glsllibs) I have also removed some ifDefs aroungs things like tbnMat's calculation, so that it will be calculated even if there is no normal map (I also still need to change PBRLighting.vert to remove ifDefs around the passing of the tbnMat and vViewDir varyings) . This will be important so that forks of the shader that do things like splatting normal maps will still be easy to make even if the original model does not have a normal map, without having to go in and change any of these .glsllibs |
Forgot about spec-gloss pipeline
Added spec-gloss vars
add inouts for specularColor and glossiness to account for specGloss pipeline
Just made one more set of changes because I forgot about the spec-gloss pipeilne. I typically only use the metallic pipeline so I overlooked spec gloss yesterday, but I fixed it so both will work now. I've extensively tested my changes with models that use the metallic pipeline, however I have very few spec-gloss models so I didn't get to test that as thoroughly. I've also updated the vert and j3md files, so now this PR should be ready for a full-scale review. (The only reamining error in the code that I am aware of is the incorrect reference to importing PBRLighting.glsllib and PBRLightingParamReads.glsllib, since I am still unsure of where the best place to place these 2 new glslibs is) |
removed ifDef checks around some things (like tangents) that could still be used by other glslibs even if the shader doesn't have a normal map.
add matDefs for indoor sunlight exposure and debugging final output. These features were previously not in PBRLighting.frag, but they are in PBRTerrain.frag which will eventually share the same glslib for lighting (after doing texture reads), so they both should be consistent.
remove unnecessary assignment of norm, as normal will already = norm if a normalMap is not assigned, and norm isn't used anywhere else in this glslib so no need to pass it in
Hi @yaRnMcDonuts , 10X :) |
There shouldn't be any compatibility issues for any existent forks that are already out there. I made sure to not remove any params or defines from the shader, and only added 3 defines that will not have any effect if left undefined. So all files (the .j3md, .frag, and .vert) on master should still be compatible with forked versions of each other.
If any jme devs out there don't want to adapt these changes to their own existing forks of PBRLighting.frag, then they should still be able to keep all of the logic in one big file and manually keep it up to date with master/stable without any newly added trouble. However, the next time someone makes a PR to add a new feature to the new PBRLighting .glsllibs on master, (such as the recent SpecularAA or AOStrength PRs) then, at that point, I'd highly recommend everyone with forks of PBRLighting adapt the changes and have their forks use the new glsllibs, so then they will never have to worry about updating their forks to stay on par with master/stable ever again in the future. But if anyone still chooses not to adapt these changes and doesn't mind manually adding new features to their own custom version of PBRLighting.frag everytime master/stable has an update, then they are still free to keep on doing things the old way without any issues. |
How about renaming the file |
…eader.glsllib renamed to PBRLightingParamsReader.glsllib
That sounds like a good name to me, I updated the PR to rename it to PBRLightingParamsReader.glsllib and also updated the imports in PBRLighting.frag to reflect the change. I also fixed the import path to point to Common/ShaderLib/ in jme-core, so unless anyone objects to having these 2 new .glsllibs in the Common/ShaderLib/ directory in favor of a better place, then I will leave them there. |
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag
Outdated
Show resolved
Hide resolved
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag
Outdated
Show resolved
Hide resolved
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag
Outdated
Show resolved
Hide resolved
I updated the comments to fix the typos you pointed out, thanks for the proofread. I also appeared to have misspelled glsllib as glslib multiple times (missing the second L) in the comments, so I fixed that as well. |
not sure why build failed after last commit that was only changing comments. resubmitting to try again...
The build failed on mac due to a time-out error, however I resubmitted the same file and it worked again... Strange, but at least everything is okay and there were no real problems. |
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md
Outdated
Show resolved
Hide resolved
added missing in/out to readMatParamsAndTextures
added missing uniform to .frag shader
@yaRnMcDonuts , Since this is a change to the way dev. will use the engine and indicates some kind of official best practice approach for using shaders, I would like engine core devs to comment on it before integration. Thanks! |
Yes I was planning to continue working on this and was going to try to have it ready in time for the next release if possible. But @riccardobl messaged me to discuss the PR, and he had said he would work on a new struct based implementation of this PR that includes the important aspects of my PR with his struct approach. So hopefully he can comment and let you know the current status. |
OK so if I understand correctly, @riccardobl will provide a new PR based on this PR and his structs approach? If so, can we close this PR as soon as he provides the new one? |
The draft is here: https://github.com/riccardobl/jmonkeyengine/tree/modularpbr |
@riccardobl Yeah that sounds good to me |
Co-authored-by: Ryan McDonough <peanut64646@gmail.com>
Hi @riccardobl , |
I don't have the push permissions, i've asked @yaRnMcDonuts for them, maybe worth pinging him here too |
Sorry I didn't see your message on discord, I don't have discord launch by default on my computer so sometimes I miss notifications on there until I manually open it up again. I went into my repo in the "collaborators" section of my repo's settings, and added you as a collaborator. Does that allow you to push to that branch, or is there any other setting/permission I need to change in the repo settings? |
That worked, thanks @yaRnMcDonuts |
I've pushed the changes, the code needs to be fully tested. Struct based modularityThe idea behind this design is to use mutable structs to create data containers that can be passed to functions. uniform sampler2D m_Tex;
uniform vec2 texCoord;
struct Surface {
vec4 baseColor;
vec4 litColor;
}
struct Light {
vec4 lightColor;
}
Surface getSurface(){
Surface s;
s.baseColor=texture2D(m_Tex,texCoord);
return s;
}
Light getLight(){
Light l;
l.lightColor=vec4(1);
return l;
}
void applyLight(inout Surface surface, in Light light){
surface.litColor=surface.baseColor+light.lightColor;
}
void main(){
Surface surface=getSurface();
Light light=getLight();
applyLight(surface,light);
gl_FragColor=surface.litColor;
} From there by strategically splitting the code into multiple libraries and using macros we can create reusable modular shader code. The
|
Hi @riccardobl , WDYT? |
We need to test it and see if the implementation is good enough or if things need to be abstracted further. |
I unfortunately haven't gotten around to testing your changes in my own project yet, although they do look good so far from what I have reviewed. I haven't had as much time as to work on my jme game this year as I have had in the past, and I got pulled into some other non shader related things around the time I last commented about testing this PR, so I haven't had time to shift back into shader-brain to work on this again (and likely won't be able to anytime soon). It does look like the latest updates you made are all okay, and the approach you took is cleaner than my initial proposal for this PR, while still retaining the important benefits from my initial PR. However the functionality between your updated code and my original code is still pretty much the same, so even though your implementation is an improvement on my original code and is cleaner and more extensible, I haven't been able to find the time/motivation to re-refactor all my PBR forks to match your latest update to this PR, and I'm also somewhat burnt out on shader refactoring and this PR since I already refactored multiple forks of PBR lighting and the terrains multiple times while working on this. I do plan to tackle this task and refactor all my shaders to match your changes some time in the future, but, as of right now, doing so unfortunately offers no benefits to my main JME project since it is solely a refactoring task and doesn't change any features/functionality in my game, so I have to prioritize some other tasks first. In the meantime I would say it is probably okay to pass this PR and have the community test it in an alpha/beta release rather than waiting for me to test it on my pbr forks, especially since shaders tend to produce different errors/issues on different devices. |
Hi @riccardobl I finally have time to work on this again, and I just built this fork to test it and implement everything into my main project. The TestPBR case with the tank ran fine, however now that I've built and imported this fork's jme-core jar to my own game, I am getting the following crash related to my usage of the Overaly.j3md filter:
If I remove the filter using Overlay.frag, then my game runs with no errors, and in that case it looks like the new changes are not breaking anything else with my own shaders so far. But some changes we've made appear to have broken that specific filter, I am not sure why though since it looks like a very basic color overlay filter. |
i think we need to exclude
on GLSL < 130 in glslcompat |
I updated it to check for the version before It says there was a conflict with this branch though, it appears a |
Not a correct solution, @yaRnMcDonuts . Try using the web editor. |
I don't quite understand what is incorrect in my 3rd (and most recent) update to GLSLCompat.glsllib I did use the web editor to add a line of code from the current master branch (based on the differences I saw when I clicked "resolve conflict" after my first edit to GLSLCompat.glsllib) but now it still says there is a conflict and i don't understand what the conflict is. I must be misunderstanding something about what github means when it says this branch has conflicts, hopefully someone can let me know what I'm doing wrong. |
nevermind my last post, it looks like I just had to remove the conflict marker characters <<<<<<<, =======, >>>>>>> that it had inserted into the file after the initial conflict. Not sure why github actually added those lines into the file, I thought that was just display-only text in the web editor so I didn't realize I needed to delete it manually. It should be resolved now. So this PR should finally be ready to merge( as long as it looks okay to everyone else). I built this branch and ran my game with these changes and everything appears to be okay. Once everything is approved and this PR is merged, then I'll start working on modularizing PBRTerrain and AdvancedPBRTerrain with the same struct funtionality and shared pbrLighting glsllib, and after that the engine's PBR shaders will be much easier to maintain and update in the future. |
Can any core devs/engine leaders take a look at this PR for a final review? |
Addresses this issue: #2122
To re-summarize:
This PR extracts all of the texture reads and base PBR matParam assignment into a .glslib file (currently named PBRLightingParamReads.glsllib)
And then it also extracts all of the lighting calculation into a .glslib file (currently named PBRLighting.glsllib)
I also fixed alot of formatting and indentation mistakes, and overall reorganized the shader.
This should now make it as easy as possible for jme devs to fork PBRLighting to make changes, and they will no longer have to update the lighting or texReads to stay on par with master, as all future changes will all be in the glsllibs. This also reduces the chances that a lesser-skilled shader dev (or even skilled shader devs on a bad day) mistakenly mess up the lighting calculations when forking the shader.
Any feedback and review is greatly appreciated.