exposed orientation and eye position to procedural entity shaders

This commit is contained in:
SamGondelman 2016-06-08 18:26:54 -07:00
parent d0e946c907
commit 24e5000aeb
10 changed files with 60 additions and 6 deletions

View file

@ -314,6 +314,8 @@ in vec4 _position;
// TODO add more uniforms
uniform float iGlobalTime; // shader playback time (in seconds)
uniform vec3 iWorldScale; // the dimensions of the object being rendered
uniform mat3 iWorldOrientation; // the orientation of the object being rendered
uniform vec3 iWorldEyePosition; // the world position of the eye
// TODO add support for textures
// TODO document available inputs other than the uniforms

View file

@ -98,7 +98,7 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
}
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
if (_procedural->ready()) {
_procedural->prepare(batch, getPosition(), getDimensions());
_procedural->prepare(batch, getPosition(), getDimensions(), getOrientation(), args->getViewFrustum().getPosition());
auto outColor = _procedural->getColor(color);
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);

View file

@ -114,6 +114,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::gl::GLBackend::do_glUniform3fv),
(&::gpu::gl::GLBackend::do_glUniform4fv),
(&::gpu::gl::GLBackend::do_glUniform4iv),
(&::gpu::gl::GLBackend::do_glUniformMatrix3fv),
(&::gpu::gl::GLBackend::do_glUniformMatrix4fv),
(&::gpu::gl::GLBackend::do_glColor4f),
@ -515,6 +516,22 @@ void GLBackend::do_glUniform4iv(Batch& batch, size_t paramOffset) {
(void)CHECK_GL_ERROR();
}
void GLBackend::do_glUniformMatrix3fv(Batch& batch, size_t paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that
// because these uniform setters are deprecated and we don;t want to create side effect
return;
}
updatePipeline();
glUniformMatrix3fv(
GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int),
batch._params[paramOffset + 2]._uint,
batch._params[paramOffset + 1]._uint,
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
(void)CHECK_GL_ERROR();
}
void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that

View file

@ -136,6 +136,7 @@ public:
virtual void do_glUniform3fv(Batch& batch, size_t paramOffset) final;
virtual void do_glUniform4fv(Batch& batch, size_t paramOffset) final;
virtual void do_glUniform4iv(Batch& batch, size_t paramOffset) final;
virtual void do_glUniformMatrix3fv(Batch& batch, size_t paramOffset) final;
virtual void do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) final;
virtual void do_glColor4f(Batch& batch, size_t paramOffset) final;

View file

@ -567,6 +567,16 @@ void Batch::_glUniform4iv(int32 location, int count, const int32* value) {
_params.push_back(location);
}
void Batch::_glUniformMatrix3fv(int32 location, int count, uint8 transpose, const float* value) {
ADD_COMMAND(glUniformMatrix3fv);
const int MATRIX3_SIZE = 9 * sizeof(float);
_params.push_back(cacheData(count * MATRIX3_SIZE, value));
_params.push_back(transpose);
_params.push_back(count);
_params.push_back(location);
}
void Batch::_glUniformMatrix4fv(int32 location, int count, uint8 transpose, const float* value) {
ADD_COMMAND(glUniformMatrix4fv);

View file

@ -269,6 +269,7 @@ public:
void _glUniform3fv(int location, int count, const float* value);
void _glUniform4fv(int location, int count, const float* value);
void _glUniform4iv(int location, int count, const int* value);
void _glUniformMatrix3fv(int location, int count, unsigned char transpose, const float* value);
void _glUniformMatrix4fv(int location, int count, unsigned char transpose, const float* value);
void _glUniform(int location, int v0) {
@ -291,6 +292,10 @@ public:
_glUniform4f(location, v.x, v.y, v.z, v.w);
}
void _glUniform(int location, const glm::quat& v) {
_glUniformMatrix3fv(location, 1, false, reinterpret_cast< const float* >(&glm::mat3_cast(v)));
}
void _glColor4f(float red, float green, float blue, float alpha);
enum Command {
@ -348,6 +353,7 @@ public:
COMMAND_glUniform3fv,
COMMAND_glUniform4fv,
COMMAND_glUniform4iv,
COMMAND_glUniformMatrix3fv,
COMMAND_glUniformMatrix4fv,
COMMAND_glColor4f,

View file

@ -39,6 +39,8 @@ static const std::string STANDARD_UNIFORM_NAMES[Procedural::NUM_STANDARD_UNIFORM
"iFrameCount",
"iWorldScale",
"iWorldPosition",
"iWorldOrientation",
"iWorldEyePosition",
"iChannelResolution"
};
@ -202,9 +204,11 @@ bool Procedural::ready() {
return true;
}
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size) {
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const glm::vec3& eyePos) {
_entityDimensions = size;
_entityPosition = position;
_entityOrientation = orientation;
_eyePos = eyePos;
if (_shaderUrl.isLocalFile()) {
auto lastModified = (quint64)QFileInfo(_shaderPath).lastModified().toMSecsSinceEpoch();
if (lastModified > _shaderModified) {
@ -404,10 +408,10 @@ void Procedural::setupUniforms() {
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[SCALE]) {
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[ORIENTATION]) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back([=](gpu::Batch& batch) {
batch._glUniform(_standardUniformSlots[SCALE], _entityDimensions);
batch._glUniform(_standardUniformSlots[ORIENTATION], _entityOrientation);
});
}
@ -417,6 +421,14 @@ void Procedural::setupUniforms() {
batch._glUniform(_standardUniformSlots[POSITION], _entityPosition);
});
}
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[EYE_POSITION]) {
// FIXME move into the 'set once' section, since this doesn't change over time
_uniforms.push_back([=](gpu::Batch& batch) {
batch._glUniform(_standardUniformSlots[EYE_POSITION], _eyePos);
});
}
}
void Procedural::setupChannels(bool shouldCreate) {

View file

@ -38,7 +38,7 @@ public:
void parse(const QString& userDataJson);
bool ready();
void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size);
void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const glm::vec3& eyePos);
const gpu::ShaderPointer& getShader() const { return _shader; }
glm::vec4 getColor(const glm::vec4& entityColor);
@ -56,6 +56,8 @@ public:
FRAME_COUNT,
SCALE,
POSITION,
ORIENTATION,
EYE_POSITION,
CHANNEL_RESOLUTION,
NUM_STANDARD_UNIFORMS
};
@ -93,6 +95,8 @@ protected:
// Entity metadata
glm::vec3 _entityDimensions;
glm::vec3 _entityPosition;
glm::quat _entityOrientation;
glm::vec3 _eyePos;
private:
// This should only be called from the render thread, as it shares data with Procedural::prepare

View file

@ -289,6 +289,8 @@ const vec4 iChannelTime = vec4(0.0);
uniform vec4 iDate;
uniform int iFrameCount;
uniform vec3 iWorldPosition;
uniform mat3 iWorldOrientation;
uniform vec3 iWorldEyePosition;
uniform vec3 iChannelResolution[4];
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;

View file

@ -52,7 +52,7 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum,
batch.setModelTransform(Transform()); // only for Mac
auto& procedural = skybox._procedural;
procedural.prepare(batch, glm::vec3(0), glm::vec3(1));
procedural.prepare(batch, glm::vec3(0), glm::vec3(1), glm::quat(1, 0, 0, 0), glm::vec3(0));
auto textureSlot = procedural.getShader()->getTextures().findLocation("cubeMap");
auto bufferSlot = procedural.getShader()->getBuffers().findLocation("skyboxBuffer");
skybox.prepare(batch, textureSlot, bufferSlot);