6#include "graphics/shaders/mesh3d_hair_frag_spv.inc"
7#include "graphics/shaders/mesh3d_hair_vert_spv.inc"
16const std::array<const char *, 15> kParams = {
17 "specExp",
"specStrength",
"primaryShift",
"secondaryShift",
18 "alphaCutoff",
"rimStrength",
"strandDirX",
"strandDirY",
19 "strandDirZ",
"marschnerR",
"marschnerTT",
"marschnerTRT",
20 "selfShadowStrength",
"selfShadowBias",
"rootAoStrength"};
23std::vector<uint32_t> copySpv(
const uint32_t *data,
size_t count) {
24 return std::vector<uint32_t>(data, data +
count);
32 if (index < 0 || index >=
int(kParams.size()))
return {};
33 return kParams[size_t(
index)];
38 shader->declareFloat(
"specExp");
39 shader->declareFloat(
"specStrength");
40 shader->declareFloat(
"primaryShift");
41 shader->declareFloat(
"secondaryShift");
42 shader->declareFloat(
"alphaCutoff");
43 shader->declareFloat(
"rimStrength");
44 shader->declareVec3(
"strandDir");
45 shader->declareFloat(
"marschnerR");
46 shader->declareFloat(
"marschnerTT");
47 shader->declareFloat(
"marschnerTRT");
48 shader->declareFloat(
"selfShadowStrength");
49 shader->declareFloat(
"selfShadowBias");
50 shader->declareFloat(
"rootAoStrength");
51 shader->sendFloat(
"specExp", 80.f);
52 shader->sendFloat(
"specStrength", 0.85f);
53 shader->sendFloat(
"primaryShift", 0.08f);
54 shader->sendFloat(
"secondaryShift", -0.06f);
55 shader->sendFloat(
"alphaCutoff", 0.15f);
56 shader->sendFloat(
"rimStrength", 0.35f);
57 shader->sendVec3(
"strandDir", 0.f, 0.f, 0.f);
58 shader->sendFloat(
"marschnerR", 1.f);
59 shader->sendFloat(
"marschnerTT", 0.45f);
60 shader->sendFloat(
"marschnerTRT", 0.25f);
62 shader->sendFloat(
"selfShadowStrength", 0.35f);
63 shader->sendFloat(
"selfShadowBias", 0.25f);
64 shader->sendFloat(
"rootAoStrength", 0.3f);
68 if (!gfx)
throw eve::Exception(
"hair::createShader: null graphics");
69 auto vert = copySpv(mesh3d_hair_vert_spv, mesh3d_hair_vert_spv_count);
70 auto frag = copySpv(mesh3d_hair_frag_spv, mesh3d_hair_frag_spv_count);
75 throw eve::Exception(
"hair::createShader: failed to create hair shader");
EVENGINE_API_FOUNDATION public API.
virtual std::string getBackendName() const =0
Renderer backend id used by sibling modules (e.g. Gpgpu).
virtual Shader * newHairShaderFromWgsl(const std::string &vertWgsl, const std::string &fragWgsl)=0
Create an alpha-blended hair/card shader from WGSL on WebGPU.
virtual Shader * newHairShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Hair/fur card shader (alpha blend + Kajiya-Kay). Empty vert → mesh3d_hair.vert. Owned by Graphics.
Procedural hair/fur card meshes + material/LOD helpers (no strand simulation).
int paramCount()
Push-constant parameter names (same order as mesh3d_hair.frag).
std::string paramName(int index)
Param name.
Shader * createShader(Graphics *gfx)
Create the default hair shader (alpha-blended, anisotropic specular). Owned by Graphics.
void bindDefaults(Shader *shader)
Bind default push-constant knobs on an existing hair shader.
constexpr const char * kHairFragWgsl
Hair fragment shader WGSL source. @ownership Borrowed immutable string literal; callers must not free...