8#include "graphics/shaders/mesh3d_toon_frag_spv.inc"
9#include "graphics/shaders/mesh3d_toon_vert_spv.inc"
11#include "stylize/shaders/anime_mesh_frag_spv.inc"
12#include "stylize/shaders/anime_mesh_wgsl.inc"
13#include "stylize/shaders/cartoon_post_frag_spv.inc"
14#include "stylize/shaders/ink_mesh_frag_spv.inc"
15#include "stylize/shaders/ink_post_frag_spv.inc"
16#include "stylize/shaders/pixel_post_frag_spv.inc"
17#include "stylize/shaders/watercolor_post_frag_spv.inc"
18#include "stylize/shaders/xray_mesh_frag_spv.inc"
19#include "stylize/shaders/ysa_mesh_frag_spv.inc"
20#include "stylize/shaders/ysa_mesh_vert_spv.inc"
21#include "stylize/shaders/ysa_mesh_wgsl.inc"
31const std::array<StyleDefinition, 7> kStyles = {{
41std::vector<uint32_t> copySpv(
const uint32_t *data,
size_t count) {
42 return std::vector<uint32_t>(data, data +
count);
49const char *kXrayMeshVertWgsl = R
"wgsl(
51 @location(0) pos: vec3f,
52 @location(1) normal: vec3f,
53 @location(2) uv: vec2f,
67 lights: array<Light3D, 8>,
74 @builtin(position) pos: vec4f,
75 @location(0) vNormal: vec3f,
76 @location(1) vUV: vec2f,
77 @location(2) vTint: vec4f,
78 @location(3) vWorldPos: vec3f,
79 @location(4) vCameraPos: vec3f,
81@group(0) @binding(0) var<uniform> ubo: Frame;
82fn inverse3x3(m: mat3x3f) -> mat3x3f {
83 let a = m[0].x; let b = m[1].x; let c = m[2].x;
84 let d = m[0].y; let e = m[1].y; let f = m[2].y;
85 let g = m[0].z; let h = m[1].z; let i = m[2].z;
86 let det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
88 vec3f((e * i - f * h) / det, (f * g - d * i) / det, (d * h - e * g) / det),
89 vec3f((c * h - b * i) / det, (a * i - c * g) / det, (b * g - a * h) / det),
90 vec3f((b * f - c * e) / det, (c * d - a * f) / det, (a * e - b * d) / det),
94fn vs_main(in: VSIn) -> VSOut {
96 out.pos = ubo.mvp * vec4f(in.pos, 1.0);
97 let world = ubo.model * vec4f(in.pos, 1.0);
98 out.vWorldPos = world.xyz;
99 let nrm = transpose(inverse3x3(mat3x3f(ubo.model[0].xyz, ubo.model[1].xyz, ubo.model[2].xyz))) * in.normal;
100 out.vNormal = normalize(nrm);
102 out.vTint = ubo.tint;
103 out.vCameraPos = ubo.cameraPos.xyz;
108const char *kXrayMeshFragWgsl = R
"wgsl(
121 lights: array<Light3D, 8>,
128 @location(0) vNormal: vec3f,
129 @location(1) vUV: vec2f,
130 @location(2) vTint: vec4f,
131 @location(3) vWorldPos: vec3f,
132 @location(4) vCameraPos: vec3f,
134@group(0) @binding(0) var<uniform> ubo: Frame;
135@group(0) @binding(7) var mainSamp: sampler;
136@group(0) @binding(9) var sceneDepth: texture_depth_2d;
139 @location(0) color: vec4f,
143fn fs_main(in: FSIn, @builtin(position) fragPos: vec4f) -> FSOut {
144 let color = ubo.texBomb.xyz;
145 let alpha = clamp(ubo.texBomb.w, 0.0, 1.0);
146 let bias = max(ubo.parallax.x, 0.0);
147 let screenW = max(ubo.parallax.y, 1.0);
148 let screenH = max(ubo.parallax.z, 1.0);
149 let rimStrength = clamp(ubo.parallax.w, 0.0, 1.0);
150 let rimPower = max(ubo.clipInfo.z, 0.1);
152 let uv = fragPos.xy / vec2f(screenW, screenH);
153 let sceneZ = textureSampleLevel(sceneDepth, mainSamp, uv, 0.0);
154 let charZ = fragPos.z;
155 let occ = smoothstep(sceneZ, sceneZ + bias, charZ);
159 let N = normalize(in.vNormal);
160 let V = normalize(in.vCameraPos - in.vWorldPos);
161 let rim = pow(clamp(1.0 - max(dot(N, V), 0.0), 0.0, 1.0), rimPower);
162 let edge = mix(1.0, rim, rimStrength);
164 out.color = vec4f(color, alpha * edge * occ);
172 const auto it = std::find_if(kStyles.begin(), kStyles.end(), [&](
const StyleDefinition &def) {
173 return style == def.id;
175 if (it != kStyles.end())
return &*it;
184 if (
index < 0)
return {};
185 if (
index <
int(kStyles.size()))
return kStyles[size_t(
index)].id;
191 if (!def)
return false;
192 if (feature ==
"post")
return def->
post;
193 if (feature ==
"mesh")
return def->
mesh;
194 if (feature ==
"cpu")
return def->
cpu;
195 if (feature ==
"depth")
return def->
depth;
196 if (feature ==
"normal")
return def->
normal;
197 if (feature ==
"gbuffer")
return def->
depth || def->
normal;
203const StyleParameterDesc kYsaParams[] = {
204 {
"lightMidpoint", 0.f, -1.f, 1.f},
205 {
"lightSmoothness", 0.1f, 0.00001f, 1.f},
206 {
"ambientR", 0.254717f, 0.f, 1.f},
207 {
"ambientG", 0.254717f, 0.f, 1.f},
208 {
"ambientB", 0.254717f, 0.f, 1.f},
209 {
"shadowPower", 0.5f, 0.f, 1.f},
210 {
"shadowSmoothness", 1.f, 0.00001f, 1.f},
211 {
"specularStrength", 0.f, 0.f, 4.f},
212 {
"specularMidpoint", 0.9f, -1.f, 1.f},
213 {
"specularSmoothness", 0.1f, 0.00001f, 1.f},
214 {
"specularR", 1.f, 0.f, 4.f},
215 {
"specularG", 1.f, 0.f, 4.f},
216 {
"specularB", 1.f, 0.f, 4.f},
217 {
"rimStrength", 0.f, 0.f, 4.f},
218 {
"rimMidpoint", 0.6f, 0.f, 1.f},
219 {
"rimSmoothness", 0.1f, 0.00001f, 1.f},
220 {
"rimDynamic", 0.5f, 0.f, 1.f},
221 {
"rimR", 1.f, 0.f, 4.f},
222 {
"rimG", 0.f, 0.f, 4.f},
223 {
"rimB", 0.f, 0.f, 4.f},
224 {
"alphaClip", 0.f, 0.f, 1.f},
225 {
"rimHideOnShadow", 1.f, 0.f, 1.f},
226 {
"linearLighting", 0.f, 0.f, 1.f},
228const StyleParameterDesc kAnimeParams[] = {
229 {
"shadowThreshold", -0.08f, -1.f, 1.f},
230 {
"shadowSoftness", 0.035f, 0.001f, 0.5f},
231 {
"shadowStrength", 1.f, 0.f, 1.f},
232 {
"rimStrength", 0.19f, 0.f, 1.f},
233 {
"skin", 0.f, 0.f, 1.f},
234 {
"hair", 0.f, 0.f, 1.f},
235 {
"skinDetail", 1.f, 0.f, 1.f},
236 {
"specularStrength", 0.22f, 0.f, 1.f},
237 {
"specularPower", 32.f, 1.f, 128.f},
238 {
"shadowR", 0.64f, 0.f, 1.f},
239 {
"shadowG", 0.66f, 0.f, 1.f},
240 {
"shadowB", 0.79f, 0.f, 1.f},
241 {
"fillGradient", 0.08f, 0.f, 1.f},
242 {
"unlit", 0.f, 0.f, 1.f},
243 {
"surfaceSpecular", 0.f, 0.f, 1.f},
244 {
"castShadowStrength", 1.f, 0.f, 1.f},
246const StyleParameterDesc kCartoonParams[] = {
247 {
"bands", 3.f, 1.f, 16.f}, {
"outlineStrength", 1.15f, 0.f, 4.f},
248 {
"outlineThreshold", 0.12f, 0.f, 1.f}, {
"posterize", 5.f, 1.f, 32.f},
249 {
"softEdge", 0.08f, 0.f, 1.f}, {
"outlineWidth", 1.5f, 0.5f, 8.f},
250 {
"shadowLift", 0.12f, 0.f, 1.f}, {
"rimPower", 2.8f, 0.1f, 16.f},
251 {
"rimStrength", 0.55f, 0.f, 2.f},
253const StyleParameterDesc kWatercolorParams[] = {
254 {
"blurAmount", 2.4f, 0.f, 12.f}, {
"edgeDarken", 2.f, 0.f, 5.f},
255 {
"paperStrength", 0.65f, 0.f, 1.f}, {
"distortion", 0.85f, 0.f, 3.f},
256 {
"bleed", 0.62f, 0.f, 1.f}, {
"saturation", 0.9f, 0.f, 2.f},
257 {
"granulation", 0.65f, 0.f, 1.f},
259const StyleParameterDesc kInkParams[] = {
260 {
"inkContrast", 1.35f, 0.f, 4.f}, {
"washLevels", 5.f, 1.f, 16.f},
261 {
"edgeThreshold", 0.18f, 0.f, 1.f}, {
"diffusion", 3.5f, 0.f, 12.f},
262 {
"paperR", 0.96f, 0.f, 1.f}, {
"paperG", 0.93f, 0.f, 1.f},
263 {
"paperB", 0.86f, 0.f, 1.f}, {
"inkDensity", 0.75f, 0.f, 2.f},
264 {
"edgeStrength", 1.1f, 0.f, 4.f}, {
"contrast", 1.25f, 0.f, 4.f},
265 {
"rimBoost", 0.65f, 0.f, 2.f},
267const StyleParameterDesc kPixelParams[] = {
268 {
"pixelSize", 5.f, 1.f, 64.f}, {
"paletteSteps", 6.f, 2.f, 32.f},
269 {
"ditherStrength", 0.18f, 0.f, 1.f}, {
"toonBands", 3.f, 1.f, 16.f},
270 {
"sharpness", 1.f, 0.f, 2.f}, {
"outline", 0.9f, 0.f, 4.f},
272const StyleParameterDesc kXrayParams[] = {
273 {
"colorR", 1.f, 0.f, 1.f}, {
"colorG", 0.62f, 0.f, 1.f},
274 {
"colorB", 0.12f, 0.f, 1.f}, {
"bias", 0.0002f, 0.f, 0.02f},
275 {
"rimPower", 2.2f, 0.1f, 16.f}, {
"rimStrength", 0.7f, 0.f, 2.f},
276 {
"alpha", 0.82f, 0.f, 1.f},
280const StyleParameterDesc *paramAt(
const StyleParameterDesc (&
params)[N],
int index) {
281 return index < 0 || index >= int(N) ? nullptr : &
params[size_t(
index)];
286 if (style ==
"ysa")
return int(std::size(kYsaParams));
287 if (style ==
"anime")
return int(std::size(kAnimeParams));
288 if (style ==
"cartoon")
return int(
sizeof(kCartoonParams) /
sizeof(kCartoonParams[0]));
289 if (style ==
"watercolor")
return int(
sizeof(kWatercolorParams) /
sizeof(kWatercolorParams[0]));
290 if (style ==
"ink")
return int(
sizeof(kInkParams) /
sizeof(kInkParams[0]));
291 if (style ==
"pixel")
return int(
sizeof(kPixelParams) /
sizeof(kPixelParams[0]));
292 if (style ==
"xray")
return int(
sizeof(kXrayParams) /
sizeof(kXrayParams[0]));
298 return desc ?
desc->id : std::string{};
302 if (style ==
"ysa")
return paramAt(kYsaParams,
index);
303 if (style ==
"anime")
return paramAt(kAnimeParams,
index);
304 if (style ==
"cartoon")
return paramAt(kCartoonParams,
index);
305 if (style ==
"watercolor")
return paramAt(kWatercolorParams,
index);
306 if (style ==
"ink")
return paramAt(kInkParams,
index);
307 if (style ==
"pixel")
return paramAt(kPixelParams,
index);
308 if (style ==
"xray")
return paramAt(kXrayParams,
index);
314 for (
int i = 0; i <
count; ++i) {
329 if (style ==
"cartoon") {
330 shader->declareFloat(
"bands");
331 shader->declareFloat(
"outlineStrength");
332 shader->declareFloat(
"outlineThreshold");
333 shader->declareFloat(
"posterize");
334 shader->declareFloat(
"texelW");
335 shader->declareFloat(
"texelH");
336 shader->declareFloat(
"time");
337 shader->declareFloat(
"softEdge");
338 shader->declareFloat(
"outlineWidth");
339 shader->declareFloat(
"shadowLift");
340 shader->sendFloat(
"bands", 3.f);
341 shader->sendFloat(
"outlineStrength", 1.15f);
342 shader->sendFloat(
"outlineThreshold", 0.12f);
343 shader->sendFloat(
"posterize", 5.f);
344 shader->sendFloat(
"texelW", 1.f / 256.f);
345 shader->sendFloat(
"texelH", 1.f / 256.f);
346 shader->sendFloat(
"time", 0.f);
347 shader->sendFloat(
"softEdge", 0.08f);
348 shader->sendFloat(
"outlineWidth", 1.5f);
349 shader->sendFloat(
"shadowLift", 0.12f);
352 if (style ==
"watercolor") {
353 shader->declareFloat(
"blurAmount");
354 shader->declareFloat(
"edgeDarken");
355 shader->declareFloat(
"paperStrength");
356 shader->declareFloat(
"distortion");
357 shader->declareFloat(
"bleed");
358 shader->declareFloat(
"saturation");
359 shader->declareFloat(
"texelW");
360 shader->declareFloat(
"texelH");
361 shader->declareFloat(
"time");
362 shader->declareFloat(
"granulation");
363 shader->sendFloat(
"blurAmount", 2.4f);
364 shader->sendFloat(
"edgeDarken", 2.0f);
365 shader->sendFloat(
"paperStrength", 0.65f);
366 shader->sendFloat(
"distortion", 0.85f);
367 shader->sendFloat(
"bleed", 0.62f);
368 shader->sendFloat(
"saturation", 0.9f);
369 shader->sendFloat(
"texelW", 1.f / 256.f);
370 shader->sendFloat(
"texelH", 1.f / 256.f);
371 shader->sendFloat(
"time", 0.f);
372 shader->sendFloat(
"granulation", 0.65f);
375 if (style ==
"ink") {
376 shader->declareFloat(
"inkContrast");
377 shader->declareFloat(
"washLevels");
378 shader->declareFloat(
"edgeThreshold");
379 shader->declareFloat(
"diffusion");
380 shader->declareFloat(
"paperR");
381 shader->declareFloat(
"paperG");
382 shader->declareFloat(
"paperB");
383 shader->declareFloat(
"inkDensity");
384 shader->declareFloat(
"texelW");
385 shader->declareFloat(
"texelH");
386 shader->declareFloat(
"time");
387 shader->declareFloat(
"edgeStrength");
388 shader->sendFloat(
"inkContrast", 1.35f);
389 shader->sendFloat(
"washLevels", 5.f);
390 shader->sendFloat(
"edgeThreshold", 0.18f);
391 shader->sendFloat(
"diffusion", 3.5f);
392 shader->sendFloat(
"paperR", 0.96f);
393 shader->sendFloat(
"paperG", 0.93f);
394 shader->sendFloat(
"paperB", 0.86f);
395 shader->sendFloat(
"inkDensity", 0.75f);
396 shader->sendFloat(
"texelW", 1.f / 256.f);
397 shader->sendFloat(
"texelH", 1.f / 256.f);
398 shader->sendFloat(
"time", 0.f);
399 shader->sendFloat(
"edgeStrength", 1.1f);
402 if (style ==
"pixel") {
403 shader->declareFloat(
"pixelSize");
404 shader->declareFloat(
"paletteSteps");
405 shader->declareFloat(
"ditherStrength");
406 shader->declareFloat(
"toonBands");
407 shader->declareFloat(
"sharpness");
408 shader->declareFloat(
"texelW");
409 shader->declareFloat(
"texelH");
410 shader->declareFloat(
"time");
411 shader->declareFloat(
"screenW");
412 shader->declareFloat(
"screenH");
413 shader->declareFloat(
"outline");
414 shader->sendFloat(
"pixelSize", 5.f);
415 shader->sendFloat(
"paletteSteps", 6.f);
416 shader->sendFloat(
"ditherStrength", 0.18f);
417 shader->sendFloat(
"toonBands", 3.f);
418 shader->sendFloat(
"sharpness", 1.f);
419 shader->sendFloat(
"texelW", 1.f / 256.f);
420 shader->sendFloat(
"texelH", 1.f / 256.f);
421 shader->sendFloat(
"time", 0.f);
422 shader->sendFloat(
"screenW", 256.f);
423 shader->sendFloat(
"screenH", 256.f);
424 shader->sendFloat(
"outline", 0.9f);
427 throw eve::Exception(
"bindPostUniforms: unknown style '%s'", style.c_str());
432 if (style ==
"ysa") {
433 for (
const auto ¶m : kYsaParams) {
434 shader->declareFloat(param.id);
435 shader->sendFloat(param.id, param.defaultValue);
439 if (style ==
"anime") {
440 for (
const auto ¶m : kAnimeParams) {
441 shader->declareFloat(param.id);
442 shader->sendFloat(param.id, param.defaultValue);
452 if (style ==
"cartoon") {
453 shader->declareFloat(
"bands");
454 shader->declareFloat(
"rimPower");
455 shader->declareFloat(
"rimStrength");
456 shader->declareFloat(
"posterize");
457 shader->sendFloat(
"bands", 4.f);
458 shader->sendFloat(
"rimPower", 2.8f);
459 shader->sendFloat(
"rimStrength", 0.55f);
460 shader->sendFloat(
"posterize", 6.f);
463 if (style ==
"ink") {
464 shader->declareFloat(
"washLevels");
465 shader->declareFloat(
"edgeThreshold");
466 shader->declareFloat(
"inkDensity");
467 shader->declareFloat(
"contrast");
468 shader->declareFloat(
"paperR");
469 shader->declareFloat(
"paperG");
470 shader->declareFloat(
"paperB");
471 shader->declareFloat(
"rimBoost");
472 shader->sendFloat(
"washLevels", 5.f);
473 shader->sendFloat(
"edgeThreshold", 0.35f);
474 shader->sendFloat(
"inkDensity", 0.9f);
475 shader->sendFloat(
"contrast", 1.25f);
476 shader->sendFloat(
"paperR", 0.93f);
477 shader->sendFloat(
"paperG", 0.90f);
478 shader->sendFloat(
"paperB", 0.82f);
479 shader->sendFloat(
"rimBoost", 0.65f);
482 if (style ==
"xray") {
483 shader->declareFloat(
"colorR");
484 shader->declareFloat(
"colorG");
485 shader->declareFloat(
"colorB");
486 shader->declareFloat(
"bias");
487 shader->declareFloat(
"screenW");
488 shader->declareFloat(
"screenH");
489 shader->declareFloat(
"rimPower");
490 shader->declareFloat(
"rimStrength");
491 shader->declareFloat(
"alpha");
492 shader->sendFloat(
"colorR", 1.f);
493 shader->sendFloat(
"colorG", 0.62f);
494 shader->sendFloat(
"colorB", 0.12f);
495 shader->sendFloat(
"bias", 0.0002f);
496 shader->sendFloat(
"screenW", 256.f);
497 shader->sendFloat(
"screenH", 256.f);
498 shader->sendFloat(
"rimPower", 2.2f);
499 shader->sendFloat(
"rimStrength", 0.7f);
500 shader->sendFloat(
"alpha", 0.82f);
503 throw eve::Exception(
"bindMeshUniforms: style '%s' has no mesh shader", style.c_str());
507 if (!gfx)
throw eve::Exception(
"createPostShader: null graphics");
510 if (!def)
throw eve::Exception(
"createPostShader: unknown style '%s'", style.c_str());
512 throw eve::Exception(
"createPostShader: style '%s' has no post technique", style.c_str());
521 throw eve::Exception(
"createPostShader: failed to create '%s' WGSL", style.c_str());
526 std::vector<uint32_t>
frag;
527 if (style ==
"cartoon")
528 frag = copySpv(cartoon_post_frag_spv, cartoon_post_frag_spv_count);
529 else if (style ==
"watercolor")
530 frag = copySpv(watercolor_post_frag_spv, watercolor_post_frag_spv_count);
531 else if (style ==
"ink")
532 frag = copySpv(ink_post_frag_spv, ink_post_frag_spv_count);
534 frag = copySpv(pixel_post_frag_spv, pixel_post_frag_spv_count);
538 throw eve::Exception(
"createPostShader: failed to create '%s'", style.c_str());
544 if (!gfx)
throw eve::Exception(
"createMeshShader: null graphics");
547 if (style ==
"ysa") {
556 copySpv(ysa_mesh_frag_spv, ysa_mesh_frag_spv_count));
562 if (style ==
"anime") {
567 copySpv(anime_mesh_frag_spv, anime_mesh_frag_spv_count));
573 if (style ==
"cartoon") {
578 throw eve::Exception(
"createMeshShader: failed to create cartoon WGSL");
582 auto vert = copySpv(mesh3d_toon_vert_spv, mesh3d_toon_vert_spv_count);
583 auto frag = copySpv(mesh3d_toon_frag_spv, mesh3d_toon_frag_spv_count);
586 throw eve::Exception(
"createMeshShader: failed to create cartoon mesh shader");
590 if (style ==
"ink") {
595 throw eve::Exception(
"createMeshShader: failed to create ink WGSL");
599 auto vert = copySpv(mesh3d_toon_vert_spv, mesh3d_toon_vert_spv_count);
600 auto frag = copySpv(ink_mesh_frag_spv, ink_mesh_frag_spv_count);
603 throw eve::Exception(
"createMeshShader: failed to create ink mesh shader");
607 if (style ==
"xray") {
612 throw eve::Exception(
"createMeshShader: failed to create xray mesh shader (wgsl)");
617 auto vert = copySpv(mesh3d_toon_vert_spv, mesh3d_toon_vert_spv_count);
618 auto frag = copySpv(xray_mesh_frag_spv, xray_mesh_frag_spv_count);
621 throw eve::Exception(
"createMeshShader: failed to create xray mesh shader");
627 "createMeshShader: style '%s' has no mesh variant (use watercolor/pixel as post)",
EVENGINE_API_FOUNDATION public API.
virtual std::string getBackendName() const =0
Renderer backend id used by sibling modules (e.g. Gpgpu).
virtual Shader * newMeshShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Create a Mesh3D custom shader (MeshVertex + Frame UBO + albedo). Empty vert → default mesh3d....
virtual Shader * newShaderFromWgsl(const std::string &vertWgsl, const std::string &fragWgsl)=0
Create a 2D custom shader from WGSL source (WebGPU backend). Empty vert → default textured vertex sha...
virtual Shader * newShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Create a custom 2D shader from SPIR-V words (vert + frag). Owned by Graphics. Vertex stage may be emp...
virtual Shader * newMeshShaderFromWgsl(const std::string &vertWgsl, const std::string &fragWgsl)=0
Create a Mesh3D custom shader from WGSL source (WebGPU backend). The WGSL must declare the engine's F...
void setXray(bool x)
X-ray mesh shader. When true, drawMeshShader renders this mesh a second pass over the already-lit sce...
std::vector< ParamSpec > params
constexpr const char * kPixel
constexpr const char * kWatercolor
constexpr const char * kCommon
constexpr const char * kInk
constexpr const char * kMeshCommon
constexpr const char * kCartoon
constexpr const char * kInkMesh
constexpr const char * kCartoonMesh
graphics::Shader * createMeshShader(graphics::Graphics *gfx, const std::string &style)
Creates mesh shader.
void bindEffectMeshUniforms(graphics::Shader *shader, const std::string &style)
Binds effect mesh uniforms.
graphics::Shader * createEffectMeshShader(graphics::Graphics *gfx, const std::string &style)
Creates effect mesh shader.
bool styleSupports(const std::string &style, const std::string &feature)
Style supports.
std::string styleIdAt(int index)
Style id at.
bool isEffectStyle(const std::string &style)
True when style names one of the ported effect shaders.
graphics::Shader * createPostShader(graphics::Graphics *gfx, const std::string &style)
Creates post shader.
graphics::Shader * createEffectPostShader(graphics::Graphics *gfx, const std::string &style)
Creates effect post shader.
void bindMeshUniforms(graphics::Shader *shader, const std::string &style)
Binds mesh uniforms.
int effectStyleCount()
Effect style count.
int styleCount()
Style count.
int styleParamCount(const std::string &style)
Style param count.
void bindEffectPostUniforms(graphics::Shader *shader, const std::string &style)
Binds effect post uniforms.
void bindPostUniforms(graphics::Shader *shader, const std::string &style)
Binds post uniforms.
bool isKnownStyle(const std::string &style)
True when known style.
std::string effectStyleIdAt(int index)
Effect style id at.
const StyleDefinition * findEffectDefinition(const std::string &style)
Effect-only StyleDefinition lookup, or nullptr when unknown.
const StyleParameterDesc * findStyleParameter(const std::string &style, const std::string &name)
Finds style parameter.
std::string styleParamName(const std::string &style, int index)
Style param name.
int effectParamCount(const std::string &style)
Effect param count.
const StyleParameterDesc * styleParameterAt(const std::string &style, int index)
Style parameter at.
const StyleParameterDesc * effectParameterAt(const std::string &style, int index)
Effect parameter at.
const StyleDefinition * findStyleDefinition(const std::string &style)
Return a built-in definition, or nullptr when the id is unknown.
Immutable capability metadata for one built-in stylization recipe.
Tooling metadata for one user-facing float parameter.