mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
graphicsdriver: Optimize shaders for the case of FILTER_SCREEN
Assume a color matrix or color vertex values are not used when the filter is FILTER_SCREEN.
This commit is contained in:
parent
cbb0a1da95
commit
3aa6eb3a66
@ -115,10 +115,10 @@ inline float2 AdjustTexelByAddress<ADDRESS_REPEAT>(float2 p, float4 tex_region)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<uint8_t filter, uint8_t address>
|
template<uint8_t filter, uint8_t address>
|
||||||
struct GetColorFromTexel;
|
struct ColorFromTexel;
|
||||||
|
|
||||||
template<uint8_t address>
|
template<uint8_t address>
|
||||||
struct GetColorFromTexel<FILTER_NEAREST, address> {
|
struct ColorFromTexel<FILTER_NEAREST, address> {
|
||||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||||
float2 p = AdjustTexelByAddress<address>(v.tex, v.tex_region);
|
float2 p = AdjustTexelByAddress<address>(v.tex, v.tex_region);
|
||||||
if (v.tex_region[0] <= p.x &&
|
if (v.tex_region[0] <= p.x &&
|
||||||
@ -133,7 +133,7 @@ struct GetColorFromTexel<FILTER_NEAREST, address> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<uint8_t address>
|
template<uint8_t address>
|
||||||
struct GetColorFromTexel<FILTER_LINEAR, address> {
|
struct ColorFromTexel<FILTER_LINEAR, address> {
|
||||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||||
constexpr sampler texture_sampler(filter::nearest);
|
constexpr sampler texture_sampler(filter::nearest);
|
||||||
const float2 texel_size = 1 / source_size;
|
const float2 texel_size = 1 / source_size;
|
||||||
@ -172,7 +172,7 @@ struct GetColorFromTexel<FILTER_LINEAR, address> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<uint8_t address>
|
template<uint8_t address>
|
||||||
struct GetColorFromTexel<FILTER_SCREEN, address> {
|
struct ColorFromTexel<FILTER_SCREEN, address> {
|
||||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||||
constexpr sampler texture_sampler(filter::nearest);
|
constexpr sampler texture_sampler(filter::nearest);
|
||||||
const float2 texel_size = 1 / source_size;
|
const float2 texel_size = 1 / source_size;
|
||||||
@ -193,14 +193,15 @@ struct GetColorFromTexel<FILTER_SCREEN, address> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<bool useColorM, uint8_t filter, uint8_t address>
|
template<bool useColorM, uint8_t filter, uint8_t address>
|
||||||
float4 FragmentShaderImpl(
|
struct FragmentShaderImpl {
|
||||||
|
inline float4 Do(
|
||||||
VertexOut v,
|
VertexOut v,
|
||||||
texture2d<float> texture,
|
texture2d<float> texture,
|
||||||
constant float2& source_size,
|
constant float2& source_size,
|
||||||
constant float4x4& color_matrix_body,
|
constant float4x4& color_matrix_body,
|
||||||
constant float4& color_matrix_translation,
|
constant float4& color_matrix_translation,
|
||||||
constant float& scale) {
|
constant float& scale) {
|
||||||
float4 c = GetColorFromTexel<filter, address>().Do(v, texture, source_size, scale);
|
float4 c = ColorFromTexel<filter, address>().Do(v, texture, source_size, scale);
|
||||||
if (useColorM) {
|
if (useColorM) {
|
||||||
c.rgb /= c.a + (1.0 - sign(c.a));
|
c.rgb /= c.a + (1.0 - sign(c.a));
|
||||||
c = (color_matrix_body * c) + color_matrix_translation;
|
c = (color_matrix_body * c) + color_matrix_translation;
|
||||||
@ -212,7 +213,21 @@ float4 FragmentShaderImpl(
|
|||||||
}
|
}
|
||||||
c = min(c, c.a);
|
c = min(c, c.a);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool useColorM, uint8_t address>
|
||||||
|
struct FragmentShaderImpl<useColorM, FILTER_SCREEN, address> {
|
||||||
|
inline float4 Do(
|
||||||
|
VertexOut v,
|
||||||
|
texture2d<float> texture,
|
||||||
|
constant float2& source_size,
|
||||||
|
constant float4x4& color_matrix_body,
|
||||||
|
constant float4& color_matrix_translation,
|
||||||
|
constant float& scale) {
|
||||||
|
return ColorFromTexel<FILTER_SCREEN, address>().Do(v, texture, source_size, scale);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Define Foo and FooCp macros to force macro replacement.
|
// Define Foo and FooCp macros to force macro replacement.
|
||||||
// See "6.10.3.1 Argument substitution" in ISO/IEC 9899.
|
// See "6.10.3.1 Argument substitution" in ISO/IEC 9899.
|
||||||
@ -228,7 +243,7 @@ float4 FragmentShaderImpl(
|
|||||||
constant float4x4& color_matrix_body [[buffer(3)]], \
|
constant float4x4& color_matrix_body [[buffer(3)]], \
|
||||||
constant float4& color_matrix_translation [[buffer(4)]], \
|
constant float4& color_matrix_translation [[buffer(4)]], \
|
||||||
constant float& scale [[buffer(5)]]) { \
|
constant float& scale [[buffer(5)]]) { \
|
||||||
return FragmentShaderImpl<useColorM, filter, address>( \
|
return FragmentShaderImpl<useColorM, filter, address>().Do( \
|
||||||
v, texture, source_size, color_matrix_body, color_matrix_translation, scale); \
|
v, texture, source_size, color_matrix_body, color_matrix_translation, scale); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,12 +197,13 @@ void main(void) {
|
|||||||
|
|
||||||
#if defined(FILTER_NEAREST)
|
#if defined(FILTER_NEAREST)
|
||||||
pos = adjustTexelByAddress(pos, varying_tex_region);
|
pos = adjustTexelByAddress(pos, varying_tex_region);
|
||||||
color = vec4(0, 0, 0, 0);
|
|
||||||
if (varying_tex_region[0] <= pos.x &&
|
if (varying_tex_region[0] <= pos.x &&
|
||||||
varying_tex_region[1] <= pos.y &&
|
varying_tex_region[1] <= pos.y &&
|
||||||
pos.x < varying_tex_region[2] &&
|
pos.x < varying_tex_region[2] &&
|
||||||
pos.y < varying_tex_region[3]) {
|
pos.y < varying_tex_region[3]) {
|
||||||
color = texture2D(texture, pos);
|
color = texture2D(texture, pos);
|
||||||
|
} else {
|
||||||
|
color = vec4(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -240,6 +241,7 @@ void main(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(FILTER_SCREEN)
|
#if defined(FILTER_SCREEN)
|
||||||
|
|
||||||
highp vec2 p0 = pos - texel_size / 2.0 / scale;
|
highp vec2 p0 = pos - texel_size / 2.0 / scale;
|
||||||
highp vec2 p1 = pos + texel_size / 2.0 / scale;
|
highp vec2 p1 = pos + texel_size / 2.0 / scale;
|
||||||
|
|
||||||
@ -253,8 +255,10 @@ void main(void) {
|
|||||||
|
|
||||||
vec2 rateCenter = vec2(1.0, 1.0) - texel_size / 2.0 / scale;
|
vec2 rateCenter = vec2(1.0, 1.0) - texel_size / 2.0 / scale;
|
||||||
vec2 rate = clamp(((fract(p0 * source_size) - rateCenter) * scale) + rateCenter, 0.0, 1.0);
|
vec2 rate = clamp(((fract(p0 * source_size) - rateCenter) * scale) + rateCenter, 0.0, 1.0);
|
||||||
color = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
|
gl_FragColor = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
|
||||||
#endif
|
// Assume that a color matrix and color vector values are not used with FILTER_SCREEN.
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#if defined(USE_COLOR_MATRIX)
|
#if defined(USE_COLOR_MATRIX)
|
||||||
// Un-premultiply alpha.
|
// Un-premultiply alpha.
|
||||||
@ -273,6 +277,9 @@ void main(void) {
|
|||||||
color = min(color, color.a);
|
color = min(color, color.a);
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user