-
-
Notifications
You must be signed in to change notification settings - Fork 172
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
Overhaul of volume Raymarching #206
Overhaul of volume Raymarching #206
Conversation
Omg! this is so impressive! I'm really excited for it Tiny suggestion:
|
This is fantastic work @shadielhajj! Do you mind providing a use example? |
#endif | ||
) { | ||
|
||
vec4 raymarch(mat4 viewMatrix, vec2 st, out float eyeDepth, out Material mat) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here is that if eyeDepth or mat are not used the compiler will optimize it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a Material struct anyway. Whether the user passes it to us, or we have to create it for them.
// user-provided struct
vec4 raymarch(mat4 viewMatrix, vec2 st, out float eyeDepth, out Material mat) {
...
}
// lygia-provided struct
vec4 raymarch(mat4 viewMatrix, vec2 st, out float eyeDepth) {
Material mat;
materialZero(mat);
return raymarch(viewMatrix, st, eyeDepth, mat);
}
In the single-sample version. There's no extra cost associated with returning AOVs.
However, in the multi-sample version, there is indeed an extra cost associated with averaging all the material properties. Which is why we require the user to enable AOVs using RAYMARCH_AOV
#if RAYMARCH_AOV
add(matAcc, mat, matAcc);
#endif
#if RAYMARCH_AOV
multiply(mat, RAYMARCH_MULTISAMPLE_FACTOR, mat);
#endif
Thanks, @patriciogonzalezvivo! Here's how to add a spherical fog volume to the raymarching example scene and enable volumetric shadows #define RAYMARCH_VOLUME
#define RAYMARCH_VOLUMETRIC_SHADOWS
Medium raymarchVolumeMap( in vec3 pos ) {
vec3 scattering = 0.05*vec3(1.0, 1.0, 1.0);
vec3 absorption = vec3(0.0);
return mediumNew(scattering, absorption, sphereSDF(pos-vec3( 0.0, 0.50, 0.0), 3.0 ));
} And here's how to add noisy volumetric fog #define RAYMARCH_VOLUME
Medium raymarchVolumeMap( in vec3 pos ) {
vec3 scattering = vec3(1.0, 1.0, 1.0);
vec3 absorption = vec3(0.0, 0.0, 0.0);
return mediumNew(scattering, absorption, fbm(pos));
} Volumetrics are quite heavy computationally, so you might want to tweak the quality params: #define RAYMARCH_VOLUME_SAMPLES 64
#define RAYMARCH_VOLUME_SAMPLES_LIGHT 32
#define FBM_OCTAVES 3 |
Sorry for all the single comments! Hope you don't mind the additions |
@patriciogonzalezvivo. Sorry didn't mean to delete your comment, was actually trying to delete mine. this one makes total sense #if defined(RAYMARCH_VOLUME)
Medium RAYMARCH_VOLUME_MAP_FNC( in vec3 pos );
#endif Regarding this one #if defined(RAYMARCH_VOLUME)
Medium res = RAYMARCH_VOLUME_MAP_FNC(position);
float density = -res.sdf;
vec3 scattering = res.scattering;
vec3 extinction = res.absorption + scattering;
#else
float density = 0.0;
vec3 scattering = vec3(0.0);
vec3 extinction = vec3(0.0);
#endif I don't really like the idea of breaking the algo because a #if defined(RAYMARCH_VOLUME)
#include "raymarch/volume.glsl"
#endif |
The issue with that approach is that the includes inside So all this files could be consider as "already added" while in reality they are not accessible because they are behind a flat
To solve that all #include parsers for python, JS and C++ need to resolve all What about doing this? #if !defined(FNC_RAYMARCH_VOLUMERENDER) && defined(RAYMARCH_VOLUME)
#define FNC_RAYMARCH_VOLUMERENDER
... |
Brillant PR @shadielhajj! |
The current volume raymarching sub-system is quite limited: It is not physically accurate, it's not very flexible (it doesn't support specifying volume density and works with directional light only), and most importantly, it cannot co-exist with other raymarching renderers (such as PBR). The entire scene is rendered either as a solid or a volume, not both.
The proposed rewrite:
Here's a scene rendered with PBR materials and and an fbm volume
The code for the volume
Note how the volume renderer is enabled with
RAYMARCH_VOLUME
. The map function is implemented inraymarchVolumeMap
(by default) which must return aMedium
. Easy peasy.Note also that the volume is not simply overlay on the scene, but properly integrated in space. In the example below, the volume sphere correctly sits in between the cone and the doughnut.
Another cool feature is volumetric shadowing by opaque objects. Very handy to create atmospheric effects. Enable it with
RAYMARCH_VOLUMETRIC_SHADOWS
Bonus Track:
Rework of the AOV interface in
raymarch.*
. Just pass the desired output parameters. If full AOV output (Material) is desired,#define RAYMARCH_AOV
should be explicitly specified. This is for optimization purposes.Including the legacy view (lookAt) signatures