diff --git a/engine/includes/commandbuffer.h b/engine/includes/commandbuffer.h index 378e6100c..516fb26c7 100644 --- a/engine/includes/commandbuffer.h +++ b/engine/includes/commandbuffer.h @@ -24,6 +24,7 @@ struct Global { Vector4 cameraPosition; Vector4 cameraParams; Vector4 params; + Vector4 padding; }; class ENGINE_EXPORT CommandBuffer: public Object { @@ -34,7 +35,7 @@ class ENGINE_EXPORT CommandBuffer: public Object { void begin(); - virtual void dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ); + virtual void dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ); virtual void drawMesh(Mesh *mesh, uint32_t sub, uint32_t layer, MaterialInstance &instance); @@ -52,10 +53,6 @@ class ENGINE_EXPORT CommandBuffer: public Object { virtual void disableScissor(); - virtual Matrix4 projection() const; - - virtual Matrix4 view() const; - virtual Texture *texture(const TString &name) const; virtual void beginDebugMarker(const TString &name); diff --git a/engine/src/commandbuffer.cpp b/engine/src/commandbuffer.cpp index 3ee5dbc7f..dc04660bc 100644 --- a/engine/src/commandbuffer.cpp +++ b/engine/src/commandbuffer.cpp @@ -28,7 +28,7 @@ void CommandBuffer::begin() { Dispatches a compute \a shader with the specified workgroup dimensions. Parameters \a groupsX, \a groupsY and \a groupsZ alows to specify a size of workgroup in each demension. */ -void CommandBuffer::dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { +void CommandBuffer::dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { A_UNUSED(shader); A_UNUSED(groupsX); A_UNUSED(groupsY); @@ -104,18 +104,6 @@ void CommandBuffer::setGlobalTexture(const TString &name, Texture *texture) { item.binding = -1; m_textures.push_back(item); } -/*! - Returns current projection matrix. -*/ -Matrix4 CommandBuffer::projection() const { - return m_global.projection; -} -/*! - Returns current view matrix. -*/ -Matrix4 CommandBuffer::view() const { - return m_global.view; -} /*! Retrieves a global texture based on its \a name. */ diff --git a/modules/editor/shadertools/converter/shaderbuilder.cpp b/modules/editor/shadertools/converter/shaderbuilder.cpp index ba7bbe5a2..ad1a04af9 100644 --- a/modules/editor/shadertools/converter/shaderbuilder.cpp +++ b/modules/editor/shadertools/converter/shaderbuilder.cpp @@ -136,6 +136,77 @@ ShaderBuilderSettings::Rhi ShaderBuilder::currentRhi() { return rhi; } +TString uniformDataHelper(const Uniform &uniform, int &offset, int &sub) { + static const char *compNames = "xyzw"; + + TString comp = "."; + + TString prefix; + + switch(uniform.type) { + case MetaType::BOOLEAN: { + prefix = "floatBitsToInt("; + comp += TString(1, compNames[sub]) + ") != 0"; + sub++; + } break; + case MetaType::INTEGER: { + prefix = "floatBitsToInt("; + comp += TString(1, compNames[sub]) + ")"; + sub++; + } break; + case MetaType::FLOAT: { + comp += TString(1, compNames[sub]); + sub++; + } break; + case MetaType::VECTOR2: { + if(sub > 2) { + sub = 0; + offset++; + } + + comp += TString(1, compNames[sub]); + sub++; + comp += compNames[sub]; + sub++; + } break; + case MetaType::VECTOR3: { + if(sub > 1) { + sub = 0; + offset++; + } + + comp += TString(1, compNames[sub]); + sub++; + comp += compNames[sub]; + sub++; + comp += compNames[sub]; + sub++; + } break; + case MetaType::VECTOR4: { + comp.clear(); + sub = 4; + } break; + case MetaType::MATRIX4: { + comp.clear(); + sub = 0; + TString data = "mat4(\n"; + data += " instance.data[_instanceOffset + " + std::to_string(offset) + "],\n"; + offset++; + data += " instance.data[_instanceOffset + " + std::to_string(offset) + "],\n"; + offset++; + data += " instance.data[_instanceOffset + " + std::to_string(offset) + "],\n"; + offset++; + data += " instance.data[_instanceOffset + " + std::to_string(offset) + "])"; + offset++; + + return data; + } break; + default: break; + } + + return prefix + "instance.data[_instanceOffset + " + std::to_string(offset) + "]" + comp; +} + void ShaderBuilder::buildInstanceData(const VariantMap &user, PragmaMap &pragmas) { TString result; @@ -151,78 +222,46 @@ void ShaderBuilder::buildInstanceData(const VariantMap &user, PragmaMap &pragmas auto it = user.find(UNIFORMS); if(it != user.end()) { int sub = 0; - const char *compNames = "xyzw"; + + TString tab(" "); + for(auto &p : it->second.toList()) { Uniform uniform = uniformFromVariant(p); - TString comp; + TString data; - if(uniform.type == MetaType::MATRIX4) { - if(sub > 0) { - sub = 0; - offset++; - } + TString array; + if(uniform.count > 1) { + array = TString("[%1]").arg(TString::number(uniform.count)); + data = uniform.typeName + array + "(\n"; + } - } else { - TString prefix; - - switch(uniform.type) { - case MetaType::BOOLEAN: { - prefix = "floatBitsToInt("; - comp = TString(1, compNames[sub]); - comp += ") != 0"; - sub++; - } break; - case MetaType::INTEGER: { - prefix = "floatBitsToInt("; - comp = TString(1, compNames[sub]); - comp += ")"; - sub++; - } break; - case MetaType::FLOAT: { - comp = TString(1, compNames[sub]); - sub++; - } break; - case MetaType::VECTOR2: { - if(sub > 2) { - sub = 0; - offset++; - } - - comp = TString(1, compNames[sub]); - sub++; - comp += compNames[sub]; - sub++; - } break; - case MetaType::VECTOR3: { - if(sub > 1) { - sub = 0; - offset++; - } - - comp = TString(1, compNames[sub]); - sub++; - comp += compNames[sub]; - sub++; - comp += compNames[sub]; - sub++; - } break; - case MetaType::VECTOR4: { - comp = compNames; - sub = 4; - } break; - default: break; + for(int i = 0; i < uniform.count; i++) { + if(uniform.count > 1) { + data += tab + tab; + } + data += uniformDataHelper(uniform, offset, sub); + if(uniform.count > 1) { + if(i < uniform.count - 1) { + data += ",\n"; + } else { + data += "\n"; + } + } else { + data += ";\n"; } - - TString data = prefix + "instance.data[_instanceOffset + " + std::to_string(offset) + "]." + comp + ";\n"; if(sub >= 4) { sub = 0; offset++; } + } - uniforms += TString(" ") + uniform.typeName + " " + uniform.name + " = " + data; + if(uniform.count > 1) { + data += tab + ");\n"; } + + uniforms += tab + uniform.typeName + " " + uniform.name + array + " = " + data; } if(sub > 0) { @@ -234,7 +273,7 @@ void ShaderBuilder::buildInstanceData(const VariantMap &user, PragmaMap &pragmas pragmas["instance"] = result; pragmas["objectId"] = objectId; - pragmas["offset"] = "_instanceOffset = gl_InstanceIndex * " + std::to_string(offset) + ";\n"; + pragmas["offset"] = " _instanceOffset = gl_InstanceIndex * " + std::to_string(offset) + ";\n"; pragmas["skinOffset"] = "const int skinOffset = " + std::to_string(offset) + ";\n"; } @@ -511,10 +550,6 @@ bool ShaderBuilder::parseShaderFormat(const TString &path, VariantMap &user, int } } - if(materialType == Material::LightFunction) { - define += "\n#define NO_INSTANCE"; - } - str = shaders[gVertex]; if(!str.isEmpty()) { user[STATIC] = loadShader(str, define, pragmas); diff --git a/modules/editor/shadertools/shaders/Shader.frag b/modules/editor/shadertools/shaders/Shader.frag index 29a8f06ba..2c8d1fa81 100644 --- a/modules/editor/shadertools/shaders/Shader.frag +++ b/modules/editor/shadertools/shaders/Shader.frag @@ -27,7 +27,6 @@ layout(location = 0) out vec4 gbuffer0; #pragma uniforms #include "ShaderLayout.h" - #include "Functions.h" #pragma fragmentFunctions diff --git a/modules/renders/rendergl/includes/commandbuffergl.h b/modules/renders/rendergl/includes/commandbuffergl.h index 2d6a27779..5ec6917dd 100644 --- a/modules/renders/rendergl/includes/commandbuffergl.h +++ b/modules/renders/rendergl/includes/commandbuffergl.h @@ -9,7 +9,7 @@ class CommandBufferGL : public CommandBuffer { public: CommandBufferGL(); - void dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) override; + void dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) override; void drawMesh(Mesh *mesh, uint32_t sub, uint32_t layer, MaterialInstance &instance) override; diff --git a/modules/renders/rendergl/src/commandbuffergl.cpp b/modules/renders/rendergl/src/commandbuffergl.cpp index e18937f80..4c1727826 100644 --- a/modules/renders/rendergl/src/commandbuffergl.cpp +++ b/modules/renders/rendergl/src/commandbuffergl.cpp @@ -11,17 +11,15 @@ CommandBufferGL::CommandBufferGL() { PROFILE_FUNCTION(); } -void CommandBufferGL::dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { +void CommandBufferGL::dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { #ifndef THUNDER_MOBILE PROFILE_FUNCTION(); - if(shader) { - ComputeInstanceGL *instance = static_cast(shader); - if(instance->bind(this)) { - glDispatchCompute(groupsX, groupsY, groupsZ); + ComputeInstanceGL &instance = static_cast(shader); + if(instance.bind(this)) { + glDispatchCompute(groupsX, groupsY, groupsZ); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - } + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } #endif } diff --git a/modules/renders/rendermt/includes/commandbuffermt.h b/modules/renders/rendermt/includes/commandbuffermt.h index 1928186cc..259b9f5dc 100644 --- a/modules/renders/rendermt/includes/commandbuffermt.h +++ b/modules/renders/rendermt/includes/commandbuffermt.h @@ -23,7 +23,7 @@ class CommandBufferMt : public CommandBuffer { RenderTargetMt *currentRenderTarget() const; - void dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) override; + void dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) override; void drawMesh(Mesh *mesh, uint32_t sub, uint32_t layer, MaterialInstance &instance) override; diff --git a/modules/renders/rendermt/src/commandbuffermt.cpp b/modules/renders/rendermt/src/commandbuffermt.cpp index f4d1ee48d..5606aacf0 100644 --- a/modules/renders/rendermt/src/commandbuffermt.cpp +++ b/modules/renders/rendermt/src/commandbuffermt.cpp @@ -34,20 +34,18 @@ RenderTargetMt *CommandBufferMt::currentRenderTarget() const { return m_currentTarget; } -void CommandBufferMt::dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { +void CommandBufferMt::dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { PROFILE_FUNCTION(); - if(shader) { - ComputeInstanceMt *instance = static_cast(shader); + ComputeInstanceMt &instance = static_cast(shader); - MTL::ComputeCommandEncoder *computeEncoder = m_commandBuffer->computeCommandEncoder(); - if(instance->bind(this, computeEncoder)) { - MTL::Size threadgroupSize(instance->maxTotalThreadsPerThreadgroup(), 1, 1); + MTL::ComputeCommandEncoder *computeEncoder = m_commandBuffer->computeCommandEncoder(); + if(instance.bind(this, computeEncoder)) { + MTL::Size threadgroupSize(instance.maxTotalThreadsPerThreadgroup(), 1, 1); - computeEncoder->dispatchThreads(MTL::Size(groupsX, groupsY, groupsZ), threadgroupSize); + computeEncoder->dispatchThreads(MTL::Size(groupsX, groupsY, groupsZ), threadgroupSize); - computeEncoder->endEncoding(); - } + computeEncoder->endEncoding(); } } diff --git a/modules/renders/rendervk/includes/commandbuffervk.h b/modules/renders/rendervk/includes/commandbuffervk.h index b7083e42a..81acf2dff 100644 --- a/modules/renders/rendervk/includes/commandbuffervk.h +++ b/modules/renders/rendervk/includes/commandbuffervk.h @@ -27,7 +27,7 @@ class CommandBufferVk : public CommandBuffer { void beginDebugMarker(const TString &name) override; void endDebugMarker() override; - void dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) override; + void dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) override; void drawMesh(Mesh *mesh, uint32_t sub, uint32_t layer, MaterialInstance &instance) override; diff --git a/modules/renders/rendervk/src/commandbuffervk.cpp b/modules/renders/rendervk/src/commandbuffervk.cpp index 51fca6f0a..cb76cbcef 100644 --- a/modules/renders/rendervk/src/commandbuffervk.cpp +++ b/modules/renders/rendervk/src/commandbuffervk.cpp @@ -68,14 +68,12 @@ void CommandBufferVk::end() { } } -void CommandBufferVk::dispatchCompute(ComputeInstance *shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { +void CommandBufferVk::dispatchCompute(ComputeInstance &shader, int32_t groupsX, int32_t groupsY, int32_t groupsZ) { PROFILE_FUNCTION(); - if(shader) { - ComputeInstanceVk *comp = static_cast(shader); - if(comp->bind(*this)) { - vkCmdDispatch(m_commandBuffer, groupsX, groupsY, groupsZ); - } + ComputeInstanceVk &comp = static_cast(shader); + if(comp.bind(*this)) { + vkCmdDispatch(m_commandBuffer, groupsX, groupsY, groupsZ); } } diff --git a/worldeditor/bin/engine/materials/AreaLight.shader b/worldeditor/bin/engine/materials/AreaLight.shader index 8c14fe062..7ab0d1845 100644 --- a/worldeditor/bin/engine/materials/AreaLight.shader +++ b/worldeditor/bin/engine/materials/AreaLight.shader @@ -21,31 +21,19 @@ #pragma flags -#define NO_INSTANCE - -#include "ShaderLayout.h" - -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix[6]; - vec4 tiles[6]; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 bias; - vec4 position; - vec4 direction; - vec4 right; - vec4 up; - float shadows; -} uni; - layout(location = 0) in vec3 vertex; layout(location = 0) out vec4 _vertex; -layout(location = 1) flat out mat4 _screenToWorld; +layout(location = 1) flat out int _instanceOffset; +layout(location = 2) flat out mat4 _screenToWorld; + +#include "ShaderLayout.h" void main(void) { - _vertex = cameraWorldToScreen() * uni.model * vec4(vertex, 1.0); +#pragma offset +#pragma instance + + _vertex = cameraWorldToScreen() * modelMatrix() * vec4(vertex, 1.0); _screenToWorld = cameraScreenToWorld(); gl_Position = _vertex; } @@ -55,37 +43,22 @@ void main(void) { #pragma flags -#define NO_INSTANCE +layout(location = 0) in vec4 _vertex; +layout(location = 1) flat in int _instanceOffset; +layout(location = 2) flat in mat4 _screenToWorld; + +layout(location = 0) out vec4 rgb; #include "ShaderLayout.h" #include "Functions.h" #include "BRDF.h" -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix[6]; - vec4 tiles[6]; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 bias; - vec4 position; - vec4 direction; - vec4 right; - vec4 up; - float shadows; -} uni; - layout(binding = UNIFORM) uniform sampler2D normalsMap; layout(binding = UNIFORM + 2) uniform sampler2D diffuseMap; layout(binding = UNIFORM + 3) uniform sampler2D paramsMap; layout(binding = UNIFORM + 4) uniform sampler2D depthMap; layout(binding = UNIFORM + 5) uniform sampler2D shadowMap; -layout(location = 0) in vec4 _vertex; -layout(location = 1) flat in mat4 _screenToWorld; - -layout(location = 0) out vec4 rgb; - int sampleCube(const vec3 v) { vec3 vAbs = abs(v); if(vAbs.z >= vAbs.x && vAbs.z >= vAbs.y) { @@ -141,8 +114,11 @@ float rectangleSolidAngle(vec3 worldPos, vec3 p0, vec3 p1, vec3 p2, vec3 p3) { } void main (void) { - vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; +#pragma instance + // params = x - brightness, y - radius/width, z - length/height, w - cutoff + + vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; #ifdef ORIGIN_TOP proj.y = 1.0 - proj.y; #endif @@ -154,17 +130,17 @@ void main (void) { float depth = texture(depthMap, proj).x; vec3 world = getWorld(_screenToWorld, proj, depth); - vec3 dir = uni.position.xyz - world; + vec3 dir = position.xyz - world; float dist = length(dir); vec3 l = dir / dist; // Shadows step float factor = 1.0; - if(uni.shadows > 0.0) { + if(shadows > 0.0) { int index = sampleCube(-l); - vec4 offset = uni.tiles[index]; - vec4 proj = uni.matrix[index] * vec4(world, 1.0); + vec4 offset = tiles[index]; + vec4 proj = matrix[index] * vec4(world, 1.0); vec3 coord = (proj.xyz / proj.w); - factor = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - uni.bias.x); + factor = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - bias.x); } if(factor > 0.0) { @@ -184,19 +160,19 @@ void main (void) { float cosTheta = clamp(dot(l, n), -0.999, 0.999); - vec3 lightPlaneNormal = uni.direction.xyz; - float lightWidth = uni.params.y; - float lightHeight = uni.params.z; - float cutoff = uni.params.w; + vec3 lightPlaneNormal = direction.xyz; + float lightWidth = params.y; + float lightHeight = params.z; + float cutoff = params.w; float halfWidth = lightWidth * 0.5; float halfHeight = lightHeight * 0.5; - vec3 p0 = uni.position.xyz - uni.right.xyz * halfWidth + uni.up.xyz * halfHeight; - vec3 p1 = uni.position.xyz - uni.right.xyz * halfWidth - uni.up.xyz * halfHeight; - vec3 p2 = uni.position.xyz + uni.right.xyz * halfWidth - uni.up.xyz * halfHeight; - vec3 p3 = uni.position.xyz + uni.right.xyz * halfWidth + uni.up.xyz * halfHeight; + vec3 p0 = position.xyz - right.xyz * halfWidth + up.xyz * halfHeight; + vec3 p1 = position.xyz - right.xyz * halfWidth - up.xyz * halfHeight; + vec3 p2 = position.xyz + right.xyz * halfWidth - up.xyz * halfHeight; + vec3 p3 = position.xyz + right.xyz * halfWidth + up.xyz * halfHeight; - if(dot(world - uni.position.xyz, lightPlaneNormal) > 0) { + if(dot(world - position.xyz, lightPlaneNormal) > 0) { float solidAngle = rectangleSolidAngle(world, p0, p1, p2, p3); factor *= solidAngle * 0.25 * (clamp(dot(normalize(p0 - world), n), 0.0, 1.0) + @@ -222,7 +198,7 @@ void main (void) { vec3 result = albedo * (1.0 - metal) + (mix(vec3(spec), albedo, metal) * refl); - rgb = vec4(uni.color.xyz * uni.params.x * result * max(factor, 0.0), 1.0); + rgb = vec4(color.xyz * params.x * result * max(factor, 0.0), 1.0); return; } } diff --git a/worldeditor/bin/engine/materials/DirectLight.shader b/worldeditor/bin/engine/materials/DirectLight.shader index 710cc52aa..3cee7224f 100644 --- a/worldeditor/bin/engine/materials/DirectLight.shader +++ b/worldeditor/bin/engine/materials/DirectLight.shader @@ -19,10 +19,6 @@ #pragma flags -#define NO_INSTANCE - -#include "ShaderLayout.h" - layout(location = 0) in vec3 vertex; layout(location = 1) in vec2 uv0; layout(location = 2) in vec4 color; @@ -31,9 +27,16 @@ layout(location = 3) in vec3 normal; layout(location = 4) in vec3 tangent; layout(location = 0) out vec4 _vertex; -layout(location = 1) flat out mat4 _screenToWorld; +layout(location = 1) flat out int _instanceOffset; +layout(location = 2) flat out mat4 _screenToWorld; + +#include "ShaderLayout.h" void main(void) { + _instanceOffset = 0; + +#pragma instance + _vertex = vec4(vertex * 2.0, 1.0); _screenToWorld = cameraScreenToWorld(); gl_Position = _vertex; @@ -44,38 +47,26 @@ void main(void) { #pragma flags -#define NO_INSTANCE +layout(location = 0) in vec4 _vertex; +layout(location = 1) flat in int _instanceOffset; +layout(location = 2) flat in mat4 _screenToWorld; #include "ShaderLayout.h" #include "Functions.h" #include "BRDF.h" -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix[4]; - vec4 tiles[4]; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 direction; - vec4 bias; - vec4 planeDistance; - float shadows; -} uni; - layout(binding = UNIFORM + 1) uniform sampler2D normalsMap; layout(binding = UNIFORM + 2) uniform sampler2D diffuseMap; layout(binding = UNIFORM + 3) uniform sampler2D paramsMap; layout(binding = UNIFORM + 4) uniform sampler2D depthMap; layout(binding = UNIFORM + 5) uniform sampler2D shadowMap; -layout(location = 0) in vec4 _vertex; -layout(location = 1) flat in mat4 _screenToWorld; - layout(location = 0) out vec4 rgb; void main(void) { - vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; +#pragma instance + vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; #ifdef ORIGIN_TOP proj.y = 1.0 - proj.y; #endif @@ -98,49 +89,49 @@ void main(void) { vec3 albedo = slice2.xyz; vec3 v = normalize(cameraPosition() - world); - vec3 h = normalize(uni.direction.xyz + v); + vec3 h = normalize(direction.xyz + v); - float cosTheta = clamp(dot(uni.direction.xyz, n), 0.0, 1.0); + float cosTheta = clamp(dot(direction.xyz, n), 0.0, 1.0); float shadow = 1.0; vec3 debugColor = vec3(1.0); - if(uni.shadows > 0.0) { + if(shadows > 0.0) { int index = 3; - float bias = 0.0; - if(uni.planeDistance.x > depth) { + float currentBias = 0.0; + if(planeDistance.x > depth) { index = 0; debugColor = vec3(1, 0.5, 0.5); - bias = uni.bias.x; - } else if(uni.planeDistance.y > depth) { + currentBias = bias.x; + } else if(planeDistance.y > depth) { index = 1; debugColor = vec3(0.5, 1, 0.5); - bias = uni.bias.y; - } else if(uni.planeDistance.z > depth) { + currentBias = bias.y; + } else if(planeDistance.z > depth) { index = 2; debugColor = vec3(0.5, 0.5, 1); - bias = uni.bias.z; + currentBias = bias.z; } else { debugColor = vec3(1, 0.5, 1); - bias = uni.bias.w; + currentBias = bias.w; } - vec4 offset = uni.tiles[index]; - vec4 proj = uni.matrix[index] * vec4(world, 1.0); + vec4 offset = tiles[index]; + vec4 proj = matrix[index] * vec4(world, 1.0); vec3 coord = proj.xyz / proj.w; if(coord.x > 0.0 && coord.x < 1.0 && coord.y > 0.0 && coord.y < 1.0 && coord.z > 0.0 && coord.z < 1.0) { - shadow = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - bias); + shadow = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - currentBias); } } vec3 refl = mix(vec3(spec), albedo, metal) * getCookTorrance(n, v, h, cosTheta, rough); vec3 result = albedo * (1.0 - metal) + refl; - if(uni.shadows > 1.0) { + if(shadows > 1.0) { result *= debugColor; } - float diff = getLambert(cosTheta, uni.params.x) * shadow; + float diff = getLambert(cosTheta, params.x) * shadow; - rgb = vec4(uni.color.xyz * result * diff, 1.0); + rgb = vec4(color.xyz * result * diff, 1.0); return; } rgb = vec4(vec3(0.0), 1.0); diff --git a/worldeditor/bin/engine/materials/PointLight.shader b/worldeditor/bin/engine/materials/PointLight.shader index d2958a8d3..4b267c533 100644 --- a/worldeditor/bin/engine/materials/PointLight.shader +++ b/worldeditor/bin/engine/materials/PointLight.shader @@ -19,29 +19,19 @@ #pragma flags -#define NO_INSTANCE - -#include "ShaderLayout.h" - -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix[6]; - vec4 tiles[6]; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 bias; - vec4 position; - vec4 direction; - float shadows; -} uni; - layout(location = 0) in vec3 vertex; layout(location = 0) out vec4 _vertex; -layout(location = 1) flat out mat4 _screenToWorld; +layout(location = 1) flat out int _instanceOffset; +layout(location = 2) flat out mat4 _screenToWorld; + +#include "ShaderLayout.h" void main(void) { - _vertex = cameraWorldToScreen() * uni.model * vec4(vertex, 1.0); +#pragma offset +#pragma instance + + _vertex = cameraWorldToScreen() * modelMatrix() * vec4(vertex, 1.0); _screenToWorld = cameraScreenToWorld(); gl_Position = _vertex; } @@ -51,35 +41,22 @@ void main(void) { #pragma flags -#define NO_INSTANCE +layout(location = 0) in vec4 _vertex; +layout(location = 1) flat in int _instanceOffset; +layout(location = 2) flat in mat4 _screenToWorld; + +layout(location = 0) out vec4 rgb; #include "ShaderLayout.h" #include "Functions.h" #include "BRDF.h" -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix[6]; - vec4 tiles[6]; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 bias; - vec4 position; - vec4 direction; - float shadows; -} uni; - layout(binding = UNIFORM) uniform sampler2D normalsMap; layout(binding = UNIFORM + 1) uniform sampler2D diffuseMap; layout(binding = UNIFORM + 2) uniform sampler2D paramsMap; layout(binding = UNIFORM + 3) uniform sampler2D depthMap; layout(binding = UNIFORM + 4) uniform sampler2D shadowMap; -layout(location = 0) in vec4 _vertex; -layout(location = 1) flat in mat4 _screenToWorld; - -layout(location = 0) out vec4 rgb; - int sampleCube(const vec3 v) { vec3 vAbs = abs(v); if(vAbs.z >= vAbs.x && vAbs.z >= vAbs.y) { @@ -91,8 +68,11 @@ int sampleCube(const vec3 v) { } void main (void) { - vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; +#pragma instance + // params = x - brightness, y - radius/width, z - length/height, w - cutoff + + vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; #ifdef ORIGIN_TOP proj.y = 1.0 - proj.y; #endif @@ -104,17 +84,17 @@ void main (void) { float depth = texture(depthMap, proj).x; vec3 world = getWorld(_screenToWorld, proj, depth); - vec3 dir = uni.position.xyz - world; + vec3 dir = position.xyz - world; float dist = length(dir); vec3 l = dir / dist; // Shadows step float factor = 1.0; - if(uni.shadows > 0.0) { + if(shadows > 0.0) { int index = sampleCube(-l); - vec4 offset = uni.tiles[index]; - vec4 proj = uni.matrix[index] * vec4(world, 1.0); + vec4 offset = tiles[index]; + vec4 proj = matrix[index] * vec4(world, 1.0); vec3 coord = (proj.xyz / proj.w); - factor = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - uni.bias.x); + factor = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - bias.x); } if(factor > 0.0) { // Material parameters @@ -131,29 +111,29 @@ void main (void) { vec3 n = normalize(slice0.xyz * 2.0 - 1.0); vec3 r = -reflect(v, n); - float radius = uni.params.y; - float width = uni.params.z; - float cutoff = uni.params.w; - vec3 left = uni.direction.xyz; + float radius = params.y; + float width = params.z; + float cutoff = params.w; + vec3 left = direction.xyz; float cosTheta = clamp(dot(l, n), 0.0, 1.0); - vec3 spherePosition = uni.position.xyz; + vec3 spherePosition = position.xyz; vec3 sphereSpecularPosition = l; if(width > 0.0) { - vec3 P0 = uni.position.xyz - left * width * 0.5; - vec3 P1 = uni.position.xyz + left * width * 0.5; + vec3 P0 = position.xyz - left * width * 0.5; + vec3 P1 = position.xyz + left * width * 0.5; vec3 forward = normalize(closestPointOnLine(P0, P1, world) - world); vec3 up = cross(left, forward); float halfLength = 0.5 * width; - vec3 p0 = uni.position.xyz - left * halfLength + radius * up; - vec3 p1 = uni.position.xyz - left * halfLength - radius * up; - vec3 p2 = uni.position.xyz + left * halfLength - radius * up; - vec3 p3 = uni.position.xyz + left * halfLength + radius * up; + vec3 p0 = position.xyz - left * halfLength + radius * up; + vec3 p1 = position.xyz - left * halfLength - radius * up; + vec3 p2 = position.xyz + left * halfLength - radius * up; + vec3 p3 = position.xyz + left * halfLength + radius * up; spherePosition = closestPointOnSegment(P0, P1, world); @@ -191,7 +171,7 @@ void main (void) { vec3 result = albedo * (1.0 - metal) + (mix(vec3(spec), albedo, metal) * refl); - rgb = vec4(uni.color.xyz * uni.params.x * result * max(factor, 0.0), 1.0); + rgb = vec4(color.xyz * params.x * result * max(factor, 0.0), 1.0); return; } } diff --git a/worldeditor/bin/engine/materials/SpotLight.shader b/worldeditor/bin/engine/materials/SpotLight.shader index 4241a4117..bcf1f353b 100644 --- a/worldeditor/bin/engine/materials/SpotLight.shader +++ b/worldeditor/bin/engine/materials/SpotLight.shader @@ -19,29 +19,19 @@ #pragma flags -#define NO_INSTANCE - -#include "ShaderLayout.h" - -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix; - vec4 tiles; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 bias; - vec4 position; - vec4 direction; - float shadows; -} uni; - layout(location = 0) in vec3 vertex; layout(location = 0) out vec4 _vertex; -layout(location = 1) flat out mat4 _screenToWorld; +layout(location = 1) flat out int _instanceOffset; +layout(location = 2) flat out mat4 _screenToWorld; + +#include "ShaderLayout.h" void main(void) { - _vertex = cameraWorldToScreen() * uni.model * vec4(vertex, 1.0); +#pragma offset +#pragma instance + + _vertex = cameraWorldToScreen() * modelMatrix() * vec4(vertex, 1.0); _screenToWorld = cameraScreenToWorld(); gl_Position = _vertex; } @@ -51,42 +41,32 @@ void main(void) { #pragma flags -#define NO_INSTANCE +layout(location = 0) in vec4 _vertex; +layout(location = 1) flat in int _instanceOffset; +layout(location = 2) flat in mat4 _screenToWorld; + +layout(location = 0) out vec4 rgb; #include "ShaderLayout.h" #include "Functions.h" #include "BRDF.h" -layout(binding = LOCAL) uniform InstanceData { - mat4 model; - mat4 matrix; - vec4 tiles; - vec4 color; - vec4 params; // x - brightness, y - radius/width, z - length/height, w - cutoff - vec4 bias; - vec4 position; - vec4 direction; - float shadows; -} uni; - layout(binding = UNIFORM) uniform sampler2D normalsMap; layout(binding = UNIFORM + 1) uniform sampler2D diffuseMap; layout(binding = UNIFORM + 2) uniform sampler2D paramsMap; layout(binding = UNIFORM + 3) uniform sampler2D depthMap; layout(binding = UNIFORM + 4) uniform sampler2D shadowMap; -layout(location = 0) in vec4 _vertex; -layout(location = 1) flat in mat4 _screenToWorld; - -layout(location = 0) out vec4 rgb; - void main (void) { - vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; +#pragma instance + vec2 proj = ((_vertex.xyz / _vertex.w) * 0.5 + 0.5).xy; #ifdef ORIGIN_TOP proj.y = 1.0 - proj.y; #endif + // params = x - brightness, y - radius/width, z - length/height, w - cutoff + vec4 slice0 = texture(normalsMap, proj); // Light model LIT @@ -96,21 +76,21 @@ void main (void) { vec3 n = normalize(slice0.xyz * 2.0 - 1.0); - vec3 dir = uni.position.xyz - world; + vec3 dir = position.xyz - world; vec3 l = normalize(dir); float dist = length(dir); - float spot = dot(l, uni.direction.xyz); + float spot = dot(l, direction.xyz); float fall = 0.0; - if(spot > uni.params.w) { - fall = 1.0 - (1.0 - spot) / (1.0 - uni.params.w); - fall = getAttenuation(dist, uni.params.y) * uni.params.x * fall; + if(spot > params.w) { + fall = 1.0 - (1.0 - spot) / (1.0 - params.w); + fall = getAttenuation(dist, params.y) * params.x * fall; } vec4 slice1 = texture(paramsMap, proj); float rough = slice1.x; float metal = slice1.z; - float spec = slice1.w; + float spec = slice1.w; vec4 slice2 = texture(diffuseMap, proj); vec3 albedo = slice2.xyz; @@ -121,18 +101,17 @@ void main (void) { float cosTheta = clamp(dot(l, n), 0.0, 1.0); float shadow = 1.0; - if(uni.shadows > 0.0) { - vec4 offset = uni.tiles; - vec4 proj = uni.matrix * vec4(world, 1.0); + if(shadows > 0.0) { + vec4 proj = matrix * vec4(world, 1.0); vec3 coord = (proj.xyz / proj.w); - shadow = getShadow(shadowMap, (coord.xy * offset.zw) + offset.xy, coord.z - uni.bias.x); + shadow = getShadow(shadowMap, (coord.xy * tiles.zw) + tiles.xy, coord.z - bias.x); } vec3 refl = mix(vec3(spec), albedo, metal) * getCookTorrance(n, v, h, cosTheta, rough); vec3 result = albedo * (1.0 - metal) + refl; - float diff = max(PI * getLambert(cosTheta, uni.params.x) * fall * shadow, 0.0); + float diff = max(PI * getLambert(cosTheta, params.x) * fall * shadow, 0.0); - rgb = vec4(uni.color.xyz * result * diff, 1.0); + rgb = vec4(color.xyz * result * diff, 1.0); return; } rgb = vec4(vec3(0.0), 1.0);