Skip to content
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

Add SSRrPass (screen space refraction) #21420

Merged
merged 39 commits into from
Mar 30, 2021
Merged

Add SSRrPass (screen space refraction) #21420

merged 39 commits into from
Mar 30, 2021

Conversation

gonnavis
Copy link
Contributor

@gonnavis gonnavis commented Mar 5, 2021

Add SSRrPass (screen space refraction), based on #20156 .

Demo

image

@gonnavis gonnavis marked this pull request as draft March 5, 2021 19:48
@mrdoob mrdoob added this to the r127 milestone Mar 5, 2021
@mrdoob
Copy link
Owner

mrdoob commented Mar 6, 2021

Looking good!

Are you planning on ignoring the fragments that are occluded by other objects?

@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 6, 2021

Thanks! Yes, I'm doing on this.

@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 6, 2021

Are you planning on ignoring the fragments that are occluded by other objects?

Done. But using the same on/off materials strategy like SSRPass which need re-render whole scene once more.
I'm curious about if can directly copy beautyRendertarget's existing depthBuffer to normalRendertarget? Not found in RenderTarget's doc.

@gonnavis gonnavis force-pushed the SSRrPassPr branch 2 times, most recently from ec95aa3 to 3042bc5 Compare March 21, 2021 17:16
@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 22, 2021

Hello @marcofugaro , I found the gaps in img1 is caused by too high maxDistance, may related to pricesion problem or something else, still researching. Now I let the maxDistance configurable, for this demo scene, I found the value 15 is most suitable, img2.

But for the whole artifacts before the background, img2, it's cause by the refraction ray not hit any rendered pixel, so fallbacked to initial rendered pixels at this palce, this fallback is very useful at areas like img7.
I think it's a limitation of screen-space. I have tried to use the end pixel of the refraction ray if not hit, demo, it can solve this specific area's artifact, img3, but caused more artifacts at elsewhere, img5 img6, so this should not the solution.
May have some good way to over-render the scene to compensate it, but for simple pure screen-space-refraction, may no good solution.

For gaps at img4, it's another issue that related to surfDist, this is a predictable problem, same as SSRPass, but I don't know why the effect thus high, and can't find a very suitable surfDist value for all the scene, still researching.
EDIT: Found that surfDist=0.5 is the most compromised value for this demo scene, changed.

image

@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 22, 2021

For gaps at img4, it's another issue that related to surfDist, this is a predictable problem, same as SSRPass, but I don't know why the effect thus high, and can't find a very suitable surfDist value for all the scene, still researching.
EDIT: Found that surfDist=0.5 is the most compromised value for this demo scene, changed.

Solved this surfDist related issue. Turned out that caused by the same reason as #20156 (comment) that when refract ray too perpendicular to screen it'll march far away even just one pixel step, so go way behind the surface it should collide.
Solved this simultaneously ( same reason ).
image

But now too accurate, if the rendered pixles not face camera ( like the ground below ) thus has large gap, will not pass the away<=sD check, thus will not be refracted, caused the holes on bunny's back 🤔. ( the holes already apeared after this commit 76fac3e , just have not noticed )

Still thinking about how to make up for this shortcoming. May let user choose each object between accurate and rough?
If accurate, do the away<=sD check, if rough, just do the viewRefractRayZ<vZ check?

Or, read neighbor rendered pixels to from a plane then check intersection? EDIT: No, the holes on bunny's back are not caused by the gap between rendered ground pixels, it's caused by sphere and cone covering the ground. May only accurate and rough solution are left.

image

@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 23, 2021

Tried to implement accurate or rough option per object, but the result seems too complex, and facing the same difficult choices at there.

So now just add a overall infiniteThick option like SSRPass, but turn it on by defualt, to ensure bunny's display effect ( especially the back ), but sacrificing some detailed parts ( especially the refrections on the cube ). Let user choose use which overall setting or implementing accurate or rough option per object by self.

@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 27, 2021

They appear when the scene background color is behind. They don't happen with the ground plane.

@marcofugaro Solved! After the commits above, now just increase the maxDistance can solve this problem! And will not introduce new problems.
Surprisingly the specular improved too!

Previously I think background's viewPosition is infinite, so feel no solution, but now turned out that it's not infinite.
Not sure what's the background's viewPosition is, but for this demo scene, maxDistance=50 is enough. Keep researching.

image

@gonnavis
Copy link
Contributor Author

gonnavis commented Mar 27, 2021

Add setting: fillHole.

accurate vs fillHole vs pure infiniteThick
image

@mrdoob
Copy link
Owner

mrdoob commented Mar 30, 2021

Thanks!

@mrdoob
Copy link
Owner

mrdoob commented Mar 30, 2021

I think this code will come in very handy for when we have to implement KHR_materials_ior, KHR_materials_translucency and KHR_materials_volume 👍

@vinkovsky
Copy link

Amazing work! Does it works with screen space reflection shader?

@vinkovsky
Copy link

It would be great to be able to change the refractive index for every object in the scene

@gonnavis
Copy link
Contributor Author

gonnavis commented Apr 2, 2021

@vinkovsky Thanks!

It would be great to be able to change the refractive index for every object in the scene

Not yet in the release, but I'm working on this #21487 , I think the same logic can use on SSRr too, copy the codes to your project first if necessary.

Does it works with screen space reflection shader?

Threejs's compoer system can be connected in series, so simple answer is can. But I think It'll has problem and hard to choose use which first.

I want to combine SSRPass and SSRrPass into something like SSRaytracePass, to make them truely work together and reuse the diffuse/depth/normal infos to improve performce. But the two existing Passes has much to be improved like the above one, so may need more time.

@vinkovsky
Copy link

Thanks for the quick response @gonnavis ! i appreciate your work!

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.

4 participants