vk,gl: use w=1 in shaders. Fix translucent modvols

Use w=1 to avoid multiply/divide of xy as in dx9
Disable rendering when video output disabled
Use original w value in pixel struct to avoid precision loss (samsptk)
vk oit: missing memory barrier was producing Tr modvol glitches (JSR)
gl oit: Tr modvol needs full vertex shader
This commit is contained in:
Flyinghead 2021-11-07 18:21:44 +01:00
parent 5209623064
commit 06ef0e5fdc
9 changed files with 230 additions and 155 deletions

View File

@ -190,6 +190,8 @@ void main(void)
)";
static const char *tr_modvol_shader_source = R"(
noperspective in vec3 vtx_uv;
// Must match ModifierVolumeMode enum values
#define MV_XOR 0
#define MV_OR 1
@ -198,9 +200,6 @@ static const char *tr_modvol_shader_source = R"(
void main(void)
{
#if MV_MODE == MV_XOR || MV_MODE == MV_OR
setFragDepth();
#endif
ivec2 coords = ivec2(gl_FragCoord.xy);
uint idx = imageLoad(abufferPointerImg, coords).x;
@ -212,10 +211,10 @@ void main(void)
if (getShadowEnable(pp))
{
#if MV_MODE == MV_XOR
if (gl_FragDepth >= pixel.depth)
if (vtx_uv.z >= pixel.depth)
atomicXor(pixels[idx].seq_num, SHADOW_STENCIL);
#elif MV_MODE == MV_OR
if (gl_FragDepth >= pixel.depth)
if (vtx_uv.z >= pixel.depth)
atomicOr(pixels[idx].seq_num, SHADOW_STENCIL);
#elif MV_MODE == MV_INCLUSION
uint prev_val = atomicAnd(pixels[idx].seq_num, ~(SHADOW_STENCIL));
@ -318,7 +317,8 @@ void initABuffer()
for (int mode = 0; mode < ModeCount; mode++)
{
modVolShader.setConstant("MV_MODE", mode);
gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], modVolShader.generate().c_str(), vertexShader.generate().c_str());
g_abuffer_tr_modvol_shaders[mode].pp_Gouraud = false;
gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], modVolShader.generate().c_str(), nullptr);
}
}
if (g_quadBuffer == 0)

View File

@ -54,13 +54,13 @@ static const char* VertexShaderSource = R"(
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#define INTERPOLATION noperspective
#endif
/* Vertex constants*/
uniform vec4 scale;
// Uniforms
uniform mat4 normal_matrix;
/* Vertex input */
// Input
in vec4 in_pos;
in vec4 in_base;
in vec4 in_offs;
@ -68,26 +68,33 @@ in vec2 in_uv;
in vec4 in_base1;
in vec4 in_offs1;
in vec2 in_uv1;
/* output */
// Output
INTERPOLATION out vec4 vtx_base;
INTERPOLATION out vec4 vtx_offs;
out vec2 vtx_uv;
noperspective out vec3 vtx_uv;
INTERPOLATION out vec4 vtx_base1;
INTERPOLATION out vec4 vtx_offs1;
out vec2 vtx_uv1;
noperspective out vec2 vtx_uv1;
void main()
{
vec4 vpos = normal_matrix * in_pos;
vtx_base = in_base;
vtx_offs = in_offs;
vtx_uv = in_uv;
vtx_uv = vec3(in_uv * vpos.z, vpos.z);
vtx_base1 = in_base1;
vtx_offs1 = in_offs1;
vtx_uv1 = in_uv1;
vec4 vpos = normal_matrix * in_pos;
vtx_uv1 = in_uv1 * vpos.z;
#if pp_Gouraud == 1
vtx_base *= vpos.z;
vtx_offs *= vpos.z;
vtx_base1 *= vpos.z;
vtx_offs1 *= vpos.z;
#endif
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
vpos.xy *= vpos.w;
vpos.w = 1.0;
vpos.z = 0.0;
gl_Position = vpos;
}
)";
@ -112,10 +119,10 @@ out vec4 FragColor;
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#define INTERPOLATION noperspective
#endif
/* Shader program params*/
// Uniforms
uniform float cp_AlphaTestValue;
uniform vec4 pp_ClipTest;
uniform vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT;
@ -142,13 +149,13 @@ uniform int shading_instr[2];
uniform int fog_control[2];
#endif
/* Vertex input*/
// Input
INTERPOLATION in vec4 vtx_base;
INTERPOLATION in vec4 vtx_offs;
in vec2 vtx_uv;
noperspective in vec3 vtx_uv;
INTERPOLATION in vec4 vtx_base1;
INTERPOLATION in vec4 vtx_offs1;
in vec2 vtx_uv1;
noperspective in vec2 vtx_uv1;
float fog_mode2(float w)
{
@ -171,9 +178,9 @@ vec4 fog_clamp(vec4 col)
#if pp_Palette == 1
vec4 palettePixel(sampler2D tex, vec2 coords)
vec4 palettePixel(sampler2D tex, vec3 coords)
{
int color_idx = int(floor(texture(tex, coords).r * 255.0 + 0.5)) + palette_index;
int color_idx = int(floor(textureProj(tex, coords).r * 255.0 + 0.5)) + palette_index;
ivec2 c = ivec2(color_idx % 32, color_idx / 32);
return texelFetch(palette, c, 0);
}
@ -182,7 +189,7 @@ vec4 palettePixel(sampler2D tex, vec2 coords)
void main()
{
setFragDepth();
setFragDepth(vtx_uv.z);
#if PASS == PASS_OIT
// Manual depth testing
@ -200,7 +207,6 @@ void main()
vec4 color = vtx_base;
vec4 offset = vtx_offs;
vec2 uv = vtx_uv;
bool area1 = false;
ivec2 cur_blend_mode = blend_mode[0];
@ -214,7 +220,6 @@ void main()
if (stencil.r == 0x81u) {
color = vtx_base1;
offset = vtx_offs1;
uv = vtx_uv1;
area1 = true;
cur_blend_mode = blend_mode[1];
cur_use_alpha = use_alpha[1];
@ -224,6 +229,10 @@ void main()
}
#endif
#endif
#if pp_Gouraud == 1
color /= vtx_uv.z;
offset /= vtx_uv.z;
#endif
#if pp_UseAlpha==0 || pp_TwoVolumes == 1
IF(!cur_use_alpha)
@ -231,27 +240,27 @@ void main()
#endif
#if pp_FogCtrl==3 || pp_TwoVolumes == 1 // LUT Mode 2
IF(cur_fog_control == 3)
color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
color = vec4(sp_FOG_COL_RAM.rgb, fog_mode2(vtx_uv.z));
#endif
#if pp_Texture==1
{
vec4 texcol;
#if pp_Palette == 0
if (area1)
texcol = texture(tex1, uv);
texcol = textureProj(tex1, vec3(vtx_uv1.xy, vtx_uv.z));
else
texcol = texture(tex0, uv);
texcol = textureProj(tex0, vtx_uv);
#else
if (area1)
texcol = palettePixel(tex1, uv);
texcol = palettePixel(tex1, vec3(vtx_uv1.xy, vtx_uv.z));
else
texcol = palettePixel(tex0, uv);
texcol = palettePixel(tex0, vtx_uv);
#endif
#if pp_BumpMap == 1
float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0;
float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0;
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0);
texcol.a = clamp(offset.a + offset.r * sin(s) + offset.g * cos(s) * cos(r - 2.0 * PI * offset.b), 0.0, 1.0);
texcol.rgb = vec3(1.0, 1.0, 1.0);
#else
#if pp_IgnoreTexA==1 || pp_TwoVolumes == 1
@ -309,7 +318,7 @@ void main()
#if pp_FogCtrl==0 || pp_TwoVolumes == 1 // LUT
IF(cur_fog_control == 0)
{
color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
color.rgb = mix(color.rgb, sp_FOG_COL_RAM.rgb, fog_mode2(vtx_uv.z));
}
#endif
#if pp_Offset==1 && pp_BumpMap == 0 && (pp_FogCtrl == 1 || pp_TwoVolumes == 1) // Per vertex
@ -385,7 +394,7 @@ void main()
Pixel pixel;
pixel.color = packColors(clamp(color, vec4(0.0), vec4(1.0)));
pixel.depth = gl_FragDepth;
pixel.depth = vtx_uv.z;
pixel.seq_num = uint(pp_Number);
pixel.next = imageAtomicExchange(abufferPointerImg, coords, idx);
pixels[idx] = pixel;
@ -402,9 +411,11 @@ void main()
)";
static const char* ModifierVolumeShader = R"(
noperspective in vec3 vtx_uv;
void main()
{
setFragDepth();
setFragDepth(vtx_uv.z);
}
)";
@ -558,7 +569,7 @@ static void create_modvol_shader()
{
if (gl4.modvol_shader.program != 0)
return;
Vertex4Source vertexShader(true);
Vertex4Source vertexShader(false);
OpenGl4Source fragmentShader;
fragmentShader.addSource(ShaderHeader)
.addSource(ModifierVolumeShader);
@ -713,8 +724,6 @@ static bool RenderFrame(int width, int height)
}
resize(rendering_width, rendering_height);
//DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]);
//VERT and RAM fog color constants
u8* fog_colvert_bgra=(u8*)&FOG_COL_VERT;
u8* fog_colram_bgra=(u8*)&FOG_COL_RAM;
@ -774,7 +783,14 @@ static bool RenderFrame(int width, int height)
if (!is_rtt)
glcache.ClearColor(VO_BORDER_COL.Red / 255.f, VO_BORDER_COL.Green / 255.f, VO_BORDER_COL.Blue / 255.f, 1.f);
if (!pvrrc.isRenderFramebuffer)
if (!is_rtt && (FB_R_CTRL.fb_enable == 0 || VO_CONTROL.blank_video == 1))
{
// Video output disabled
glBindFramebuffer(GL_FRAMEBUFFER, output_fbo);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT);
}
else if (!pvrrc.isRenderFramebuffer)
{
//Main VBO
glBindBuffer(GL_ARRAY_BUFFER, gl4.vbo.geometry); glCheck();

View File

@ -38,9 +38,9 @@ struct Pixel { \n\
#define DST_ALPHA 6 \n\
#define INVERSE_DST_ALPHA 7 \n\
\n\
void setFragDepth(void) \n\
void setFragDepth(float z) \n\
{ \n\
float w = 100000.0 * gl_FragCoord.w; \n\
float w = 100000.0 * z; \n\
gl_FragDepth = log2(1.0 + w) / 34.0; \n\
} \n\
\n\

View File

@ -68,16 +68,22 @@ const char *PixelCompatShader = R"(
)";
static const char* GouraudSource = R"(
#if (TARGET_GL == GL3 || TARGET_GL == GLES3) && pp_Gouraud == 0
#if TARGET_GL == GL3 || TARGET_GL == GLES3
#define NOPERSPECTIVE noperspective
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION noperspective
#endif
#else
#define NOPERSPECTIVE
#define INTERPOLATION
#endif
)";
static const char* VertexShaderSource = R"(
/* Vertex constants*/
uniform highp vec4 depth_scale;
uniform highp vec4 depth_scale;
uniform highp mat4 normal_matrix;
uniform highp float sp_FOG_DENSITY;
@ -89,25 +95,27 @@ in highp vec2 in_uv;
/* output */
INTERPOLATION out lowp vec4 vtx_base;
INTERPOLATION out lowp vec4 vtx_offs;
out highp vec2 vtx_uv;
#if TARGET_GL == GLES2
out highp float fog_depth;
#endif
NOPERSPECTIVE out highp vec3 vtx_uv;
void main()
{
highp vec4 vpos = normal_matrix * in_pos;
vtx_base = in_base;
vtx_offs = in_offs;
vtx_uv = in_uv;
highp vec4 vpos = normal_matrix * in_pos;
#if TARGET_GL == GLES2
vtx_uv = vec3(in_uv, vpos.z * sp_FOG_DENSITY);
vpos.w = 1.0 / vpos.z;
#if TARGET_GL != GLES2
vpos.z = vpos.w;
#else
fog_depth = vpos.z * sp_FOG_DENSITY;
vpos.z = depth_scale.x + depth_scale.y * vpos.w;
#endif
vpos.xy *= vpos.w;
#else
#if pp_Gouraud == 1
vtx_base *= vpos.z;
vtx_offs *= vpos.z;
#endif
vtx_uv = vec3(in_uv * vpos.z, vpos.z);
vpos.w = 1.0;
vpos.z = 0.0;
#endif
gl_Position = vpos;
}
)";
@ -133,15 +141,12 @@ uniform mediump int palette_index;
/* Vertex input*/
INTERPOLATION in lowp vec4 vtx_base;
INTERPOLATION in lowp vec4 vtx_offs;
in highp vec2 vtx_uv;
#if TARGET_GL == GLES2
in highp float fog_depth;
#endif
NOPERSPECTIVE in highp vec3 vtx_uv;
lowp float fog_mode2(highp float w)
{
#if TARGET_GL == GLES2
highp float z = clamp(fog_depth, 1.0, 255.9999);
highp float z = clamp(vtx_uv.z, 1.0, 255.9999);
#else
highp float z = clamp(w * sp_FOG_DENSITY, 1.0, 255.9999);
#endif
@ -163,13 +168,14 @@ highp vec4 fog_clamp(lowp vec4 col)
#if pp_Palette == 1
lowp vec4 palettePixel(highp vec2 coords)
lowp vec4 palettePixel(highp vec3 coords)
{
highp int color_idx = int(floor(texture(tex, coords).FOG_CHANNEL * 255.0 + 0.5)) + palette_index;
#if TARGET_GL == GLES2 || TARGET_GL == GL2
highp int color_idx = int(floor(texture(tex, coords.xy).FOG_CHANNEL * 255.0 + 0.5)) + palette_index;
highp vec2 c = vec2((mod(float(color_idx), 32.0) * 2.0 + 1.0) / 64.0, (float(color_idx / 32) * 2.0 + 1.0) / 64.0);
return texture(palette, c);
#else
highp int color_idx = int(floor(textureProj(tex, coords).FOG_CHANNEL * 255.0 + 0.5)) + palette_index;
highp ivec2 c = ivec2(color_idx % 32, color_idx / 32);
return texelFetch(palette, c, 0);
#endif
@ -177,6 +183,12 @@ lowp vec4 palettePixel(highp vec2 coords)
#endif
#if TARGET_GL == GLES2
#define depth gl_FragCoord.w
#else
#define depth vtx_uv.z
#endif
void main()
{
// Clip inside the box
@ -186,17 +198,26 @@ void main()
discard;
#endif
lowp vec4 color=vtx_base;
lowp vec4 color = vtx_base;
lowp vec4 offset = vtx_offs;
#if pp_Gouraud == 1 && TARGET_GL != GLES2
color /= vtx_uv.z;
offset /= vtx_uv.z;
#endif
#if pp_UseAlpha==0
color.a=1.0;
#endif
#if pp_FogCtrl==3
color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
color = vec4(sp_FOG_COL_RAM.rgb, fog_mode2(depth));
#endif
#if pp_Texture==1
{
#if pp_Palette == 0
lowp vec4 texcol = texture(tex, vtx_uv);
#if TARGET_GL == GLES2 || TARGET_GL == GL2
lowp vec4 texcol = texture(tex, vtx_uv.xy);
#else
lowp vec4 texcol = textureProj(tex, vtx_uv);
#endif
#else
lowp vec4 texcol = palettePixel(vtx_uv);
#endif
@ -204,7 +225,7 @@ void main()
#if pp_BumpMap == 1
highp float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0;
highp float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0;
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0);
texcol.a = clamp(offset.a + offset.r * sin(s) + offset.g * cos(s) * cos(r - 2.0 * PI * offset.b), 0.0, 1.0);
texcol.rgb = vec3(1.0, 1.0, 1.0);
#else
#if pp_IgnoreTexA==1
@ -240,9 +261,7 @@ void main()
#endif
#if pp_Offset==1 && pp_BumpMap == 0
{
color.rgb+=vtx_offs.rgb;
}
color.rgb += offset.rgb;
#endif
}
#endif
@ -250,26 +269,22 @@ void main()
color = fog_clamp(color);
#if pp_FogCtrl == 0
{
color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
}
color.rgb = mix(color.rgb, sp_FOG_COL_RAM.rgb, fog_mode2(depth));
#endif
#if pp_FogCtrl == 1 && pp_Offset==1 && pp_BumpMap == 0
{
color.rgb=mix(color.rgb,sp_FOG_COL_VERT.rgb,vtx_offs.a);
}
color.rgb = mix(color.rgb, sp_FOG_COL_VERT.rgb, offset.a);
#endif
#if pp_TriLinear == 1
color *= trilinear_alpha;
#endif
//color.rgb=vec3(gl_FragCoord.w * sp_FOG_DENSITY / 128.0);
//color.rgb = vec3(vtx_uv.z * sp_FOG_DENSITY / 128.0);
#if TARGET_GL != GLES2
highp float w = gl_FragCoord.w * 100000.0;
highp float w = vtx_uv.z * 100000.0;
gl_FragDepth = log2(1.0 + w) / 34.0;
#endif
gl_FragColor =color;
gl_FragColor = color;
}
)";
@ -277,10 +292,12 @@ static const char* ModifierVolumeShader = R"(
uniform lowp float sp_ShaderColor;
/* Vertex input*/
NOPERSPECTIVE in highp vec3 vtx_uv;
void main()
{
#if TARGET_GL != GLES2
highp float w = gl_FragCoord.w * 100000.0;
highp float w = vtx_uv.z * 100000.0;
gl_FragDepth = log2(1.0 + w) / 34.0;
#endif
gl_FragColor=vec4(0.0, 0.0, 0.0, sp_ShaderColor);
@ -832,10 +849,11 @@ static void create_modvol_shader()
{
if (gl.modvol_shader.program != 0)
return;
VertexSource vertexShader(true);
VertexSource vertexShader(false);
OpenGlSource fragmentShader;
fragmentShader.addSource(PixelCompatShader)
.addSource(GouraudSource)
.addSource(ModifierVolumeShader);
gl.modvol_shader.program = gl_CompileAndLink(vertexShader.generate().c_str(), fragmentShader.generate().c_str());
@ -1236,10 +1254,14 @@ bool RenderFrame(int width, int height)
if (!is_rtt)
glcache.ClearColor(VO_BORDER_COL.Red / 255.f, VO_BORDER_COL.Green / 255.f, VO_BORDER_COL.Blue / 255.f, 1.f);
//move vertex to gpu
if (!pvrrc.isRenderFramebuffer)
if (!is_rtt && (FB_R_CTRL.fb_enable == 0 || VO_CONTROL.blank_video == 1))
{
// Video output disabled
glClear(GL_COLOR_BUFFER_BIT);
}
else if (!pvrrc.isRenderFramebuffer)
{
//move vertex to gpu
//Main VBO
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();

View File

@ -332,6 +332,11 @@ bool Drawer::Draw(const Texture *fogTexture, const Texture *paletteTexture)
currentScissor = vk::Rect2D();
vk::CommandBuffer cmdBuffer = BeginRenderPass();
if (!pvrrc.isRTT && (FB_R_CTRL.fb_enable == 0 || VO_CONTROL.blank_video == 1))
{
// Video output disabled
return true;
}
SetProvokingVertices();

View File

@ -163,6 +163,12 @@ void OITDrawer::DrawModifierVolumes(const vk::CommandBuffer& cmdBuffer, int firs
cmdBuffer.draw((param.first + param.count - mod_base) * 3, 1, mod_base * 3, 0);
mod_base = -1;
if (Translucent)
{
vk::MemoryBarrier barrier(vk::AccessFlagBits::eShaderWrite, vk::AccessFlagBits::eShaderRead);
cmdBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader, vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlagBits::eByRegion, barrier, nullptr, nullptr);
}
}
}
const vk::DeviceSize offset = 0;
@ -332,27 +338,35 @@ bool OITDrawer::Draw(const Texture *fogTexture, const Texture *paletteTexture)
targetFramebuffer, viewport, clear_colors.size(), clear_colors.data()),
vk::SubpassContents::eInline);
// Depth + stencil subpass
DrawList(cmdBuffer, ListType_Opaque, false, Pass::Depth, pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count);
DrawList(cmdBuffer, ListType_Punch_Through, false, Pass::Depth, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count);
if (!pvrrc.isRTT && (FB_R_CTRL.fb_enable == 0 || VO_CONTROL.blank_video == 1))
{
// Video output disabled
cmdBuffer.nextSubpass(vk::SubpassContents::eInline);
}
else
{
// Depth + stencil subpass
DrawList(cmdBuffer, ListType_Opaque, false, Pass::Depth, pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count);
DrawList(cmdBuffer, ListType_Punch_Through, false, Pass::Depth, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count);
DrawModifierVolumes<false>(cmdBuffer, previous_pass.mvo_count, current_pass.mvo_count - previous_pass.mvo_count);
DrawModifierVolumes<false>(cmdBuffer, previous_pass.mvo_count, current_pass.mvo_count - previous_pass.mvo_count);
// Color subpass
cmdBuffer.nextSubpass(vk::SubpassContents::eInline);
// Color subpass
cmdBuffer.nextSubpass(vk::SubpassContents::eInline);
// OP + PT
DrawList(cmdBuffer, ListType_Opaque, false, Pass::Color, pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count);
DrawList(cmdBuffer, ListType_Punch_Through, false, Pass::Color, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count);
// OP + PT
DrawList(cmdBuffer, ListType_Opaque, false, Pass::Color, pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count);
DrawList(cmdBuffer, ListType_Punch_Through, false, Pass::Color, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count);
// TR
if (current_pass.autosort)
{
if (!oitBuffers->isFirstFrameAfterInit())
DrawList(cmdBuffer, ListType_Translucent, true, Pass::OIT, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count);
}
else
DrawList(cmdBuffer, ListType_Translucent, false, Pass::Color, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count);
// TR
if (current_pass.autosort)
{
if (!oitBuffers->isFirstFrameAfterInit())
DrawList(cmdBuffer, ListType_Translucent, true, Pass::OIT, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count);
}
else
DrawList(cmdBuffer, ListType_Translucent, false, Pass::Color, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count);
}
// Final subpass
cmdBuffer.nextSubpass(vk::SubpassContents::eInline);

View File

@ -38,23 +38,28 @@ layout (location = 6) in mediump vec2 in_uv1;
layout (location = 0) INTERPOLATION out lowp vec4 vtx_base;
layout (location = 1) INTERPOLATION out lowp vec4 vtx_offs;
layout (location = 2) out mediump vec2 vtx_uv;
layout (location = 2) noperspective out mediump vec3 vtx_uv;
layout (location = 3) INTERPOLATION out lowp vec4 vtx_base1; // New for OIT, only for OP/PT with 2-volume
layout (location = 4) INTERPOLATION out lowp vec4 vtx_offs1;
layout (location = 5) out mediump vec2 vtx_uv1;
layout (location = 5) noperspective out mediump vec2 vtx_uv1;
void main()
{
vec4 vpos = uniformBuffer.normal_matrix * in_pos;
vtx_base = vec4(in_base) / 255.0;
vtx_offs = vec4(in_offs) / 255.0;
vtx_uv = in_uv;
vtx_base1 = vec4(in_base1) / 255.0; // New for OIT, only for OP/PT with 2-volume
vtx_uv = vec3(in_uv * vpos.z, vpos.z);
vtx_base1 = vec4(in_base1) / 255.0;
vtx_offs1 = vec4(in_offs1) / 255.0;
vtx_uv1 = in_uv1;
vec4 vpos = uniformBuffer.normal_matrix * in_pos;
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
vpos.xy *= vpos.w;
vtx_uv1 = in_uv1 * vpos.z;
#if pp_Gouraud == 1
vtx_base *= vpos.z;
vtx_offs *= vpos.z;
vtx_base1 *= vpos.z;
vtx_offs1 *= vpos.z;
#endif
vpos.w = 1.0;
vpos.z = 0.0;
gl_Position = vpos;
}
)";
@ -165,10 +170,10 @@ layout (input_attachment_index = 0, set = 0, binding = 5) uniform subpassInput D
// Vertex input
layout (location = 0) INTERPOLATION in lowp vec4 vtx_base;
layout (location = 1) INTERPOLATION in lowp vec4 vtx_offs;
layout (location = 2) in mediump vec2 vtx_uv;
layout (location = 2) noperspective in mediump vec3 vtx_uv;
layout (location = 3) INTERPOLATION in lowp vec4 vtx_base1; // new for OIT. Only if 2 vol
layout (location = 4) INTERPOLATION in lowp vec4 vtx_offs1;
layout (location = 5) in mediump vec2 vtx_uv1;
layout (location = 5) noperspective in mediump vec2 vtx_uv1;
#if pp_FogCtrl != 2 || pp_TwoVolumes == 1
layout (set = 0, binding = 2) uniform sampler2D fog_table;
@ -196,9 +201,9 @@ vec4 colorClamp(vec4 col)
#if pp_Palette == 1
vec4 palettePixel(sampler2D tex, vec2 coords)
vec4 palettePixel(sampler2D tex, vec3 coords)
{
vec4 c = vec4(texture(tex, coords).r * 255.0 / 1023.0 + pushConstants.palette_index, 0.5, 0.0, 0.0);
vec4 c = vec4(textureProj(tex, coords).r * 255.0 / 1023.0 + pushConstants.palette_index, 0.5, 0.0, 0.0);
return texture(palette, c.xy);
}
@ -206,7 +211,7 @@ vec4 palettePixel(sampler2D tex, vec2 coords)
void main()
{
setFragDepth();
setFragDepth(vtx_uv.z);
#if PASS == PASS_OIT
// Manual depth testing
@ -224,7 +229,6 @@ void main()
highp vec4 color = vtx_base;
lowp vec4 offset = vtx_offs;
mediump vec2 uv = vtx_uv;
bool area1 = false;
ivec2 cur_blend_mode = pushConstants.blend_mode0.xy;
@ -238,7 +242,6 @@ void main()
if (stencil.r == 0x81u) {
color = vtx_base1;
offset = vtx_offs1;
uv = vtx_uv1;
area1 = true;
cur_blend_mode = pushConstants.blend_mode1.xy;
cur_use_alpha = pushConstants.use_alpha1 != 0;
@ -248,6 +251,10 @@ void main()
}
#endif
#endif
#if pp_Gouraud == 1
color /= vtx_uv.z;
offset /= vtx_uv.z;
#endif
#if pp_UseAlpha == 0 || pp_TwoVolumes == 1
IF (!cur_use_alpha)
@ -255,7 +262,7 @@ void main()
#endif
#if pp_FogCtrl == 3 || pp_TwoVolumes == 1 // LUT Mode 2
IF (cur_fog_control == 3)
color = vec4(uniformBuffer.sp_FOG_COL_RAM.rgb, fog_mode2(gl_FragCoord.w));
color = vec4(uniformBuffer.sp_FOG_COL_RAM.rgb, fog_mode2(vtx_uv.z));
#endif
#if pp_Texture==1
{
@ -263,21 +270,21 @@ void main()
#if pp_TwoVolumes == 1
if (area1)
#if pp_Palette == 0
texcol = texture(tex1, uv);
texcol = textureProj(tex1, vec3(vtx_uv1, vtx_uv.z));
#else
texcol = palettePixel(tex1, uv);
texcol = palettePixel(tex1, vec3(vtx_uv1, vtx_uv.z));
#endif
else
#endif
#if pp_Palette == 0
texcol = texture(tex0, uv);
texcol = textureProj(tex0, vtx_uv);
#else
texcol = palettePixel(tex0, uv);
texcol = palettePixel(tex0, vtx_uv);
#endif
#if pp_BumpMap == 1
highp float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0;
highp float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0;
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0);
texcol.a = clamp(offset.a + offset.r * sin(s) + offset.g * cos(s) * cos(r - 2.0 * PI * offset.b), 0.0, 1.0);
texcol.rgb = vec3(1.0, 1.0, 1.0);
#else
#if pp_IgnoreTexA==1 || pp_TwoVolumes == 1
@ -335,7 +342,7 @@ void main()
#if pp_FogCtrl == 0 || pp_TwoVolumes == 1 // LUT
IF(cur_fog_control == 0)
{
color.rgb = mix(color.rgb, uniformBuffer.sp_FOG_COL_RAM.rgb, fog_mode2(gl_FragCoord.w));
color.rgb = mix(color.rgb, uniformBuffer.sp_FOG_COL_RAM.rgb, fog_mode2(vtx_uv.z));
}
#endif
#if pp_Offset==1 && pp_BumpMap == 0 && (pp_FogCtrl == 1 || pp_TwoVolumes == 1) // Per vertex
@ -347,7 +354,7 @@ void main()
color *= pushConstants.trilinearAlpha;
//color.rgb=vec3(gl_FragCoord.w * uniformBuffer.sp_FOG_DENSITY / 128.0);
//color.rgb = vec3(vtx_uv.z * uniformBuffer.sp_FOG_DENSITY / 128.0);
#if PASS == PASS_COLOR
FragColor = color;
@ -411,7 +418,7 @@ void main()
Pixel pixel;
pixel.color = packColors(clamp(color, vec4(0.0), vec4(1.0)));
pixel.depth = gl_FragDepth;
pixel.depth = vtx_uv.z;
pixel.seq_num = uint(pushConstants.pp_Number);
pixel.next = atomicExchange(abufferPointer.pointers[coords.x + coords.y * uniformBuffer.viewportWidth], idx);
PixelBuffer.pixels[idx] = pixel;
@ -421,9 +428,11 @@ void main()
)";
static const char OITModifierVolumeShader[] = R"(
layout (location = 0) noperspective in float depth;
void main()
{
setFragDepth();
setFragDepth(depth);
}
)";
@ -584,6 +593,8 @@ void main(void)
)";
static const char OITTranslucentModvolShaderSource[] = R"(
layout (location = 0) noperspective in float depth;
// Must match ModifierVolumeMode enum values
#define MV_XOR 0
#define MV_OR 1
@ -592,9 +603,6 @@ static const char OITTranslucentModvolShaderSource[] = R"(
void main()
{
#if MV_MODE == MV_XOR || MV_MODE == MV_OR
setFragDepth();
#endif
ivec2 coords = ivec2(gl_FragCoord.xy);
uint idx = abufferPointer.pointers[coords.x + coords.y * uniformBuffer.viewportWidth];
@ -606,10 +614,10 @@ void main()
if (getShadowEnable(pp))
{
#if MV_MODE == MV_XOR
if (gl_FragDepth >= pixel.depth)
if (depth >= pixel.depth)
atomicXor(PixelBuffer.pixels[idx].seq_num, SHADOW_STENCIL);
#elif MV_MODE == MV_OR
if (gl_FragDepth >= pixel.depth)
if (depth >= pixel.depth)
atomicOr(PixelBuffer.pixels[idx].seq_num, SHADOW_STENCIL);
#elif MV_MODE == MV_INCLUSION
uint prev_val = atomicAnd(PixelBuffer.pixels[idx].seq_num, ~(SHADOW_STENCIL));

View File

@ -36,17 +36,20 @@ layout (location = 3) in mediump vec2 in_uv;
layout (location = 0) INTERPOLATION out lowp vec4 vtx_base;
layout (location = 1) INTERPOLATION out lowp vec4 vtx_offs;
layout (location = 2) out mediump vec2 vtx_uv;
layout (location = 2) noperspective out mediump vec3 vtx_uv;
void main()
{
vec4 vpos = uniformBuffer.normal_matrix * in_pos;
vtx_base = vec4(in_base) / 255.0;
vtx_offs = vec4(in_offs) / 255.0;
vtx_uv = in_uv;
vec4 vpos = uniformBuffer.normal_matrix * in_pos;
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
vpos.xy *= vpos.w;
vtx_uv = vec3(in_uv * vpos.z, vpos.z);
#if pp_Gouraud == 1
vtx_base *= vpos.z;
vtx_offs *= vpos.z;
#endif
vpos.w = 1.0;
vpos.z = 0.0;
gl_Position = vpos;
}
)";
@ -84,7 +87,7 @@ layout (set = 0, binding = 3) uniform sampler2D palette;
// Vertex input
layout (location = 0) INTERPOLATION in lowp vec4 vtx_base;
layout (location = 1) INTERPOLATION in lowp vec4 vtx_offs;
layout (location = 2) in mediump vec2 vtx_uv;
layout (location = 2) noperspective in mediump vec3 vtx_uv;
#if pp_FogCtrl != 2
layout (set = 0, binding = 2) uniform sampler2D fog_table;
@ -111,9 +114,9 @@ vec4 colorClamp(vec4 col)
#if pp_Palette == 1
vec4 palettePixel(sampler2D tex, vec2 coords)
vec4 palettePixel(sampler2D tex, vec3 coords)
{
vec4 c = vec4(texture(tex, coords).r * 255.0 / 1023.0 + pushConstants.palette_index, 0.5, 0.0, 0.0);
vec4 c = vec4(textureProj(tex, coords).r * 255.0 / 1023.0 + pushConstants.palette_index, 0.5, 0.0, 0.0);
return texture(palette, c.xy);
}
@ -129,6 +132,11 @@ void main()
#endif
vec4 color = vtx_base;
vec4 offset = vtx_offs;
#if pp_Gouraud == 1
color /= vtx_uv.z;
offset /= vtx_uv.z;
#endif
#if pp_UseAlpha == 0
color.a = 1.0;
#endif
@ -138,7 +146,7 @@ void main()
#if pp_Texture == 1
{
#if pp_Palette == 0
vec4 texcol = texture(tex, vtx_uv);
vec4 texcol = textureProj(tex, vtx_uv);
#else
vec4 texcol = palettePixel(tex, vtx_uv);
#endif
@ -146,7 +154,7 @@ void main()
#if pp_BumpMap == 1
float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0;
float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0;
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0);
texcol.a = clamp(offset.a + offset.r * sin(s) + offset.g * cos(s) * cos(r - 2.0 * PI * offset.b), 0.0, 1.0);
texcol.rgb = vec3(1.0, 1.0, 1.0);
#else
#if pp_IgnoreTexA == 1
@ -183,7 +191,7 @@ void main()
#if pp_Offset == 1 && pp_BumpMap == 0
{
color.rgb += vtx_offs.rgb;
color.rgb += offset.rgb;
}
#endif
}
@ -193,12 +201,12 @@ void main()
#if pp_FogCtrl == 0
{
color.rgb = mix(color.rgb, uniformBuffer.sp_FOG_COL_RAM.rgb, fog_mode2(gl_FragCoord.w));
color.rgb = mix(color.rgb, uniformBuffer.sp_FOG_COL_RAM.rgb, fog_mode2(vtx_uv.z));
}
#endif
#if pp_FogCtrl == 1 && pp_Offset==1 && pp_BumpMap == 0
{
color.rgb = mix(color.rgb, uniformBuffer.sp_FOG_COL_VERT.rgb, vtx_offs.a);
color.rgb = mix(color.rgb, uniformBuffer.sp_FOG_COL_VERT.rgb, offset.a);
}
#endif
@ -208,7 +216,7 @@ void main()
//color.rgb = vec3(gl_FragCoord.w * uniformBuffer.sp_FOG_DENSITY / 128.0);
float w = gl_FragCoord.w * 100000.0;
float w = vtx_uv.z * 100000.0;
gl_FragDepth = log2(1.0 + w) / 34.0;
gl_FragColor = color;
@ -221,7 +229,8 @@ layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
mat4 normal_matrix;
} uniformBuffer;
layout (location = 0) in vec4 in_pos;
layout (location = 0) in vec4 in_pos;
layout (location = 0) noperspective out float depth;
void main()
{
@ -233,14 +242,15 @@ void main()
}
vpos = uniformBuffer.normal_matrix * vpos;
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
vpos.xy *= vpos.w;
depth = vpos.z;
vpos.w = 1.0;
vpos.z = 0.0;
gl_Position = vpos;
}
)";
static const char ModVolFragmentShaderSource[] = R"(
layout (location = 0) noperspective in float depth;
layout (location = 0) out vec4 FragColor;
layout (push_constant) uniform pushBlock
@ -250,7 +260,7 @@ layout (push_constant) uniform pushBlock
void main()
{
float w = gl_FragCoord.w * 100000.0;
float w = depth * 100000.0;
gl_FragDepth = log2(1.0 + w) / 34.0;
FragColor = vec4(0.0, 0.0, 0.0, pushConstants.sp_ShaderColor);
}

View File

@ -82,7 +82,7 @@ static const char GouraudSource[] = R"(
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#define INTERPOLATION noperspective
#endif
)";