mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 04:28:59 +02:00
Reimplement procedural uniforms without extension requirements
This commit is contained in:
parent
c8e664a0a1
commit
3f2f5b18ec
3 changed files with 97 additions and 82 deletions
|
@ -40,7 +40,7 @@ static const std::string PROCEDURAL_VERSION = "//PROCEDURAL_VERSION";
|
|||
|
||||
bool operator==(const ProceduralData& a, const ProceduralData& b) {
|
||||
return ((a.version == b.version) && (a.shaderUrl == b.shaderUrl) && (a.uniforms == b.uniforms) &&
|
||||
(a.channels == b.channels));
|
||||
(a.channels == b.channels));
|
||||
}
|
||||
|
||||
QJsonValue ProceduralData::getProceduralData(const QString& proceduralJson) {
|
||||
|
@ -105,7 +105,7 @@ Procedural::Procedural() {
|
|||
_transparentState->setCullMode(gpu::State::CULL_NONE);
|
||||
_transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
_transparentState->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
_standardInputsBuffer = std::make_shared<gpu::Buffer>(sizeof(StandardInputs), nullptr);
|
||||
}
|
||||
|
@ -211,10 +211,10 @@ bool Procedural::isReady() const {
|
|||
}
|
||||
|
||||
void Procedural::prepare(gpu::Batch& batch,
|
||||
const glm::vec3& position,
|
||||
const glm::vec3& size,
|
||||
const glm::quat& orientation,
|
||||
const glm::vec4& color) {
|
||||
const glm::vec3& position,
|
||||
const glm::vec3& size,
|
||||
const glm::quat& orientation,
|
||||
const glm::vec4& color) {
|
||||
_entityDimensions = size;
|
||||
_entityPosition = position;
|
||||
_entityOrientation = glm::mat3_cast(orientation);
|
||||
|
@ -308,6 +308,7 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Procedural::setupUniforms(bool transparent) {
|
||||
_uniforms.clear();
|
||||
auto customUniformCount = _data.uniforms.keys().size();
|
||||
|
@ -323,53 +324,50 @@ void Procedural::setupUniforms(bool transparent) {
|
|||
} else if (value.isArray()) {
|
||||
auto valueArray = value.toArray();
|
||||
switch (valueArray.size()) {
|
||||
case 0:
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
float v = valueArray[0].toDouble();
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform1f(slot, v); });
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
float v = valueArray[0].toDouble();
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform1f(slot, v); });
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
glm::vec2 v{ valueArray[0].toDouble(), valueArray[1].toDouble() };
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform2f(slot, v.x, v.y); });
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
glm::vec2 v{ valueArray[0].toDouble(), valueArray[1].toDouble() };
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform2f(slot, v.x, v.y); });
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
glm::vec3 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform3f(slot, v.x, v.y, v.z); });
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
glm::vec3 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform3f(slot, v.x, v.y, v.z); });
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
case 4: {
|
||||
glm::vec4 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
valueArray[3].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform4f(slot, v.x, v.y, v.z, v.w); });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case 4: {
|
||||
glm::vec4 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
valueArray[3].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform4f(slot, v.x, v.y, v.z, v.w); });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
// Time and position
|
||||
{
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
_standardInputs.posAndTime = vec4(_entityPosition, time);
|
||||
}
|
||||
_standardInputs.position = vec4(_entityPosition, 1.0f);
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
_standardInputs.time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
|
||||
// Date
|
||||
{
|
||||
|
@ -385,7 +383,8 @@ void Procedural::setupUniforms(bool transparent) {
|
|||
_standardInputs.date.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
|
||||
}
|
||||
|
||||
_standardInputs.scaleAndCount = vec4(_entityDimensions, ++_frameCount);
|
||||
_standardInputs.scale = vec4(_entityDimensions, 1.0f);
|
||||
_standardInputs.frameCount = ++_frameCount;
|
||||
_standardInputs.orientation = mat4(_entityOrientation);
|
||||
|
||||
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
|
||||
|
|
|
@ -73,14 +73,29 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
// DO NOT TOUCH
|
||||
// We have to pack these in a particular way to match the ProceduralCommon.slh
|
||||
// layout.
|
||||
struct StandardInputs {
|
||||
vec4 date;
|
||||
vec4 posAndTime;
|
||||
vec4 scaleAndCount;
|
||||
mat4 orientation;
|
||||
vec4 position;
|
||||
vec4 scale;
|
||||
float time;
|
||||
int frameCount;
|
||||
vec2 _spare1;
|
||||
vec4 resolution[4];
|
||||
mat4 orientation;
|
||||
};
|
||||
|
||||
static_assert(0 == offsetof(StandardInputs, date), "ProceduralOffsets");
|
||||
static_assert(16 == offsetof(StandardInputs, position), "ProceduralOffsets");
|
||||
static_assert(32 == offsetof(StandardInputs, scale), "ProceduralOffsets");
|
||||
static_assert(48 == offsetof(StandardInputs, time), "ProceduralOffsets");
|
||||
static_assert(52 == offsetof(StandardInputs, frameCount), "ProceduralOffsets");
|
||||
static_assert(56 == offsetof(StandardInputs, _spare1), "ProceduralOffsets");
|
||||
static_assert(64 == offsetof(StandardInputs, resolution), "ProceduralOffsets");
|
||||
static_assert(128 == offsetof(StandardInputs, orientation), "ProceduralOffsets");
|
||||
|
||||
// Procedural metadata
|
||||
ProceduralData _data;
|
||||
|
||||
|
|
|
@ -23,42 +23,43 @@ LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
|
|||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
|
||||
|
||||
struct StandardInputs {
|
||||
// DO NOT TOUCH
|
||||
// This block does not follow our normal rules of always using a struct and
|
||||
// always using 16 byte aligned types like vec4 and mat4
|
||||
//
|
||||
// This is because this block must be EXACTLY how it is in order to maintain
|
||||
// comptability with existing procedural shaders that previously relied on these
|
||||
// inputs as uniforms, not members of a UBO
|
||||
|
||||
LAYOUT_STD140(binding=0) uniform standardInputsBuffer {
|
||||
// Offset 0
|
||||
vec4 date;
|
||||
vec4 posAndTime;
|
||||
vec4 scaleAndCount;
|
||||
mat4 orientation;
|
||||
vec4 resolution[4];
|
||||
};
|
||||
|
||||
|
||||
LAYOUT(binding=0) uniform standardInputsBuffer {
|
||||
StandardInputs params;
|
||||
};
|
||||
|
||||
// shader playback time (in seconds)
|
||||
float iGlobalTime = params.posAndTime.w;
|
||||
|
||||
vec4 iDate = params.date;
|
||||
|
||||
int iFrameCount = int(params.scaleAndCount.w);
|
||||
|
||||
// the position of the object being rendered
|
||||
vec3 iWorldPosition = params.posAndTime.xyz;
|
||||
|
||||
// the dimensions of the object being rendered
|
||||
vec3 iWorldScale = params.scaleAndCount.xyz;
|
||||
|
||||
// the orientation of the object being rendered
|
||||
mat3 iWorldOrientation = mat3(params.orientation);
|
||||
|
||||
vec3 iChannelResolution[4] = vec3[4](
|
||||
params.resolution[0].xyz,
|
||||
params.resolution[1].xyz,
|
||||
params.resolution[2].xyz,
|
||||
params.resolution[3].xyz
|
||||
);
|
||||
// Offset 16, acts as vec4 for alignment purposes
|
||||
vec3 worldPosition;
|
||||
// Offset 32, acts as vec4 for alignment purposes
|
||||
vec3 worldScale;
|
||||
// Offset 48
|
||||
float globalTime;
|
||||
// Offset 52
|
||||
int frameCount;
|
||||
// Offset 56
|
||||
vec2 _spare1;
|
||||
// Offset 64, acts as vec4[4] for alignment purposes
|
||||
vec3 channelResolution[4];
|
||||
// Offset 128, acts as vec4[3] for alignment purposes
|
||||
// Also, each individual component is aligned as a vec4
|
||||
mat3 worldOrientation;
|
||||
// Offset 176
|
||||
vec4 _spare2;
|
||||
} standardInputs;
|
||||
|
||||
#define iDate standardInputs.date
|
||||
#define iWorldPosition standardInputs.worldPosition
|
||||
#define iWorldScale standardInputs.worldScale
|
||||
#define iGlobalTime standardInputs.globalTime
|
||||
#define iFrameCount standardInputs.frameCount
|
||||
#define iChannelResolution standardInputs.channelResolution
|
||||
#define iWorldOrientation standardInputs.worldOrientation
|
||||
|
||||
// Unimplemented uniforms
|
||||
// Resolution doesn't make sense in the VR context
|
||||
|
|
Loading…
Reference in a new issue