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

Initial. AlphaTestGroupStrategy and associated test. #6317

Open
wants to merge 53 commits into
base: master
Choose a base branch
from

Conversation

jeffcragg
Copy link

AlphaTestGroupStrategy. DecalAlphaTest shows intersecting overlapping translucent decals without artifacts with stipple/screen door transparency. The test is based on the CameraGroupStrategy one switched to perspective camera.

@mgsx-dev mgsx-dev self-requested a review December 17, 2020 02:06
@@ -0,0 +1,151 @@
package com.badlogic.gdx.graphics.g3d.decals;
Copy link
Contributor

Choose a reason for hiding this comment

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

please add copyright header (like other libgdx classes) and also run formater on the whole class, see https://libgdx.badlogicgames.com/documentation/hacking/Contributing.html#formatting

Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like there is an issue with the formatted code (some spaces everywhere and some space padded statements)

@@ -0,0 +1,151 @@
package com.badlogic.gdx.graphics.g3d.decals;

import com.badlogic.gdx.*;
Copy link
Contributor

Choose a reason for hiding this comment

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

better only import what is used instead of all packages

import com.badlogic.gdx.utils.*;

/**
* <p>Single Group strategy (all Decals same) using Z-buffer to render using screen door transparency to avoid having
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to explain clearly what the pros and cons (eg. doesn't support half transparency, performances impacts compared to general purpose CameraGroupStrategy), and also document it the same way as CameraGroupStrategy with a states table.

just like CameraGroupStrategy, i think it's important to explain to devs, in which situation this class is preferable over CameraGroupStrategy. Also explain a bit more the stipple/dissolve/screen door feature, especially explain that it takes both original texture alpha and decal alpha to perform the test and the stipple.

Globally, i think a clear documentation is very important for this class.

public void beforeGroups() {

Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
shader.begin();
Copy link
Contributor

Choose a reason for hiding this comment

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

shader.begin is deprecated, use bind instead


@Override
public void afterGroups() {
shader.end();
Copy link
Contributor

Choose a reason for hiding this comment

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

shader.end is deprecated, you can remove this line.

+ "varying vec4 v_color;\n" //
+ "varying vec2 v_texCoords;\n" //
+ "uniform sampler2D u_texture;\n" //
+ "float[] bayerMatrix ={1.0f / 17.0f, 9.0f / 17.0f, 3.0f / 17.0f, 11.0f / 17.0f," //
Copy link
Contributor

Choose a reason for hiding this comment

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

f is not valid in GLSL2 shader code for literal floats.
I think it would be better to have stipple feature as an option (disabled by default). Could be a boolean in constructor.

+ "{\n" //
+ "int xPos = int(gl_FragCoord.x) % 4; \n" //
+ "int yPos = int(gl_FragCoord.y) % 4; \n" //
+ "float stipple= bayerMatrix[ xPos * (yPos*4) ]; \n" //
Copy link
Contributor

Choose a reason for hiding this comment

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

are you sure about this? isn't it yPos * 4 + xPos instead?

Copy link
Member

Choose a reason for hiding this comment

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

That does look incorrect, and it also won't run on GWT (can't use variable indices into arrays). It should be documented that this is GWT-incompatible.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch! indeed, variable array index requires GLSL 130 (GLES 3.0+ / WebGL 2.0). There are possible workarounds either using a for loop to find the entry or using a texture lookup.
I was balanced to include this stipple feature from the beginning mainly because it's not really a concern of group strategy. Since implementation would bring more complexity or limitation, i'm in favor to fully remove this feature from the PR.
It could be interesting to have it but i would separate it from Decals stuff (and do it in another PR), user code could plug it in this class easily by overriding this method anyway.

Copy link
Author

Choose a reason for hiding this comment

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

From Tettinger's post the bayer stuff is no longer going to be present anyway. I have been looking at this https://bartwronski.com/2016/10/30/dithering-part-three-real-world-2d-quantization-dithering/. I think stipple should be included though, because it is a part of the group strategy idea, that within a strategy some groups are translucent, and others opaque etc but if you remove stippling then the group strategy has no support for translucency at all when it could easily be a setting in the constructor. And i think that probably people would prefer CameraGroupStrategy or AlphaTestStrategy working entirely without needing extra stuff for the second choice, because its easy to just replace one with the other to see which is preferable.

+ "int yPos = int(gl_FragCoord.y) % 4; \n" //
+ "float stipple= bayerMatrix[ xPos * (yPos*4) ]; \n" //
+ "vec4 tex2D = texture2D(u_texture, v_texCoords); \n" //
+ "vec4 tinted = v_color*tex2D; \n" //
Copy link
Contributor

Choose a reason for hiding this comment

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

could be optimized a bit, we only need alpha multiplication for alpha test and we only need RGB multiplication for fragColor, eg. gl_FragColor = vec4(tex2D.rgb * v_color.rgb, 1.0); i'm not sure which version perform the best though, it'd need to be confirmed.


/**
* <p>Single Group strategy (all Decals same) using Z-buffer to render using screen door transparency to avoid having
* to presort the decals. Materials are still sorted.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

presort decals is not an issue, the reason of this class is to avoid overlap artifacts in some situation.


import java.util.*;

public class DecalAlphaTest extends GdxTest {
Copy link
Contributor

Choose a reason for hiding this comment

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

This test is a bit complicated, a load test is not really what we need. Maybe a better approach would be to switch from/to different strategy at runtime and see how much FPS we can get (vsync can be disabled manually by testers when needed). Also adding/removing decals manually (via keyboard keys) would be better.

Before performance measurement, what we really need is to test that the strategy works (eg. the stipple effect, etc)

Copy link
Contributor

@mgsx-dev mgsx-dev left a comment

Choose a reason for hiding this comment

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

also you forgot to include a class to GWT xml (that's why the build fails), and also need to add an entry to the CHANGES file

@@ -147,6 +147,7 @@

<!-- graphics/g3d/decals -->
<include name="graphics/g3d/decals/CameraGroupStrategy.java"/>
<include name="graphics/g3d/decals/AlphaTestGroupStrategy.java"/>
Copy link
Contributor

Choose a reason for hiding this comment

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

please use alphabetical order (A before C)

+ " gl_Position = u_projectionViewMatrix * " + ShaderProgram.POSITION_ATTRIBUTE + ";" + "\n" //
+ "}\n";

String dfragmentShader = "#ifdef GL_ES\n" //
Copy link
Contributor

Choose a reason for hiding this comment

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

dead code

* @param bayerFilter Specifies the size of the dithering filter used to discard pixels
* of translucent textures.
*/
public AlphaTestGroupStrategy (final Camera camera, final BayerFilter bayerFilter) {
Copy link
Contributor

Choose a reason for hiding this comment

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

better use an integer (keep it simple)

* @param camera
*/
public AlphaTestGroupStrategy (final Camera camera) {
this(camera, BayerFilter.MODERATE);
Copy link
Contributor

Choose a reason for hiding this comment

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

should be disabled by default

+ "#define MAX_LEVEL 4\n" //
+ "float GetBayer() {\n" //
+ " float finalBayer = 0.0;\n" //
+ " for(int i = 1 - "+bayerFilter.size +"; i<= 0; i++) {\n" //
Copy link
Contributor

Choose a reason for hiding this comment

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

better have an optimized version when stipple is disabled

+ " for(int i = 1 - "+bayerFilter.size +"; i<= 0; i++) {\n" //
+ " float bayerSize = exp2(float(i)); // negative exponent makes an inverse\n" //
+ " vec2 c = mod(floor(gl_FragCoord.xy * bayerSize), 2.0);\n" //
+ " float bayer = 2. * c.x - 4. * c.x * c.y + 3. * c.y; // borrows factors of the summed geometric series soon to"
Copy link
Contributor

Choose a reason for hiding this comment

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

comments in generated shader code is not necessary, you could move it to java comments instead

+ "uniform sampler2D u_texture;\n" //
+ "\n" //
+ "#define MAX_LEVEL 4\n" //
+ "float GetBayer() {\n" //
Copy link
Contributor

Choose a reason for hiding this comment

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

why calculating for every fragment when we could use a lookup table (like in your original PR)?

Copy link
Author

@jeffcragg jeffcragg Dec 20, 2020

Choose a reason for hiding this comment

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

this one works on webgl and the lookup one can't unfortunately as variable access to arrays not allowed. and for four iterations wtih this you get the equivalent of 16x16 dither block (a single pass looks ok imo)

+ "\n" //
+ "void main()\n" //
+ "{\n" //
+ " v_color = " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" //
Copy link
Contributor

Choose a reason for hiding this comment

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

missing v_color.a = v_color.a * (255.0/254.0);, see CameraGroupStrategy

jeffcragg and others added 26 commits February 24, 2023 16:06
@crykn crykn added this to the 1.12.2 milestone Nov 23, 2023
@crykn crykn modified the milestones: 1.12.2, 1.12.3 Apr 20, 2024
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.

None yet

5 participants