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

Yet another overbright bug (deformvertexes autosprite2) #1246

Closed
slipher opened this issue Aug 17, 2024 · 6 comments
Closed

Yet another overbright bug (deformvertexes autosprite2) #1246

slipher opened this issue Aug 17, 2024 · 6 comments

Comments

@slipher
Copy link
Member

slipher commented Aug 17, 2024

Map: https://users.unvanquished.net/~sweet/pkg/map-defenxe_0+b2.dpk

Shader:

textures/mario/tree_shader
{
	qer_editorimage textures/mario/tree.tga
	surfaceparm alphashadow
	surfaceparm noimpact
	surfaceparm nomarks
	surfaceparm nonsolid
	surfaceparm trans
	cull disable
	deformVertexes autosprite2
	{
		map textures/mario/tree.tga
		rgbGen identity
		depthWrite
		alphaFunc GE128
	}
	{
		map $lightmap 
		blendfunc filter
		rgbGen identity
		tcGen lightmap 
		depthFunc equal
	}
}

How it now looks:
unvanquished_2024-08-17_011937_000

With r_forcelegacyoverbrightclamping 1, all the trees looks like the brightly colored one under the map name in the levelshot:
defenxe

(There is a second bug that unlike the levelshot, the trees are seemingly unaffected by the light grid and all equally bright. But that's unchanged since 0.51.)

Also there is a third bug that the tree sprites are incorrectly culled despite the shader saying cull disable :)

@illwieckz
Copy link
Member

Alongside overbright and culling problems, maybe there are other problems involved. The engine currently assume a BSP surface is fullbright if there is no lightmap, it only uses lightgrid for non-BSP models, but maybe such surface have no lightmap and maybe they should use lightgrid.

I want to use lightgrid on some bsp surfaces while the rest of the world use lightmap, especially for moving parts like doors. Maybe the original quake3 engine already did this and maybe those trees are an example of this. This is also something I thought about some autosprite2 in metro (chains not being properly lit).

And of course, among the various problems, this trees are autosprite2 and autosprite2 is still incomplete:

@slipher
Copy link
Member Author

slipher commented Aug 21, 2024

I misspoke saying lightgrid, I believe it should just be lightmaps in this case. Although lightmaps are not a theoretically correct approach here, considering the surface can be drawn at different positions/angles.

The problem is that gl_lightMappingShader does not know how to fetch sprite vertexes. It is not configured with the USE_VERTEX_SPRITE macro. So the lightmap vertexes are not drawn at the correct position; this causes both the first and second bugs. So apparently in the new overbright implementation, the color map stage draws the image with 4x brightness or whatever, and needs the lightmap stage to cut that down to something reasonable. While with r_forcelegacyoverbrightclamping 1 it starts out with 1x brightness so it will not look so bad when the lightmap stage fails to draw anything.

I tried a bit to set it up the lightmap shader with USE_VERTEX_SPRITE and the needed uniforms, but still couldn't get the vertexes to appear in the correct location. But anyway, the whole VBO sprite vertexes thing smells like bad design. We have 4 different options for reading out a vertex in GLSL: vertexSimple_vp.glsl, vertexAnimation_vp.glsl, vertexSkinning_vp.glsl, and vertexSprite_vp.glsl. So for any GLSL shader that needs to support all the variants, the number of GLSL binaries is multiplied by 4. The first variant is a basic vertex with nothing fancy. The 2nd and 3rd are specialized for types of models. It makes sense to have these because models are expensive to draw and used a lot. But the 4th is only useful for being able to draw BSP autosprite surfaces from the static VBO. This is not compelling because the feature is seldom used. Moreover the number of triangles is small: sprites are inherently low-poly because the surface is required to be a rectangle composed of 2 triangles to work. So I propose NUKING USE_VERTEX_SPRITE/vertexSprite_vp.glsl and just adding the vertexes from the CPU. Essentially, reverting b10e8c2.

I might want to do this before finishing my vertex translation branch since it would get rid of the nasty case of two overlapping vertex attribute arrays for ATTR_ORIENTATION and ATTR_QTANGENT (see the union in shaderVertex_t).

@VReaperV
Copy link
Contributor

I tried a bit to set it up the lightmap shader with USE_VERTEX_SPRITE and the needed uniforms, but still couldn't get the vertexes to appear in the correct location. But anyway, the whole VBO sprite vertexes thing smells like bad design. We have 4 different options for reading out a vertex in GLSL: vertexSimple_vp.glsl, vertexAnimation_vp.glsl, vertexSkinning_vp.glsl, and vertexSprite_vp.glsl. So for any GLSL shader that needs to support all the variants, the number of GLSL binaries is multiplied by 4. The first variant is a basic vertex with nothing fancy. The 2nd and 3rd are specialized for types of models. It makes sense to have these because models are expensive to draw and used a lot. But the 4th is only useful for being able to draw BSP autosprite surfaces from the static VBO. This is not compelling because the feature is seldom used. Moreover the number of triangles is small: sprites are inherently low-poly because the surface is required to be a rectangle composed of 2 triangles to work. So I propose NUKING USE_VERTEX_SPRITE/vertexSprite_vp.glsl and just adding the vertexes from the CPU. Essentially, reverting b10e8c2.

Can't they just be converted to use vertexSimple_vp and a model matrix be calculated accordingly, so they're always facing the viewer?

@slipher
Copy link
Member Author

slipher commented Aug 21, 2024

Can't they just be converted to use vertexSimple_vp and a model matrix be calculated accordingly, so they're always facing the viewer?

Yeah, probably possible. One thing that could be wrong with such an approach is the light grid. But this stuff only really has to work with BSP surfaces, where the light grid (I think) can't be used. If it were used the errors would be small in most cases. It would probably fine as long as there isn't anything else that depends on having a correct world position.

The advantage would be you keep using the VBO. The disadvantage would be you always have to send every sprite (2 triangles) as a separate draw call since the matrices are different.

@VReaperV
Copy link
Contributor

The advantage would be you keep using the VBO. The disadvantage would be you always have to send every sprite (2 triangles) as a separate draw call since the matrices are different.

We could put all matrices into a buffer, however it won't work on ancient hardware that doesn't support that.

@slipher slipher changed the title Yet another overbright bug Yet another overbright bug (deformvertexes autosprite2) Aug 24, 2024
slipher added a commit that referenced this issue Sep 7, 2024
Get rid of vertexSprite_vp.glsl/USE_VERTEX_SPRITE and return to doing
deformvertexes autosprite/autosprite2 vertex calculations on the CPU
(like it was until 2015). This fixes various bugs with autosprite[2]
BSP surfaces. Also it
fixes some particle systems which were broken for unknown reasons.

One problem with the vertex sprite GLSL is that it always applied depth
fade, regardless of whether it was requested. Depth fade means the alpha
will be reduced if there is something close behind the particle within a
certain depth (judging by the z buffer). With autosprite1, this depth
parameter was set equal to the size of the sprite. So it is like a
cube-shaped cloud (which matters when part of the cloud is inside a
wall). The shader-specified fade depth, if any, was ignored. With
autosprite2, the shader used a negative depth parameter, which just
breaks everything. By removing unwanted depth fade for
BSP surfaces, this fixes #997
(non-opaque autosprite2 BSP surfaces do not show up, as seen with the
various flames on KOsAD's metro map).

Also depth fade will no longer be automatically applied to all
particles. I believe we have just 3 Unvanquished shaders configured with
depth fade: acid tube acid, booster effect, and grenade smoke. All
'cloud of gas'-type effects. Any other particles could potentially look
different due to removing depth fade. However, I have failed to notice
any (other than broken ones that started working). For small particles,
the depth fade is unlikely to make any difference.

Another issue is that USE_VERTEX_SPRITE was not available for lightmap
shaders. This meant that vertex positions were out of sync between
the generic and lightmap shaders, and the lightmap shader failed to render
anything. So this commit fixes #1246 (wrong lighting for autosprite[2]
BSP surfaces with lightmaps, as seen on map "defenxe") by calculating
the final vertex positions before uploading them, which ensures they are
the same for all GLSL shaders used.

With this commit, some particles that were previously not visible are
now rendered: the ones with the gfx/players/alien_base/green_acid shader
which are emitted upon evolving, or damaging or destroying an alien
buildable. I believe the problem must have been that Tess_AddSprite
oriented the triangles backward (CW instead of CCW or vice versa). And
unlike most particle shaders, the acid one fails to specify double-sided
culling, so it would disappear if oriented backward.

To implement CPU-side autosprite/autosprite2 transformations, I took the
code from an old (~2015) version of the file. But I ended up completely
writing the autosprite2 one.

When autosprites were first implemented in GLSL, there was also a
change in how the polygon is positioned: in the GLSL implementation it
faces towards the viewer, rather than Tremulous' behavior to face
opposite the view direction. I decided that the GLSL behavior is
superior for autosprite2 and reimplemented the CPU version that way (but
you can get the old behavior by setting the r_autosprite2Style cvar).
For autosprite the old behavior seems good enough so it once again faces
opposing the view direction.

This commit makes autosprite2 surfaces work with material system enabled
for the first time, by virtue of rendering them without using the
material system.
slipher added a commit that referenced this issue Sep 9, 2024
Get rid of vertexSprite_vp.glsl/USE_VERTEX_SPRITE and return to doing
deformvertexes autosprite/autosprite2 vertex calculations on the CPU
(like it was until 2015). This fixes various bugs with autosprite[2]
BSP surfaces. Also it
fixes some particle systems which were broken for unknown reasons.

One problem with the vertex sprite GLSL is that it always applied depth
fade, regardless of whether it was requested. Depth fade means the alpha
will be reduced if there is something close behind the particle within a
certain depth (judging by the z buffer). With autosprite1, this depth
parameter was set equal to the size of the sprite. So it is like a
cube-shaped cloud (which matters when part of the cloud is inside a
wall). The shader-specified fade depth, if any, was ignored. With
autosprite2, the shader used a negative depth parameter, which just
breaks everything. By removing unwanted depth fade for
BSP surfaces, this fixes #997
(non-opaque autosprite2 BSP surfaces do not show up, as seen with the
various flames on KOsAD's metro map).

Also depth fade will no longer be automatically applied to all
particles. I believe we have just 3 Unvanquished shaders configured with
depth fade: acid tube acid, booster effect, and grenade smoke. Any other
particles could potentially look different due to removing depth fade.
So we may need some asset changes to adjust to this change.

Another issue is that USE_VERTEX_SPRITE was not available for lightmap
shaders. This meant that vertex positions were out of sync between
the generic and lightmap shaders, and the lightmap shader failed to render
anything. So this commit fixes #1246 (wrong lighting for autosprite[2]
BSP surfaces with lightmaps, as seen on map "defenxe") by calculating
the final vertex positions before uploading them, which ensures they are
the same for all GLSL shaders used.

With this commit, some particles that were previously not visible are
now rendered, for example:
- ones with the gfx/players/alien_base/green_acid shader
  which are emitted upon evolving, or damaging or destroying an alien
  buildable
- orange glowing "mark" (which is actually a particle) added at impact
  point of several weapons (rifle, shotgun...)
I believe the problem must have been that Tess_AddSprite
oriented the triangles backward (CW instead of CCW or vice versa). And
unlike most particle shaders, the acid one fails to specify double-sided
culling, so it would disappear if oriented backward.

To implement CPU-side autosprite/autosprite2 transformations, I took the
code from an old (~2015) version of the file. But I ended up completely
writing the autosprite2 one.

When autosprites were first implemented in GLSL, there was also a
change in how the polygon is positioned: in the GLSL implementation it
faces towards the viewer, rather than Tremulous' behavior to face
opposite the view direction. I decided that the GLSL behavior is
superior for autosprite2 and reimplemented the CPU version that way (but
you can get the old behavior by setting the r_autosprite2Style cvar).
For autosprite the old behavior seems good enough so it once again faces
opposing the view direction.

This commit makes autosprite2 surfaces work with material system enabled
for the first time, by virtue of rendering them without using the
material system.
slipher added a commit that referenced this issue Sep 19, 2024
Get rid of vertexSprite_vp.glsl/USE_VERTEX_SPRITE and return to doing
deformvertexes autosprite/autosprite2 vertex calculations on the CPU
(like it was until 2015). This fixes various bugs with autosprite[2]
BSP surfaces. Also it
fixes some particle systems which were broken for unknown reasons.

One problem with the vertex sprite GLSL is that it always applied depth
fade, regardless of whether it was requested. Depth fade means the alpha
will be reduced if there is something close behind the particle within a
certain depth (judging by the z buffer). With autosprite1, this depth
parameter was set equal to the size of the sprite. So it is like a
cube-shaped cloud (which matters when part of the cloud is inside a
wall). The shader-specified fade depth, if any, was ignored. With
autosprite2, the shader used a negative depth parameter, which just
breaks everything. By removing unwanted depth fade for
BSP surfaces, this fixes #997
(non-opaque autosprite2 BSP surfaces do not show up, as seen with the
various flames on KOsAD's metro map).

Also depth fade will no longer be automatically applied to all
particles. I believe we have just 3 Unvanquished shaders configured with
depth fade: acid tube acid, booster effect, and grenade smoke. Any other
particles could potentially look different due to removing depth fade.
So we may need some asset changes to adjust to this change.

Another issue is that USE_VERTEX_SPRITE was not available for lightmap
shaders. This meant that vertex positions were out of sync between
the generic and lightmap shaders, and the lightmap shader failed to render
anything. So this commit fixes #1246 (wrong lighting for autosprite[2]
BSP surfaces with lightmaps, as seen on map "defenxe") by calculating
the final vertex positions before uploading them, which ensures they are
the same for all GLSL shaders used.

With this commit, some particles that were previously not visible are
now rendered, for example:
- ones with the gfx/players/alien_base/green_acid shader
  which are emitted upon evolving, or damaging or destroying an alien
  buildable
- orange glowing "mark" (which is actually a particle) added at impact
  point of several weapons (rifle, shotgun...)
I believe the problem must have been that Tess_AddSprite
oriented the triangles backward (CW instead of CCW or vice versa). And
unlike most particle shaders, the acid one fails to specify double-sided
culling, so it would disappear if oriented backward.

To implement CPU-side autosprite/autosprite2 transformations, I took the
code from an old (~2015) version of the file. But I ended up completely
writing the autosprite2 one.

When autosprites were first implemented in GLSL, there was also a
change in how the polygon is positioned: in the GLSL implementation it
faces towards the viewer, rather than Tremulous' behavior to face
opposite the view direction. I decided that the GLSL behavior is
superior for autosprite2 and reimplemented the CPU version that way (but
you can get the old behavior by setting the r_autosprite2Style cvar).
For autosprite the old behavior seems good enough so it once again faces
opposing the view direction.

This commit makes autosprite2 surfaces work with material system enabled
for the first time, by virtue of rendering them without using the
material system.
slipher added a commit that referenced this issue Oct 4, 2024
Get rid of vertexSprite_vp.glsl/USE_VERTEX_SPRITE and return to doing
deformvertexes autosprite/autosprite2 vertex calculations on the CPU
(like it was until 2015). This fixes various bugs with autosprite[2]
BSP surfaces. Also it
fixes some particle systems which were broken for unknown reasons.

One problem with the vertex sprite GLSL is that it always applied depth
fade, regardless of whether it was requested. Depth fade means the alpha
will be reduced if there is something close behind the particle within a
certain depth (judging by the z buffer). With autosprite1, this depth
parameter was set equal to the size of the sprite. So it is like a
cube-shaped cloud (which matters when part of the cloud is inside a
wall). The shader-specified fade depth, if any, was ignored. With
autosprite2, the shader used a negative depth parameter, which just
breaks everything. By removing unwanted depth fade for
BSP surfaces, this fixes #997
(non-opaque autosprite2 BSP surfaces do not show up, as seen with the
various flames on KOsAD's metro map).

Also depth fade will no longer be automatically applied to all
particles. I believe we have just 3 Unvanquished shaders configured with
depth fade: acid tube acid, booster effect, and grenade smoke. Any other
particles could potentially look different due to removing depth fade.
So we may need some asset changes to adjust to this change.

Another issue is that USE_VERTEX_SPRITE was not available for lightmap
shaders. This meant that vertex positions were out of sync between
the generic and lightmap shaders, and the lightmap shader failed to render
anything. So this commit fixes #1246 (wrong lighting for autosprite[2]
BSP surfaces with lightmaps, as seen on map "defenxe") by calculating
the final vertex positions before uploading them, which ensures they are
the same for all GLSL shaders used.

With this commit, some particles that were previously not visible are
now rendered, for example:
- ones with the gfx/players/alien_base/green_acid shader
  which are emitted upon evolving, or damaging or destroying an alien
  buildable
- orange glowing "mark" (which is actually a particle) added at impact
  point of several weapons (rifle, shotgun...)
I believe the problem must have been that Tess_AddSprite
oriented the triangles backward (CW instead of CCW or vice versa). And
unlike most particle shaders, the acid one fails to specify double-sided
culling, so it would disappear if oriented backward.

To implement CPU-side autosprite/autosprite2 transformations, I took the
code from an old (~2015) version of the file. But I ended up completely
writing the autosprite2 one.

When autosprites were first implemented in GLSL, there was also a
change in how the polygon is positioned: in the GLSL implementation it
faces towards the viewer, rather than Tremulous' behavior to face
opposite the view direction. I decided that the GLSL behavior is
superior for autosprite2 and reimplemented the CPU version that way (but
you can get the old behavior by setting the r_autosprite2Style cvar).
For autosprite the old behavior seems good enough so it once again faces
opposing the view direction.

This commit makes autosprite2 surfaces work with material system enabled
for the first time, by virtue of rendering them without using the
material system.
slipher added a commit that referenced this issue Oct 7, 2024
Get rid of vertexSprite_vp.glsl/USE_VERTEX_SPRITE and return to doing
deformvertexes autosprite/autosprite2 vertex calculations on the CPU
(like it was until 2015). This fixes various bugs with autosprite[2]
BSP surfaces. Also it
fixes some particle systems which were broken for unknown reasons.

One problem with the vertex sprite GLSL is that it always applied depth
fade, regardless of whether it was requested. Depth fade means the alpha
will be reduced if there is something close behind the particle within a
certain depth (judging by the z buffer). With autosprite1, this depth
parameter was set equal to the size of the sprite. So it is like a
cube-shaped cloud (which matters when part of the cloud is inside a
wall). The shader-specified fade depth, if any, was ignored. With
autosprite2, the shader used a negative depth parameter, which just
breaks everything. By removing unwanted depth fade for
BSP surfaces, this fixes #997
(non-opaque autosprite2 BSP surfaces do not show up, as seen with the
various flames on KOsAD's metro map).

Also depth fade will no longer be automatically applied to all
particles. I believe we have just 3 Unvanquished shaders configured with
depth fade: acid tube acid, booster effect, and grenade smoke. Any other
particles could potentially look different due to removing depth fade.
So we may need some asset changes to adjust to this change.

Another issue is that USE_VERTEX_SPRITE was not available for lightmap
shaders. This meant that vertex positions were out of sync between
the generic and lightmap shaders, and the lightmap shader failed to render
anything. So this commit fixes #1246 (wrong lighting for autosprite[2]
BSP surfaces with lightmaps, as seen on map "defenxe") by calculating
the final vertex positions before uploading them, which ensures they are
the same for all GLSL shaders used.

With this commit, some particles that were previously not visible are
now rendered, for example:
- ones with the gfx/players/alien_base/green_acid shader
  which are emitted upon evolving, or damaging or destroying an alien
  buildable
- orange glowing "mark" (which is actually a particle) added at impact
  point of several weapons (rifle, shotgun...)
I believe the problem with green_acid must have been that Tess_AddSprite
oriented the triangles backward (CW instead of CCW or vice versa). And
unlike most particle shaders, the acid one fails to specify double-sided
culling, so it would disappear if oriented backward.
The problem with the orange mark (and some other impact particles) is that
it is positioned very close to the surface. The alpha more or less goes
to zero when using depth fade, if you are looking from a direction close
to the impact surface's normal. The impact mark particle was only
visible from tangential angles.

To implement CPU-side autosprite/autosprite2 transformations, I took the
code from an old (~2015) version of the file. But I ended up completely
writing the autosprite2 one.

When autosprites were first implemented in GLSL, there was also a
change in how the polygon is positioned: in the GLSL implementation it
faces towards the viewer, rather than Tremulous' behavior to face
opposite the view direction. I decided that the GLSL behavior is
superior for autosprite2 and reimplemented the CPU version that way (but
you can get the old behavior by setting the r_autosprite2Style cvar).
For autosprite the old behavior seems good enough so it once again faces
opposing the view direction.

This commit makes autosprite2 surfaces work with material system enabled
for the first time, by virtue of rendering them without using the
material system.
slipher added a commit that referenced this issue Oct 7, 2024
Get rid of vertexSprite_vp.glsl/USE_VERTEX_SPRITE and return to doing
deformvertexes autosprite/autosprite2 vertex calculations on the CPU
(like it was until 2015). This fixes various bugs with autosprite[2]
BSP surfaces. Also it
fixes some particle systems which were broken for unknown reasons.

One problem with the vertex sprite GLSL is that it always applied depth
fade, regardless of whether it was requested. Depth fade means the alpha
will be reduced if there is something close behind the particle within a
certain depth (judging by the z buffer). With autosprite1, this depth
parameter was set equal to the size of the sprite. So it is like a
cube-shaped cloud (which matters when part of the cloud is inside a
wall). The shader-specified fade depth, if any, was ignored. With
autosprite2, the shader used a negative depth parameter, which just
breaks everything. By removing unwanted depth fade for
BSP surfaces, this fixes #997
(non-opaque autosprite2 BSP surfaces do not show up, as seen with the
various flames on KOsAD's metro map).

Also depth fade will no longer be automatically applied to all
particles. I believe we have just 3 Unvanquished shaders configured with
depth fade: acid tube acid, booster effect, and grenade smoke. Any other
particles could potentially look different due to removing depth fade.
So we may need some asset changes to adjust to this change.

Another issue is that USE_VERTEX_SPRITE was not available for lightmap
shaders. This meant that vertex positions were out of sync between
the generic and lightmap shaders, and the lightmap shader failed to render
anything. So this commit fixes #1246 (wrong lighting for autosprite[2]
BSP surfaces with lightmaps, as seen on map "defenxe") by calculating
the final vertex positions before uploading them, which ensures they are
the same for all GLSL shaders used.

With this commit, some particles that were previously not visible are
now rendered, for example:
- ones with the gfx/players/alien_base/green_acid shader
  which are emitted upon evolving, or damaging or destroying an alien
  buildable
- orange glowing "mark" (which is actually a particle) added at impact
  point of several weapons (rifle, shotgun...)
I believe the problem with green_acid must have been that Tess_AddSprite
oriented the triangles backward (CW instead of CCW or vice versa). And
unlike most particle shaders, the acid one fails to specify double-sided
culling, so it would disappear if oriented backward.
The problem with the orange mark (and some other impact particles) is that
it is positioned very close to the surface. The alpha more or less goes
to zero when using depth fade, if you are looking from a direction close
to the impact surface's normal. The impact mark particle was only
visible from tangential angles.

To implement CPU-side autosprite/autosprite2 transformations, I took the
code from an old (~2015) version of the file. But I ended up completely
writing the autosprite2 one.

When autosprites were first implemented in GLSL, there was also a
change in how the polygon is positioned: in the GLSL implementation it
faces towards the viewer, rather than Tremulous' behavior to face
opposite the view direction. I decided that the GLSL behavior is
superior for autosprite2 and reimplemented the CPU version that way (but
you can get the old behavior by setting the r_autosprite2Style cvar).
For autosprite the old behavior seems good enough so it once again faces
opposing the view direction.

This commit makes autosprite2 surfaces work with material system enabled
for the first time, by virtue of rendering them without using the
material system.
@slipher
Copy link
Member Author

slipher commented Oct 12, 2024

Fixed by #1281.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants