sp614x / optifine

1.81k stars 418 forks source link

(Shaders) More control over gbuffer transparency handling #195

Open BruceKnowsHow opened 8 years ago

BruceKnowsHow commented 8 years ago

I'm trying to implement a double-layered deferred rendering solution to handle semi-opaque surfaces. I've come up with a couple of things that would improve my pipeline:

1: Disable alpha based fragment culling for opaque gbuffers. I would like to use the alpha channel of opaque gbuffers to store information, however if the channel falls below about 0.1, the fragment is discarded. This functionality can be imitated (and already is in my shaderpack) by just having this type of line somewhere in your opaque gbuffers:

if (diffuse.a < 0.1000003) discard;

2: Make alpha based fragment blending optional per-buffer for semi-transparent gbuffers. Similar to request 1, I would like to store information in the alpha channel of my buffer, but if it's dictating the mix amount of the RGB components, it's unusable. I would like to use RGB blending with some of my gbuffers, but not others. A shaderpack constant would do the job perfectly.

Requests 1 and 2 can be fulfilled in a roundabout way quite simply: Make gbuffer alpha blending/culling optional per-buffer, using shaderpack constants. For example:

const bool FragData0Blending = true; // default behavior, only active in gbuffers const bool FragData3Blending = false; // opaques will not cull, semi-opaques will not blend

This should maintain compatibility with other shaderpacks.

3: Alpha channel blending for semi-transparent gbuffers. I asked for this (in addition to a redundant feature) in the past. I do not know if it is possible in OpenGL, but it would be extremely ideal, because it would save me a whole buffer dedicated to just recovering the accumulated alpha of semi-transparent surfaces (as I currently do, and as is described in my conclusion to the linked issue).

BruceKnowsHow commented 8 years ago

Figured out a little bit more about how alpha blending/culling works.

For opaque gbuffers, culling is only based on the alpha channel of gl_FragData[0], or gl_FragData[1] if gl_FragData[0] isn't written to.

For semi-transparent gbuffers, blending is buffer independant, and is based on the alpha channels of individual buffers.

This basically just means that I shouldn't run into any problems with my opaque fragments discarding themselves, as the alpha channel I'm using is not gl_FragData[0].

dotModded commented 8 years ago

Bump