From 642388709bc4110bd32c916195d98b4104dd5652 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sat, 6 Aug 2022 13:06:42 -0700 Subject: [PATCH] Shader helper improvements; --- etc/shaders/animator.comp | 9 +++++--- etc/shaders/equirect.frag | 2 -- etc/shaders/lovr.glsl | 37 ++++++++++++++++++++++--------- src/api/l_data_modelData.c | 1 - src/api/l_graphics.c | 22 ++++++++---------- src/api/l_graphics_material.c | 1 - src/api/l_graphics_shader.c | 6 ++--- src/core/gpu.h | 6 ++--- src/core/gpu_vk.c | 14 ++++++------ src/core/spv.c | 6 ++--- src/core/spv.h | 2 +- src/modules/data/modelData.h | 1 - src/modules/data/modelData_gltf.c | 3 +-- src/modules/data/modelData_obj.c | 3 +-- src/modules/graphics/graphics.c | 25 ++++++++++++--------- src/modules/graphics/graphics.h | 9 ++++---- 16 files changed, 79 insertions(+), 68 deletions(-) diff --git a/etc/shaders/animator.comp b/etc/shaders/animator.comp index 464b3007..2e7b79cb 100644 --- a/etc/shaders/animator.comp +++ b/etc/shaders/animator.comp @@ -1,4 +1,7 @@ #version 460 +#extension GL_GOOGLE_include_directive : require + +#include "lovr.glsl" layout(local_size_x = 32, local_size_x_id = 0) in; @@ -25,9 +28,9 @@ layout(set = 0, binding = 1) buffer restrict writeonly VertexOut { ModelVertex v layout(set = 0, binding = 2) buffer restrict readonly VertexWeights { SkinVertex skin[]; }; layout(set = 0, binding = 3) uniform JointTransforms { mat4 joints[256]; }; -void main() { - if (gl_GlobalInvocationID.x >= vertexCount) return; - uint vertexIndex = baseVertex + gl_GlobalInvocationID.x; +void lovrmain() { + if (GlobalThreadID.x >= vertexCount) return; + uint vertexIndex = baseVertex + GlobalThreadID.x; uint indices = skin[vertexIndex].indices; uint i0 = (indices >> 0) & 0xff; diff --git a/etc/shaders/equirect.frag b/etc/shaders/equirect.frag index 2525d005..8b873cfb 100644 --- a/etc/shaders/equirect.frag +++ b/etc/shaders/equirect.frag @@ -4,8 +4,6 @@ #include "lovr.glsl" -#define PI 3.141592653589793238462643383 - layout(location = 0) in vec3 Direction; vec4 lovrmain() { diff --git a/etc/shaders/lovr.glsl b/etc/shaders/lovr.glsl index 4eece836..171e5509 100644 --- a/etc/shaders/lovr.glsl +++ b/etc/shaders/lovr.glsl @@ -33,7 +33,6 @@ struct MaterialData { float clearcoat; float clearcoatRoughness; float occlusionStrength; - float glowStrength; float normalScale; float alphaCutoff; float pointSize; @@ -81,7 +80,13 @@ layout(location = 12) in vec2 UV; // Macros #ifdef GL_COMPUTE_SHADER -// +#define SubgroupCount gl_NumSubgroups +#define WorkgroupCount gl_NumWorkGroups +#define WorkgroupSize gl_WorkGroupSize +#define WorkgroupID gl_WorkGroupID +#define GlobalThreadID gl_GlobalInvocationID +#define LocalThreadID gl_LocalInvocationID +#define LocalThreadIndex gl_LocalInvocationIndex #else #define BaseInstance gl_BaseInstance #define BaseVertex gl_BaseVertex @@ -95,36 +100,46 @@ layout(location = 12) in vec2 UV; #define PointCoord gl_PointCoord #define PointSize gl_PointSize #define Position gl_Position -#define PrimitiveId gl_PrimitiveID -#define SampleId gl_SampleID +#define PrimitiveID gl_PrimitiveID +#define SampleID gl_SampleID #define SampleMaskIn gl_SampleMaskIn #define SampleMask gl_SampleMask #define SamplePosition gl_SamplePosition #define VertexIndex gl_VertexIndex #define ViewIndex gl_ViewIndex -#define DrawId gl_BaseInstance +#define DrawID gl_BaseInstance #define Projection Cameras[ViewIndex].projection #define View Cameras[ViewIndex].view #define ViewProjection Cameras[ViewIndex].viewProjection #define InverseProjection Cameras[ViewIndex].inverseProjection -#define Transform Draws[DrawId].transform -#define NormalMatrix mat3(Draws[DrawId].normalMatrix) -#define PassColor Draws[DrawId].color +#define Transform Draws[DrawID].transform +#define NormalMatrix mat3(Draws[DrawID].normalMatrix) +#define PassColor Draws[DrawID].color #define ClipFromLocal (ViewProjection * Transform) #define ClipFromWorld (ViewProjection) #define ClipFromView (Projection) #define ViewFromLocal (View * Transform) #define ViewFromWorld (View) +#define ViewFromClip (InverseProjection) #define WorldFromLocal (Transform) +#define WorldFromView (inverse(View)) +#define WorldFromClip (inverse(ViewProjection)) + +#define CameraPositionWorld (-View[3].xyz * mat3(View)) #define DefaultPosition (ClipFromLocal * VertexPosition) #define DefaultColor (Color * getPixel(ColorTexture, UV)) #endif +// Constants +#define PI 3.141592653589793238462643383279502f +#define TAU (2.f * PI) +#define PI_2 (.5f * PI) + // Helpers -#ifdef GL_FRAGMENT_SHADER +#ifndef GL_COMPUTE_SHADER vec4 getPixel(texture2D t, vec2 uv) { return texture(sampler2D(t, Sampler), uv); } vec4 getPixel(texture3D t, vec3 uvw) { return texture(sampler3D(t, Sampler), uvw); } vec4 getPixel(textureCube t, vec3 dir) { return texture(samplerCube(t, Sampler), dir); } @@ -156,7 +171,7 @@ void main() { PixelColors[0] = lovrmain(); if (applyGlow) { - PixelColors[0].rgb += getPixel(GlowTexture, UV).rgb * Material.glow.rgb; + PixelColors[0].rgb += getPixel(GlowTexture, UV).rgb * Material.glow.rgb * Material.glow.a; } if (applyAlphaCutoff && PixelColors[0].a <= Material.alphaCutoff) { @@ -166,7 +181,7 @@ void main() { #endif #ifdef GL_COMPUTE_SHADER -vec4 lovrmain(); +void lovrmain(); void main() { lovrmain(); } diff --git a/src/api/l_data_modelData.c b/src/api/l_data_modelData.c index 1a550ce7..165159c5 100644 --- a/src/api/l_data_modelData.c +++ b/src/api/l_data_modelData.c @@ -607,7 +607,6 @@ static int l_lovrModelDataGetMaterial(lua_State* L) { lua_pushnumber(L, material->clearcoat), lua_setfield(L, -2, "clearcoat"); lua_pushnumber(L, material->clearcoatRoughness), lua_setfield(L, -2, "clearcoatRoughness"); lua_pushnumber(L, material->occlusionStrength), lua_setfield(L, -2, "occlusionStrength"); - lua_pushnumber(L, material->glowStrength), lua_setfield(L, -2, "glowStrength"); lua_pushnumber(L, material->normalScale), lua_setfield(L, -2, "normalScale"); lua_pushnumber(L, material->alphaCutoff), lua_setfield(L, -2, "alphaCutoff"); lua_pushnumber(L, material->pointSize), lua_setfield(L, -2, "pointSize"); diff --git a/src/api/l_graphics.c b/src/api/l_graphics.c index ba3c5988..397266c1 100644 --- a/src/api/l_graphics.c +++ b/src/api/l_graphics.c @@ -771,18 +771,18 @@ static int l_lovrGraphicsGetLimits(lua_State* L) { lua_pushinteger(L, limits.clipAndCullDistances), lua_setfield(L, -2, "clipAndCullDistances"); lua_createtable(L, 3, 0); - lua_pushinteger(L, limits.computeDispatchCount[0]), lua_rawseti(L, -2, 1); - lua_pushinteger(L, limits.computeDispatchCount[1]), lua_rawseti(L, -2, 2); - lua_pushinteger(L, limits.computeDispatchCount[2]), lua_rawseti(L, -2, 3); - lua_setfield(L, -2, "computeDispatchCount"); + lua_pushinteger(L, limits.workgroupCount[0]), lua_rawseti(L, -2, 1); + lua_pushinteger(L, limits.workgroupCount[1]), lua_rawseti(L, -2, 2); + lua_pushinteger(L, limits.workgroupCount[2]), lua_rawseti(L, -2, 3); + lua_setfield(L, -2, "workgroupCount"); lua_createtable(L, 3, 0); - lua_pushinteger(L, limits.computeWorkgroupSize[0]), lua_rawseti(L, -2, 1); - lua_pushinteger(L, limits.computeWorkgroupSize[1]), lua_rawseti(L, -2, 2); - lua_pushinteger(L, limits.computeWorkgroupSize[2]), lua_rawseti(L, -2, 3); - lua_setfield(L, -2, "computeWorkgroupSize"); + lua_pushinteger(L, limits.workgroupSize[0]), lua_rawseti(L, -2, 1); + lua_pushinteger(L, limits.workgroupSize[1]), lua_rawseti(L, -2, 2); + lua_pushinteger(L, limits.workgroupSize[2]), lua_rawseti(L, -2, 3); + lua_setfield(L, -2, "workgroupSize"); - lua_pushinteger(L, limits.computeWorkgroupVolume), lua_setfield(L, -2, "computeWorkgroupVolume"); + lua_pushinteger(L, limits.totalWorkgroupSize), lua_setfield(L, -2, "totalWorkgroupSize"); lua_pushinteger(L, limits.computeSharedMemory), lua_setfield(L, -2, "computeSharedMemory"); lua_pushinteger(L, limits.shaderConstantSize), lua_setfield(L, -2, "shaderConstantSize"); lua_pushinteger(L, limits.indirectDrawCount), lua_setfield(L, -2, "indirectDrawCount"); @@ -1346,10 +1346,6 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) { info.data.occlusionStrength = luax_optfloat(L, -1, 1.f); lua_pop(L, 1); - lua_getfield(L, 1, "glowStrength"); - info.data.glowStrength = luax_optfloat(L, -1, 1.f); - lua_pop(L, 1); - lua_getfield(L, 1, "normalScale"); info.data.normalScale = luax_optfloat(L, -1, 1.f); lua_pop(L, 1); diff --git a/src/api/l_graphics_material.c b/src/api/l_graphics_material.c index 792e694a..2c8cad59 100644 --- a/src/api/l_graphics_material.c +++ b/src/api/l_graphics_material.c @@ -50,7 +50,6 @@ static int l_lovrMaterialGetProperties(lua_State* L) { lua_pushnumber(L, info->data.clearcoat), lua_setfield(L, -2, "clearcoat"); lua_pushnumber(L, info->data.clearcoatRoughness), lua_setfield(L, -2, "clearcoatRoughness"); lua_pushnumber(L, info->data.occlusionStrength), lua_setfield(L, -2, "occlusionStrength"); - lua_pushnumber(L, info->data.glowStrength), lua_setfield(L, -2, "glowStrength"); lua_pushnumber(L, info->data.normalScale), lua_setfield(L, -2, "normalScale"); lua_pushnumber(L, info->data.alphaCutoff), lua_setfield(L, -2, "alphaCutoff"); lua_pushnumber(L, info->data.pointSize), lua_setfield(L, -2, "pointSize"); diff --git a/src/api/l_graphics_shader.c b/src/api/l_graphics_shader.c index 74397668..bdcfe0b4 100644 --- a/src/api/l_graphics_shader.c +++ b/src/api/l_graphics_shader.c @@ -64,7 +64,7 @@ static int l_lovrShaderHasAttribute(lua_State* L) { return 1; } -static int l_lovrShaderGetLocalWorkgroupSize(lua_State* L) { +static int l_lovrShaderGetWorkgroupSize(lua_State* L) { Shader* shader = luax_checktype(L, 1, Shader); if (!lovrShaderHasStage(shader, STAGE_COMPUTE)) { @@ -73,7 +73,7 @@ static int l_lovrShaderGetLocalWorkgroupSize(lua_State* L) { } uint32_t size[3]; - lovrShaderGetLocalWorkgroupSize(shader, size); + lovrShaderGetWorkgroupSize(shader, size); lua_pushinteger(L, size[0]); lua_pushinteger(L, size[1]); lua_pushinteger(L, size[2]); @@ -85,6 +85,6 @@ const luaL_Reg lovrShader[] = { { "getType", l_lovrShaderGetType }, { "hasStage", l_lovrShaderHasStage }, { "hasAttribute", l_lovrShaderHasAttribute }, - { "getLocalWorkgroupSize", l_lovrShaderGetLocalWorkgroupSize }, + { "getWorkgroupSize", l_lovrShaderGetWorkgroupSize }, { NULL, NULL } }; diff --git a/src/core/gpu.h b/src/core/gpu.h index 7ec006aa..e669a5c7 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -665,9 +665,9 @@ typedef struct { uint32_t clipDistances; uint32_t cullDistances; uint32_t clipAndCullDistances; - uint32_t computeDispatchCount[3]; - uint32_t computeWorkgroupSize[3]; - uint32_t computeWorkgroupVolume; + uint32_t workgroupCount[3]; + uint32_t workgroupSize[3]; + uint32_t totalWorkgroupSize; uint32_t computeSharedMemory; uint32_t pushConstantSize; uint32_t indirectDrawCount; diff --git a/src/core/gpu_vk.c b/src/core/gpu_vk.c index a00c179a..f3ccd418 100644 --- a/src/core/gpu_vk.c +++ b/src/core/gpu_vk.c @@ -1928,13 +1928,13 @@ bool gpu_init(gpu_config* config) { config->limits->clipDistances = limits->maxClipDistances; config->limits->cullDistances = limits->maxCullDistances; config->limits->clipAndCullDistances = limits->maxCombinedClipAndCullDistances; - config->limits->computeDispatchCount[0] = limits->maxComputeWorkGroupCount[0]; - config->limits->computeDispatchCount[1] = limits->maxComputeWorkGroupCount[1]; - config->limits->computeDispatchCount[2] = limits->maxComputeWorkGroupCount[2]; - config->limits->computeWorkgroupSize[0] = limits->maxComputeWorkGroupSize[0]; - config->limits->computeWorkgroupSize[1] = limits->maxComputeWorkGroupSize[1]; - config->limits->computeWorkgroupSize[2] = limits->maxComputeWorkGroupSize[2]; - config->limits->computeWorkgroupVolume = limits->maxComputeWorkGroupInvocations; + config->limits->workgroupCount[0] = limits->maxComputeWorkGroupCount[0]; + config->limits->workgroupCount[1] = limits->maxComputeWorkGroupCount[1]; + config->limits->workgroupCount[2] = limits->maxComputeWorkGroupCount[2]; + config->limits->workgroupSize[0] = limits->maxComputeWorkGroupSize[0]; + config->limits->workgroupSize[1] = limits->maxComputeWorkGroupSize[1]; + config->limits->workgroupSize[2] = limits->maxComputeWorkGroupSize[2]; + config->limits->totalWorkgroupSize = limits->maxComputeWorkGroupInvocations; config->limits->computeSharedMemory = limits->maxComputeSharedMemorySize; config->limits->pushConstantSize = limits->maxPushConstantsSize; config->limits->indirectDrawCount = limits->maxDrawIndirectCount; diff --git a/src/core/spv.c b/src/core/spv.c index acdcc982..b68f6f65 100644 --- a/src/core/spv.c +++ b/src/core/spv.c @@ -187,9 +187,9 @@ static spv_result spv_parse_execution_mode(spv_context* spv, const uint32_t* op, return SPV_OK; } - info->localWorkgroupSize[0] = op[3]; - info->localWorkgroupSize[1] = op[4]; - info->localWorkgroupSize[2] = op[5]; + info->workgroupSize[0] = op[3]; + info->workgroupSize[1] = op[4]; + info->workgroupSize[2] = op[5]; return SPV_OK; } diff --git a/src/core/spv.h b/src/core/spv.h index b6280e4e..593387df 100644 --- a/src/core/spv.h +++ b/src/core/spv.h @@ -56,7 +56,7 @@ typedef struct { typedef struct { uint32_t version; - uint32_t localWorkgroupSize[3]; + uint32_t workgroupSize[3]; uint32_t featureCount; uint32_t specConstantCount; uint32_t pushConstantCount; diff --git a/src/modules/data/modelData.h b/src/modules/data/modelData.h index a0898c09..8e52225a 100644 --- a/src/modules/data/modelData.h +++ b/src/modules/data/modelData.h @@ -84,7 +84,6 @@ typedef struct { float clearcoat; float clearcoatRoughness; float occlusionStrength; - float glowStrength; float normalScale; float alphaCutoff; float pointSize; diff --git a/src/modules/data/modelData_gltf.c b/src/modules/data/modelData_gltf.c index 1aaad5e5..3a88258a 100644 --- a/src/modules/data/modelData_gltf.c +++ b/src/modules/data/modelData_gltf.c @@ -695,7 +695,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io ModelMaterial* material = model->materials; for (int i = (token++)->size; i > 0; i--, material++) { memcpy(material->color, (float[4]) { 1.f, 1.f, 1.f, 1.f }, 16); - memcpy(material->glow, (float[4]) { 0.f, 0.f, 0.f, 0.f }, 16); + memcpy(material->glow, (float[4]) { 0.f, 0.f, 0.f, 1.f }, 16); material->uvShift[0] = 0.f; material->uvShift[1] = 0.f; material->uvScale[0] = 1.f; @@ -705,7 +705,6 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io material->clearcoat = 0.f; material->clearcoatRoughness = 0.f; material->occlusionStrength = 1.f; - material->glowStrength = 1.f; material->normalScale = 1.f; material->alphaCutoff = 0.f; material->pointSize = 1.f; diff --git a/src/modules/data/modelData_obj.c b/src/modules/data/modelData_obj.c index c47dce6b..7d6dfc85 100644 --- a/src/modules/data/modelData_obj.c +++ b/src/modules/data/modelData_obj.c @@ -48,7 +48,7 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_image_t* image map_set(names, hash64(line + 7, length - 7), materials->length); arr_push(materials, ((ModelMaterial) { .color = { 1.f, 1.f, 1.f, 1.f }, - .glow = { 0.f, 0.f, 0.f, 0.f }, + .glow = { 0.f, 0.f, 0.f, 1.f }, .uvShift = { 0.f, 0.f }, .uvScale = { 1.f, 1.f }, .metalness = 1.f, @@ -56,7 +56,6 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_image_t* image .clearcoat = 0.f, .clearcoatRoughness = 0.f, .occlusionStrength = 1.f, - .glowStrength = 1.f, .normalScale = 1.f, .alphaCutoff = 0.f, .pointSize = 1.f, diff --git a/src/modules/graphics/graphics.c b/src/modules/graphics/graphics.c index b880b9e2..6bfe4c18 100644 --- a/src/modules/graphics/graphics.c +++ b/src/modules/graphics/graphics.c @@ -101,7 +101,7 @@ struct Shader { ShaderInfo info; uint32_t layout; uint32_t computePipeline; - uint32_t localWorkgroupSize[3]; + uint32_t workgroupSize[3]; uint32_t bufferMask; uint32_t textureMask; uint32_t samplerMask; @@ -728,9 +728,9 @@ void lovrGraphicsGetLimits(GraphicsLimits* limits) { limits->clipDistances = state.limits.clipDistances; limits->cullDistances = state.limits.cullDistances; limits->clipAndCullDistances = state.limits.clipAndCullDistances; - memcpy(limits->computeDispatchCount, state.limits.computeDispatchCount, 3 * sizeof(uint32_t)); - memcpy(limits->computeWorkgroupSize, state.limits.computeWorkgroupSize, 3 * sizeof(uint32_t)); - limits->computeWorkgroupVolume = state.limits.computeWorkgroupVolume; + memcpy(limits->workgroupCount, state.limits.workgroupCount, 3 * sizeof(uint32_t)); + memcpy(limits->workgroupSize, state.limits.workgroupSize, 3 * sizeof(uint32_t)); + limits->totalWorkgroupSize = state.limits.totalWorkgroupSize; limits->computeSharedMemory = state.limits.computeSharedMemory; limits->shaderConstantSize = MIN(state.limits.pushConstantSize, 256); limits->indirectDrawCount = state.limits.indirectDrawCount; @@ -1556,7 +1556,12 @@ Shader* lovrShaderCreate(const ShaderInfo* info) { } if (info->type == SHADER_COMPUTE) { - memcpy(shader->localWorkgroupSize, spv[0].localWorkgroupSize, 3 * sizeof(uint32_t)); + memcpy(shader->workgroupSize, spv[0].workgroupSize, 3 * sizeof(uint32_t)); + lovrCheck(shader->workgroupSize[0] <= state.limits.workgroupSize[0], "Shader workgroup size exceeds the 'workgroupSize' limit"); + lovrCheck(shader->workgroupSize[1] <= state.limits.workgroupSize[1], "Shader workgroup size exceeds the 'workgroupSize' limit"); + lovrCheck(shader->workgroupSize[2] <= state.limits.workgroupSize[2], "Shader workgroup size exceeds the 'workgroupSize' limit"); + uint32_t totalWorkgroupSize = shader->workgroupSize[0] * shader->workgroupSize[1] * shader->workgroupSize[2]; + lovrCheck(totalWorkgroupSize <= state.limits.totalWorkgroupSize, "Shader workgroup size exceeds the 'totalWorkgroupSize' limit"); } uint32_t constantStage = spv[0].pushConstantSize > spv[1].pushConstantSize ? 0 : 1; @@ -1818,8 +1823,8 @@ bool lovrShaderHasAttribute(Shader* shader, const char* name, uint32_t location) return false; } -void lovrShaderGetLocalWorkgroupSize(Shader* shader, uint32_t size[3]) { - memcpy(size, shader->localWorkgroupSize, 3 * sizeof(uint32_t)); +void lovrShaderGetWorkgroupSize(Shader* shader, uint32_t size[3]) { + memcpy(size, shader->workgroupSize, 3 * sizeof(uint32_t)); } // Material @@ -5087,9 +5092,9 @@ void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* ind Shader* shader = pass->pipeline->shader; lovrCheck(shader && shader->info.type == SHADER_COMPUTE, "Tried to run a compute shader, but no compute shader is bound"); - lovrCheck(x <= state.limits.computeDispatchCount[0], "Compute %s count exceeds computeDispatchCount limit", "x"); - lovrCheck(y <= state.limits.computeDispatchCount[1], "Compute %s count exceeds computeDispatchCount limit", "y"); - lovrCheck(z <= state.limits.computeDispatchCount[2], "Compute %s count exceeds computeDispatchCount limit", "z"); + lovrCheck(x <= state.limits.workgroupCount[0], "Compute %s count exceeds workgroupCount limit", "x"); + lovrCheck(y <= state.limits.workgroupCount[1], "Compute %s count exceeds workgroupCount limit", "y"); + lovrCheck(z <= state.limits.workgroupCount[2], "Compute %s count exceeds workgroupCount limit", "z"); gpu_pipeline* pipeline = state.pipelines.data[shader->computePipeline]; diff --git a/src/modules/graphics/graphics.h b/src/modules/graphics/graphics.h index 0413e34c..d4c130fe 100644 --- a/src/modules/graphics/graphics.h +++ b/src/modules/graphics/graphics.h @@ -72,9 +72,9 @@ typedef struct { uint32_t clipDistances; uint32_t cullDistances; uint32_t clipAndCullDistances; - uint32_t computeDispatchCount[3]; - uint32_t computeWorkgroupSize[3]; - uint32_t computeWorkgroupVolume; + uint32_t workgroupCount[3]; + uint32_t workgroupSize[3]; + uint32_t totalWorkgroupSize; uint32_t computeSharedMemory; uint32_t shaderConstantSize; uint32_t indirectDrawCount; @@ -315,7 +315,7 @@ void lovrShaderDestroy(void* ref); const ShaderInfo* lovrShaderGetInfo(Shader* shader); bool lovrShaderHasStage(Shader* shader, ShaderStage stage); bool lovrShaderHasAttribute(Shader* shader, const char* name, uint32_t location); -void lovrShaderGetLocalWorkgroupSize(Shader* shader, uint32_t size[3]); +void lovrShaderGetWorkgroupSize(Shader* shader, uint32_t size[3]); // Material @@ -330,7 +330,6 @@ typedef struct { float clearcoat; float clearcoatRoughness; float occlusionStrength; - float glowStrength; float normalScale; float alphaCutoff; float pointSize;