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

Postprocessing+ Emissive texture rework + Optimize rendering performance #179

Merged
merged 24 commits into from
Nov 3, 2021

Conversation

Yefancy
Copy link
Contributor

@Yefancy Yefancy commented Oct 6, 2021

The future work

  • Add Emissive and Bloom effects to some models (some casings)
  • Add support for dynamic rendering Bloom Effect, such as TESR rendering.
  • Add emissive frame makes it easier to make models involving emissive textures.

What:

  1. Add postprocessing pipeline for shader rendering. For now i implemented the blur effect and bloom effect.
    Bloom Efffect is pretty with emissive textures.
  2. Optimized rendering in GTCE for better performance.
    DEMO:
    https://user-images.githubusercontent.com/18493855/136208568-750c7251-fe2e-401f-a920-df67d57a4776.mp4
    (Ignore the "shiny" casing, this is just for effect testing, I made emissive and Bloom effects for casing. Actually only Emissive Textures in MetaTileEntity currently has Bloom Effect)

How solved:

The postprocessing itself is easy and won't be covered here, thanks to the completed Shader framework before.

A lot of people are worried about Bloom making FPS low. I did a lot of work to render Bloom as efficiently as possible so that there was almost no performance loss. Let me explain briefly how I implement it:

The BlockLayer has 4 layers (Solid, Mipped Cutout, Cutout, Translucent), which always render in order and show our world. I capture and render the highlight parts (models in Bloom layer) by append a Bloom layer between Cutout and Translucent, and renders Bloom effect after Translucent finished.
Compared with rendering bloom directly from the final image(WorldLastEvent). This has the advantage of effectively presenting a true highlight and perfectly compatible with Translucent

Since all rendering is compiled into the chunk rendering pipeline, it is very efficient. You don't need to scan every block and render it like TESR does.

There are no duplicated renderings, even the Bloom Layer are rendered only once using FBO off-screen tech.The only additional overhead is to Bloom the proposed highlights, but this is negligible.

Comparison of performance:

People tend to be a little scared of special effects, worried about performance.Here are the test results. NOTE: all tests have the same environment Intel UHD Graphic 630. I think you all have Nvidia or AMD graphics, which are absolutely better than mine.

Bloom Off:
normal
Bloom On:
bloom

Just pay attention to the parameters of BTLayer and Bloom.
BTLayer: Proportion of the cost of rendering Bloom Layer and Translucent layer in a frame.
Bloom: Proportion of the cost of rendering Bloom Effect in a frame.
Considering the overall performance from the right-top(cost of the render of the level section). Only increase 0.53%(from 14.27% to 14.80)
We can see that there is almost no performance burden.

performance comparison video
Bloom Off:
https://user-images.githubusercontent.com/18493855/136211462-733c656b-07f9-4938-a73b-e00f926b2a30.mp4
Bloom On:
https://user-images.githubusercontent.com/18493855/136211784-f47e41e5-51a0-43c7-bf98-ec126b6acc72.mp4

How to use it? (for DEVs):

Simply specify your model (hightlight parts) or texture render in Bloom Layer. It is suggested to use with emissive texture, which will make the effect better. Who would like to see an object with bloom effect but does not emit light at night?

Optimize

  • MetaTileEntityRenderer will check culling faces before buffer data pushed, avoiding unnecessary sides be rendered.
  • Remove IRenderMetaTileEntity, using IFastMetaTileEntity as the only interface for TESR. The previous IFast was bogus, essentially calling the draw function once for each MetaTileEntity. Now, we using batch buffer from Forge, which is called to draw after all TE finish their FASTTESR. Significantly improved rendering performance for many entities.

Custom Texture

Implement two features from CTM: Custom lightmap and layered rendering.
Model
image
Emissive
image
Bloom
image

@Yefancy Yefancy changed the title Postprocessing Bloom + Blur Postprocessing+ Emissive texture rework Oct 13, 2021
@Yefancy Yefancy changed the title Postprocessing+ Emissive texture rework Postprocessing+ Emissive texture rework + Optimize rendering performance Oct 19, 2021
@Yefancy Yefancy requested a review from a team October 24, 2021 03:17
Copy link
Member

@bruberu bruberu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are some general thoughts on some more confusing parts of this PR.

Copy link
Member

@bruberu bruberu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you've clarified a lot of the questions that I had, I personally approve this. Of course, there's probably quite a bit of testing that needs to get done, but if there are problems, I'm not able to see them.

@ALongStringOfNumbers
Copy link
Contributor

ALongStringOfNumbers commented Oct 26, 2021

When running a recipe in a multiblock that is not getting enough energy (I did EBF in this case), the coils will light up for the first couple recipe ticks and then turn off when the multiblock is in the not enough energy state, which is expected. However, if you begin supplying enough energy to the multiblock, the bloom/emissive effects will not return until the recipe is completed, even though the recipe is now progressing fine.

Might not be fixable without some refactoring to the "not enough energy state" for multiblocks.

Also, I had this display issue with a fusion reactor that was formed before I checked out the PR:
2021-10-26_13-04

However, the issue went away when I broke and replaced the controller, so it is most likely minor or not applicable.

btw, for anyone testing, the fusion reactor will crash due to not having df4c08b

@Yefancy
Copy link
Contributor Author

Yefancy commented Oct 27, 2021

When running a recipe in a multiblock that is not getting enough energy (I did EBF in this case), the coils will light up for the first couple recipe ticks and then turn off when the multiblock is in the not enough energy state, which is expected. However, if you begin supplying enough energy to the multiblock, the bloom/emissive effects will not return until the recipe is completed, even though the recipe is now progressing fine.

its an issue causing by AbstractRecipeLogic. it doesn't always maintain a correct state of the hasNotEnoughEnergy. i can fix it here, but it has been fixed in #136

@Yefancy
Copy link
Contributor Author

Yefancy commented Oct 27, 2021

Also, I had this display issue with a fusion reactor that was formed before I checked out the PR:

i also met this problem. it should have to do with my culling optimize, and I'm actively exploring reasons. let me know if there is a way to reproduce.

@ALongStringOfNumbers
Copy link
Contributor

i also met this problem. it should have to do with my culling optimize, and I'm actively exploring reasons. let me know if there is a way to reproduce.

It seems like the places it happened to me were on Multiblock parts where the output/input facings were being rendered.
EG. The gray box with blue arrows for the output hatches, and the pattern marking the input for the energy input. I have attached some images of the faces I am talking about.

2021-10-26_20-23_1
2021-10-26_20-23

@Yefancy
Copy link
Contributor Author

Yefancy commented Oct 27, 2021

It seems like the places it happened to me were on Multiblock parts where the output/input facings were being rendered.
EG. The gray box with blue arrows for the output hatches, and the pattern marking the input for the energy input. I have attached some images of the faces I am talking about.

This info could be valuable. Could you tell me if any invisible face is on the bound of the chunk? You show three invisible faces and two correct faces. What's the other one? Is it also a functional side of the block?

@Yefancy
Copy link
Contributor Author

Yefancy commented Oct 27, 2021

oh, I have a thinking about what's going on, the chunkcache rendering is multi-threaded, but the SideMask of the Textures Renderer is a static field. If so, the problem can be easily solved.

@ALongStringOfNumbers
Copy link
Contributor

This info could be valuable. Could you tell me if any invisible face is on the bound of the chunk? You show three invisible faces and two correct faces. What's the other one? Is it also a functional side of the block?

The third invisible face in the screenshot is a side of the output bus, but one that does not have the output side texture (gray box + arrows) on it.

And, when checking on the structure, none of the faces that were invisible were on the boundary layers of a chunk. The energy input hatch (the right-most invisible block) is on a chunk boundary, but the overlay texture is on the opposite side of the block from the face that is touching the chunk border.

@Yefancy Yefancy merged commit 43aa0e7 into master Nov 3, 2021
@TechLord22 TechLord22 deleted the postprocessing branch November 3, 2021 14:38
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.

3 participants