Skip to content

Commit 6d4d824

Browse files
authored
Merge pull request #166 from litwak913/shader-new
Improve shader and introduce alternative edge kernel (NEW)
2 parents 29a44b6 + 185f738 commit 6d4d824

14 files changed

Lines changed: 377 additions & 49 deletions

File tree

assets/ArkPetsConfigDefault.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"render_outline_emphasis":3,
4141
"render_outline_emphasis_color":"#FFBB00FF",
4242
"render_outline_width":2.0,
43+
"render_shader_high_quality":true,
4344
"render_shadow_color":"#000000BB",
4445
"transition_duration":0.3,
4546
"transition_type":"EASE_OUT_CUBIC",

assets/UI/SettingsModule.fxml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@
103103
</Tab>
104104
<Tab text="其他">
105105
<VBox>
106+
<HBox>
107+
<JFXCheckBox fx:id="configEnableHighQuality" mnemonicParsing="false" text="高质量滤波"/>
108+
<JFXButton fx:id="configEnableHighQualityHelp"/>
109+
</HBox>
106110
<HBox>
107111
<JFXCheckBox fx:id="configEnableMipMap" mnemonicParsing="false" text="MipMap 抗锯齿"/>
108112
<JFXButton fx:id="configEnableMipMapHelp"/>

assets/shaders/gl21/ComplexFragment.glsl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ vec4 getGaussianNeighborsSum(vec2 unitLength) {
5454
return sum;
5555
}
5656

57-
vec4 getOutlined() {
58-
vec4 texColor = texture2D(u_texture, v_texCoords);
57+
vec4 getOutlined(vec4 texColor) {
5958
if (u_outlineColor.a > 0.0 && u_outlineWidth > 0.0 && u_outlineAlpha > 0.0) {
6059
vec2 relOutlineWidth = vec2(1.0) / u_textureSize * u_outlineWidth;
6160
vec4 neighbor = getGaussianNeighborsSum(relOutlineWidth) * c_outlineOverstate;
@@ -82,7 +81,7 @@ void main() {
8281
if (texColor.a < c_alphaHigh) {
8382
if (texColor.a < c_alphaLow) {
8483
// Outline effect
85-
texColor = getOutlined();
84+
texColor = getOutlined(texColor);
8685
}
8786
// Box shadow effect
8887
texColor = mix(getBoxShadow(), texColor, texColor.a);
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#version 120
2+
/** Copyright (c) 2022-2024, Harry Huang
3+
* At GPL-3.0 License
4+
*/
5+
6+
// Complex fragment shader for TwoColorPolygonBatch with outline and box shadow effect. (Low Quality Version)
7+
8+
varying vec2 v_texCoords; // From VS
9+
uniform sampler2D u_texture; // From TCPB
10+
uniform vec4 u_outlineColor; // Required
11+
uniform float u_outlineWidth; // Required
12+
uniform float u_outlineAlpha; // Required
13+
uniform vec4 u_shadowColor; // Required
14+
uniform ivec2 u_textureSize; // Required
15+
uniform float u_alpha; // Required
16+
17+
const float c_alphaLow = 0.1;
18+
const float c_alphaHigh = 0.9;
19+
const float c_seamCoef = 0.6;
20+
const float c_outlineOverstate = 10.0;
21+
const float c_shadowOffset = 2.0;
22+
23+
const vec2 OFFSETS[16] = vec2[16](
24+
vec2(-1.000, 0.000), // 0 (Left) - Actually 180, but starting here for comparison
25+
vec2(-0.924, -0.383), // 22.5
26+
vec2(-0.707, -0.707), // 45 (Down-Left)
27+
vec2(-0.383, -0.924), // 67.5
28+
vec2( 0.000, -1.000), // 90 (Down)
29+
vec2( 0.383, -0.924), // 112.5
30+
vec2( 0.707, -0.707), // 135 (Down-Right)
31+
vec2( 0.924, -0.383), // 157.5
32+
vec2( 1.000, 0.000), // 180 (Right) - Actually 0
33+
vec2( 0.924, 0.383), // 202.5
34+
vec2( 0.707, 0.707), // 225 (Up-Right)
35+
vec2( 0.383, 0.924), // 247.5
36+
vec2( 0.000, 1.000), // 270 (Up)
37+
vec2(-0.383, 0.924), // 292.5
38+
vec2(-0.707, 0.707), // 315 (Up-Left)
39+
vec2(-0.924, 0.383) // 337.5
40+
);
41+
42+
vec4 getSimpleSampleSum(float width) {
43+
vec4 sum = vec4(0.0);
44+
for (int i = 0; i < OFFSETS.length(); i++) {
45+
sum += texture2D(u_texture, v_texCoords + OFFSETS[i] * width / u_textureSize);
46+
}
47+
return sum;
48+
}
49+
50+
vec4 getOutlined(vec4 sum, vec4 texColor) {
51+
if (u_outlineColor.a > 0.0 && u_outlineWidth > 0.0 && u_outlineAlpha > 0.0) {
52+
vec2 relOutlineWidth = vec2(1.0) / u_textureSize * u_outlineWidth;
53+
vec4 neighbor = sum * c_outlineOverstate;
54+
if (neighbor.a > c_alphaLow) {
55+
texColor.rgb = u_outlineColor.rgb;
56+
texColor.a = min(1.0, neighbor.a) * u_outlineColor.a * u_outlineAlpha;
57+
}
58+
}
59+
return texColor;
60+
}
61+
62+
vec4 getBoxShadow(vec4 texColor) {
63+
if (u_shadowColor.a > 0.0) {
64+
// Sample around to get maximum shadow alpha from neighbors
65+
vec4 shadowSum = getSimpleSampleSum(c_shadowOffset);
66+
float maxShadowAlpha = clamp(shadowSum.a, 0.0, 1.0);
67+
// Only apply shadow where the current pixel is transparent/semi-transparent
68+
// and there are opaque pixels nearby
69+
if (maxShadowAlpha > c_alphaLow && texColor.a < c_alphaHigh) {
70+
float shadowAlpha = maxShadowAlpha * u_shadowColor.a;
71+
// Blend shadow with current texColor using "over" compositing
72+
// Shadow sits behind, so only fill where texColor is not already visible
73+
float blendFactor = shadowAlpha * (1.0 - texColor.a);
74+
texColor.rgb = mix(texColor.rgb, u_shadowColor.rgb, blendFactor);
75+
texColor.a = texColor.a + blendFactor;
76+
}
77+
}
78+
return texColor;
79+
}
80+
81+
void main() {
82+
vec4 texColor = texture2D(u_texture, v_texCoords);
83+
84+
if (texColor.a < c_alphaHigh) {
85+
if (texColor.a < c_alphaLow) {
86+
// Outline effect
87+
texColor = getOutlined(getSimpleSampleSum(u_outlineWidth),texColor);
88+
}
89+
// Box shadow effect
90+
texColor = getBoxShadow(texColor);
91+
} else {
92+
// No effect
93+
}
94+
95+
// Ultimate composing
96+
gl_FragColor = texColor;
97+
gl_FragColor.a *= u_alpha;
98+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#version 120
2+
3+
attribute vec4 a_position;
4+
attribute vec4 a_color;
5+
attribute vec2 a_texCoord0;
6+
7+
uniform mat4 u_projTrans;
8+
9+
varying vec4 v_color;
10+
varying vec2 v_texCoords;
11+
12+
void main()
13+
{
14+
v_color = a_color;
15+
v_color.a = v_color.a * (255.0/254.0);
16+
v_texCoords = a_texCoord0;
17+
gl_Position = u_projTrans * a_position;
18+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#version 300 es
2+
/** Copyright (c) 2022-2024, Harry Huang
3+
* At GPL-3.0 License
4+
*/
5+
6+
// Complex fragment shader for TwoColorPolygonBatch with outline and box shadow effect. (Low Quality Version)
7+
8+
precision mediump float;
9+
10+
in vec2 v_texCoords; // From VS
11+
uniform sampler2D u_texture; // From TCPB
12+
uniform vec4 u_outlineColor; // Required
13+
uniform float u_outlineWidth; // Required
14+
uniform float u_outlineAlpha; // Required
15+
uniform vec4 u_shadowColor; // Required
16+
uniform ivec2 u_textureSize; // Required
17+
uniform float u_alpha; // Required
18+
19+
out vec4 fragColor;
20+
21+
const float c_alphaLow = 0.1;
22+
const float c_alphaHigh = 0.9;
23+
const float c_seamCoef = 0.6;
24+
const float c_outlineOverstate = 10.0;
25+
const float c_shadowOffset = 2.0;
26+
27+
const vec2 OFFSETS[16] = vec2[16](
28+
vec2(-1.000, 0.000), // 0 (Left) - Actually 180, but starting here for comparison
29+
vec2(-0.924, -0.383), // 22.5
30+
vec2(-0.707, -0.707), // 45 (Down-Left)
31+
vec2(-0.383, -0.924), // 67.5
32+
vec2( 0.000, -1.000), // 90 (Down)
33+
vec2( 0.383, -0.924), // 112.5
34+
vec2( 0.707, -0.707), // 135 (Down-Right)
35+
vec2( 0.924, -0.383), // 157.5
36+
vec2( 1.000, 0.000), // 180 (Right) - Actually 0
37+
vec2( 0.924, 0.383), // 202.5
38+
vec2( 0.707, 0.707), // 225 (Up-Right)
39+
vec2( 0.383, 0.924), // 247.5
40+
vec2( 0.000, 1.000), // 270 (Up)
41+
vec2(-0.383, 0.924), // 292.5
42+
vec2(-0.707, 0.707), // 315 (Up-Left)
43+
vec2(-0.924, 0.383) // 337.5
44+
);
45+
46+
vec4 getSimpleSampleSum(float width) {
47+
vec4 sum = vec4(0.0);
48+
for (int i = 0; i < OFFSETS.length(); i++) {
49+
sum += texture(u_texture, v_texCoords + OFFSETS[i] * width / vec2(u_textureSize));
50+
}
51+
return sum;
52+
}
53+
54+
vec4 getOutlined(vec4 sum, vec4 texColor) {
55+
if (u_outlineColor.a > 0.0 && u_outlineWidth > 0.0 && u_outlineAlpha > 0.0) {
56+
vec2 relOutlineWidth = vec2(1.0) / vec2(u_textureSize) * u_outlineWidth;
57+
vec4 neighbor = sum * c_outlineOverstate;
58+
if (neighbor.a > c_alphaLow) {
59+
texColor.rgb = u_outlineColor.rgb;
60+
texColor.a = min(1.0, neighbor.a) * u_outlineColor.a * u_outlineAlpha;
61+
}
62+
}
63+
return texColor;
64+
}
65+
66+
vec4 getBoxShadow(vec4 texColor) {
67+
if (u_shadowColor.a > 0.0) {
68+
// Sample around to get maximum shadow alpha from neighbors
69+
vec4 shadowSum = getSimpleSampleSum(c_shadowOffset);
70+
float maxShadowAlpha = clamp(shadowSum.a, 0.0, 1.0);
71+
// Only apply shadow where the current pixel is transparent/semi-transparent
72+
// and there are opaque pixels nearby
73+
if (maxShadowAlpha > c_alphaLow && texColor.a < c_alphaHigh) {
74+
float shadowAlpha = maxShadowAlpha * u_shadowColor.a;
75+
// Blend shadow with current texColor using "over" compositing
76+
// Shadow sits behind, so only fill where texColor is not already visible
77+
float blendFactor = shadowAlpha * (1.0 - texColor.a);
78+
texColor.rgb = mix(texColor.rgb, u_shadowColor.rgb, blendFactor);
79+
texColor.a = texColor.a + blendFactor;
80+
}
81+
}
82+
return texColor;
83+
}
84+
85+
void main() {
86+
vec4 texColor = texture(u_texture, v_texCoords);
87+
88+
if (texColor.a < c_alphaHigh) {
89+
if (texColor.a < c_alphaLow) {
90+
// Outline effect
91+
texColor = getOutlined(getSimpleSampleSum(u_outlineWidth),texColor);
92+
}
93+
// Box shadow effect
94+
texColor = getBoxShadow(texColor);
95+
} else {
96+
// No effect
97+
}
98+
99+
// Ultimate composing
100+
fragColor = texColor;
101+
fragColor.a *= u_alpha;
102+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#version 300 es
2+
3+
in vec4 a_position;
4+
in vec4 a_color;
5+
in vec2 a_texCoord0;
6+
7+
uniform mat4 u_projTrans;
8+
9+
out vec4 v_color;
10+
out vec2 v_texCoords;
11+
12+
const float c_lightAlphaCoef = 255.0 / 254.0;
13+
14+
void main()
15+
{
16+
v_color = a_color;
17+
v_color.a = v_color.a * c_lightAlphaCoef;
18+
v_texCoords = a_texCoord0;
19+
gl_Position = u_projTrans * a_position;
20+
}

0 commit comments

Comments
 (0)