mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 21:21:17 +01:00
Tess Renderer: compute gradient F in vertex shader.
Compute gradient F in vertex shader as discussed on Slack with @csmartdalton Diffs= d4d6067a3 Fix radial gradient interpolation 14026d5dc Compute gradient F in vertex shader.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -34,14 +34,27 @@ void main() {
|
||||
@vs vs_path
|
||||
uniform vs_path_params {
|
||||
mat4 mvp;
|
||||
int fillType;
|
||||
vec2 gradientStart;
|
||||
vec2 gradientEnd;
|
||||
};
|
||||
|
||||
in vec2 position;
|
||||
out vec2 pos;
|
||||
out vec2 gradient_uv;
|
||||
|
||||
void main() {
|
||||
pos = position;
|
||||
gl_Position = mvp * vec4(position, 0.0, 1.0);
|
||||
|
||||
if(fillType == 1) {
|
||||
// Linear gradient.
|
||||
vec2 toEnd = gradientEnd - gradientStart;
|
||||
float lengthSquared = toEnd.x * toEnd.x + toEnd.y * toEnd.y;
|
||||
gradient_uv.x = dot(position - gradientStart, toEnd) / lengthSquared;
|
||||
}
|
||||
else if(fillType == 2) {
|
||||
// fillType == 2 (Radial gradient)
|
||||
gradient_uv = (position - gradientStart) / distance(gradientStart, gradientEnd);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -51,12 +64,10 @@ uniform fs_path_uniforms {
|
||||
int fillType;
|
||||
vec4 colors[16];
|
||||
vec4 stops[4];
|
||||
vec2 gradientStart;
|
||||
vec2 gradientEnd;
|
||||
int stopCount;
|
||||
};
|
||||
|
||||
in vec2 pos;
|
||||
in vec2 gradient_uv;
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
@@ -65,18 +76,7 @@ void main() {
|
||||
frag_color = colors[0];
|
||||
}
|
||||
else {
|
||||
float f;
|
||||
if(fillType == 1) {
|
||||
// Linear gradient.
|
||||
vec2 toEnd = gradientEnd - gradientStart;
|
||||
float lengthSquared = toEnd.x * toEnd.x + toEnd.y * toEnd.y;
|
||||
f = dot(pos - gradientStart, toEnd) / lengthSquared;
|
||||
}
|
||||
else {
|
||||
// fillType == 2 (Radial gradient)
|
||||
f = distance(gradientStart, pos) / distance(gradientStart, gradientEnd);
|
||||
}
|
||||
|
||||
float f = fillType == 1 ? gradient_uv.x : length(gradient_uv);
|
||||
vec4 color =
|
||||
mix(colors[0], colors[1], smoothstep(stops[0][0], stops[0][1], f));
|
||||
for (int i = 1; i < 15; ++i)
|
||||
|
||||
@@ -636,18 +636,18 @@ public:
|
||||
m_end = Vec2D(cx + radius, cy);
|
||||
}
|
||||
|
||||
void bind(fs_path_uniforms_t& uniforms) {
|
||||
void bind(vs_path_params_t& vertexUniforms, fs_path_uniforms_t& fragmentUniforms) {
|
||||
auto stopCount = m_stops.size();
|
||||
uniforms.fillType = m_type;
|
||||
uniforms.stopCount = stopCount;
|
||||
uniforms.gradientStart = m_start;
|
||||
uniforms.gradientEnd = m_end;
|
||||
vertexUniforms.fillType = fragmentUniforms.fillType = m_type;
|
||||
vertexUniforms.gradientStart = m_start;
|
||||
vertexUniforms.gradientEnd = m_end;
|
||||
fragmentUniforms.stopCount = stopCount;
|
||||
for (int i = 0; i < stopCount; i++) {
|
||||
auto colorBufferIndex = i * 4;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
uniforms.colors[i][j] = m_colors[colorBufferIndex + j];
|
||||
fragmentUniforms.colors[i][j] = m_colors[colorBufferIndex + j];
|
||||
}
|
||||
uniforms.stops[i / 4][i % 4] = m_stops[i];
|
||||
fragmentUniforms.stops[i / 4][i % 4] = m_stops[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -737,10 +737,11 @@ public:
|
||||
|
||||
void shader(rcp<RenderShader> shader) override { m_shader = shader; }
|
||||
|
||||
void draw(SokolRenderPath* path) {
|
||||
void draw(vs_path_params_t& vertexUniforms, SokolRenderPath* path) {
|
||||
if (m_shader) {
|
||||
static_cast<SokolGradient*>(m_shader.get())->bind(m_uniforms);
|
||||
static_cast<SokolGradient*>(m_shader.get())->bind(vertexUniforms, m_uniforms);
|
||||
}
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, SG_RANGE_REF(vertexUniforms));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, SLOT_fs_path_uniforms, SG_RANGE_REF(m_uniforms));
|
||||
if (m_stroke != nullptr) {
|
||||
if (m_strokeDirty) {
|
||||
@@ -943,9 +944,8 @@ void SokolTessRenderer::drawPath(RenderPath* path, RenderPaint* paint) {
|
||||
case BlendMode::multiply: setPipeline(m_pathMultiplyPipeline[m_clipCount]); break;
|
||||
default: setPipeline(m_pathScreenPipeline[m_clipCount]); break;
|
||||
}
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, SG_RANGE_REF(vs_params));
|
||||
|
||||
static_cast<SokolRenderPaint*>(paint)->draw(static_cast<SokolRenderPath*>(path));
|
||||
static_cast<SokolRenderPaint*>(paint)->draw(vs_params, static_cast<SokolRenderPath*>(path));
|
||||
}
|
||||
|
||||
SokolRenderImage::SokolRenderImage(const uint8_t* bytes, uint32_t width, uint32_t height) :
|
||||
|
||||
Reference in New Issue
Block a user