-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Solari specular scene/PT support #20242
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
base: main
Are you sure you want to change the base?
Conversation
…into solari6-perfopt-good
// https://gpuopen.com/download/Bounded_VNDF_Sampling_for_Smith-GGX_Reflections.pdf (Listing 1) | ||
fn sample_ggx_vndf(wi_tangent: vec3<f32>, roughness: f32, rng: ptr<function, u32>) -> vec3<f32> { | ||
let i = wi_tangent; | ||
let rand = rand_vec2f(rng); | ||
let i_std = normalize(vec3(i.xy * roughness, i.z)); | ||
let phi = 2.0 * PI * rand.x; | ||
let a = roughness; | ||
let s = 1.0 + length(vec2(i.xy)); | ||
let a2 = a * a; | ||
let s2 = s * s; | ||
let k = (1.0 - a2) * s2 / (s2 + a2 * i.z * i.z); | ||
let b = select(i_std.z, k * i_std.z, i.z > 0.0); | ||
let z = fma(1.0 - rand.y, 1.0 + b, -b); | ||
let sin_theta = sqrt(saturate(1.0 - z * z)); | ||
let o_std = vec3(sin_theta * cos(phi), sin_theta * sin(phi), z); | ||
let m_std = i_std + o_std; | ||
let m = normalize(vec3(m_std.xy * roughness, m_std.z)); | ||
return 2.0 * dot(i, m) * m - i; | ||
} | ||
|
||
// https://gpuopen.com/download/Bounded_VNDF_Sampling_for_Smith-GGX_Reflections.pdf (Listing 2) | ||
fn ggx_vndf_pdf(wi_tangent: vec3<f32>, wo_tangent: vec3<f32>, roughness: f32) -> f32 { | ||
let i = wi_tangent; | ||
let o = wo_tangent; | ||
let m = normalize(i + o); | ||
let ndf = D_GGX(roughness, saturate(m.z)); | ||
let ai = roughness * i.xy; | ||
let len2 = dot(ai, ai); | ||
let t = sqrt(len2 + i.z * i.z); | ||
if i.z >= 0.0 { | ||
let a = roughness; | ||
let s = 1.0 + length(i.xy); | ||
let a2 = a * a; | ||
let s2 = s * s; | ||
let k = (1.0 - a2) * s2 / (s2 + a2 * i.z * i.z); | ||
return ndf / (2.0 * (k * i.z + t)); | ||
} | ||
return ndf * (t - i.z) / (2.0 * len2); | ||
} |
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.
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.
Since Jasmine's version is less code, I wonder why the big difference and whether i could just use this function in my case as is. I'll test it out and share my findings.
Just came here to add that a 1 to 1 compatibility with the solari material system and materialx is disirable. |
There's vague plans to support MaterialX in bevy, but for solari, we're unlikely to support such a wide range of materials. Raytracing is already super expensive, adding lots of varied materials on top makes it even slower :) |
let B = TBN[1]; | ||
let N = TBN[2]; | ||
|
||
let wo_tangent = vec3(dot(wo, T), dot(wo, B), dot(wo, N)); |
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.
If TBN
is a mat3<f32>
, this is just TBN * wo
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.
Hmm this is the code we use everywhere else in bevy 😅
var wi_tangent: vec3<f32>; | ||
if rand_f(rng) < diffuse_weight { | ||
wi = sample_cosine_hemisphere(ray_hit.world_normal, rng); | ||
wi_tangent = vec3(dot(wi, T), dot(wi, B), dot(wi, N)); |
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.
Same here.
wi_tangent = vec3(dot(wi, T), dot(wi, B), dot(wi, N)); | ||
} else { | ||
wi_tangent = sample_ggx_vndf(wo_tangent, ray_hit.material.roughness, rng); | ||
wi = wi_tangent.x * T + wi_tangent.y * B + wi_tangent.z * N; |
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.
And this is a mul with the transpose.
wi = wi_tangent.x * T + wi_tangent.y * B + wi_tangent.z * N; | ||
} | ||
|
||
let diffuse_pdf = dot(wi, ray_hit.world_normal) / PI; |
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 have wi_tangent
here, can just use the Z component (I assume that's up) instead of the dot.
Note that specular support for the realtime lighting plugin will come at a future date. I think I want to focus on getting GI more stable and hooking up a denoiser first. This is just support for the material properties in RaytracingScenePlugin, and specular lighting in the PathtracingPlugin.