Request: Add support for custom vertex shaders
Currently Ebitengine only supports fragments shaders. While fragments shaders give you a lot of freedom, there are some effects that are easier(and maybe more efficient) to implement using the vertex shader(scaling, stretching, rotating, changing the shape, etc.). Rotating a handful of vertices is much simpler than all of the pixels within a source image.
This feature will give more more freedom, especially with combination with fragment shaders, allowing for more complex shaders to be possible.
Another more concrete example is this simple shader, moving the top vertices in a certain wave form to simulate wind - can be useful for moving grass sprites, trees, etc. A possible implementation:
var Amplitude float
var Frequency float
var Delay float
var Time float
func Vertex(position vec2, texCoord vec2, color vec4) (position vec4, texCoord vec2, color vec4) {
// Check if current vertex is one of the top two vertices.
// If using something similar to gl_VertexID is possible.
// Else using texCoord it should also be possible to infer the vertex id.
if texCoord.y == 0 { // Assuming (0,0) and (1, 0) correspond to the top vertices.
position.x += Amplitude * sin((Time + Delay) * Frequency)
//position.y += AmplitudeY * sin((Time + DelayY) * FrequencyY)
}
return __projectionMatrix * vec4(position, 0, 1), texCoord, color
}
One point raised, was that this is essentially exposing another API which then will need to be maintained, thus raising the maintenance cost. This is can be potentially flagged as experimental, and be left for the discretion of the user, whether to use a custom vertex shader or not.
Interesting, but can we already do similar effects by modifying vertices on the CPU side?
Interesting, but can we already do similar effects by modifying vertices on the CPU side?
Yeah, that's true, we can.
In addition, scaling, stretching, and rotating are all possible with the current GeoM struct when drawing using images. I'm sure vertex shaders would be more efficient, as this would allow us to perform these calculations on the GPU and free up time on the CPU, but by how much I'm not sure.
I think it might be good to examine this from a performance perspective to see if, say, rotating, scaling, stretching, and skewing using GeoM is significantly worse than doing it through a theoretical vertex shader.
Yeah, we need to do some performance experiments. My concern is that a vertex shader might prevent batching, so the performance might be worse in some cases.
@SolarLune vertex shaders could allow bump mapping in Tetra? Among many other things I guess, but I think this one is a common use case in 3D
@SolarLune vertex shaders could allow bump mapping in Tetra? Among many other things I guess, but I think this one is a common use case in 3D
I suppose you could use a vertex shader to vary the shape of a mesh, though I think normal mapping would be most effectively done through modification of Tetra3D's per-fragment rendering shader, rather than using vertex shaders for bump mapping (unless I am missing alternate possibilities).
Using a vertex shader would allow for rendering meshes faster in Tetra3D, but I would need to send the necessary data to transform each vertex to be able to take advantage of it (the volume of which Kage doesn't currently support, so that's not an option currently).
Will it be implemented?
Not planned