mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 01:22:25 +02:00
Merge pull request #14034 from samcake/black-bis
Refactor Deformed mesh rendering pipeline for better scalability and performances at runtime
This commit is contained in:
commit
46a50b04ea
116 changed files with 966 additions and 1373 deletions
|
@ -128,7 +128,11 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
QString materialMapString = mapping.value("materialMap").toString();
|
||||
QJsonDocument materialMapDocument = QJsonDocument::fromJson(materialMapString.toUtf8());
|
||||
QJsonObject materialMap = materialMapDocument.object();
|
||||
|
||||
if (!materialMapString.isEmpty()) {
|
||||
if (materialMapDocument.isEmpty() || materialMap.isEmpty()) {
|
||||
qCDebug(modelformat) << "fbx Material Map found but did not produce valid JSON:" << materialMapString;
|
||||
}
|
||||
}
|
||||
for (QHash<QString, FBXMaterial>::iterator it = _fbxMaterials.begin(); it != _fbxMaterials.end(); it++) {
|
||||
FBXMaterial& material = (*it);
|
||||
|
||||
|
|
|
@ -585,7 +585,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
|
||||
FBXMesh& fbxMesh = extractedMesh;
|
||||
graphics::MeshPointer mesh(new graphics::Mesh());
|
||||
bool hasBlendShapes = !fbxMesh.blendshapes.empty();
|
||||
int numVerts = extractedMesh.vertices.size();
|
||||
|
||||
if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) {
|
||||
|
@ -618,7 +617,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
qWarning() << "Unexpected tangents in " << url;
|
||||
}
|
||||
const auto normalsAndTangentsSize = normalsSize + tangentsSize;
|
||||
const int normalsAndTangentsStride = 2 * normalElement.getSize();
|
||||
|
||||
// Color attrib
|
||||
const auto colorElement = FBX_COLOR_ELEMENT;
|
||||
|
@ -761,33 +759,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
bool interleavePositions = true;
|
||||
bool interleaveNormalsTangents = true;
|
||||
|
||||
// TODO: We are using the same vertex format layout for all meshes because this is more efficient
|
||||
// This work is going into rc73 release which is meant to be used for the SPot500 event and we are picking the format
|
||||
// that works best for blendshaped and skinned meshes aka the avatars.
|
||||
// We will improve this technique in a hot fix to 73.
|
||||
hasBlendShapes = true;
|
||||
|
||||
// If has blend shapes allocate and assign buffers for pos and tangents now
|
||||
if (hasBlendShapes) {
|
||||
auto posBuffer = std::make_shared<gpu::Buffer>();
|
||||
posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset);
|
||||
vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize());
|
||||
|
||||
auto normalsAndTangentsBuffer = std::make_shared<gpu::Buffer>();
|
||||
normalsAndTangentsBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset);
|
||||
vertexBufferStream->addBuffer(normalsAndTangentsBuffer, 0, normalsAndTangentsStride);
|
||||
|
||||
// update channels and attribBuffer size accordingly
|
||||
interleavePositions = false;
|
||||
interleaveNormalsTangents = false;
|
||||
|
||||
tangentChannel = 1;
|
||||
attribChannel = 2;
|
||||
|
||||
totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize;
|
||||
}
|
||||
|
||||
// Define the vertex format, compute the offset for each attributes as we append them to the vertex format
|
||||
// Define the vertex format, compute the offset for each attributes as we append them to the vertex format
|
||||
gpu::Offset bufOffset = 0;
|
||||
if (positionsSize) {
|
||||
vertexFormat->setAttribute(gpu::Stream::POSITION, posChannel, positionElement, bufOffset);
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "nvToolsExt.h"
|
||||
#endif
|
||||
|
||||
// Define the GPU_BATCH_DETAILED_TRACING to get detailed tracing of the commands during the batch executions
|
||||
// #define GPU_BATCH_DETAILED_TRACING
|
||||
|
||||
#include <GPUIdent.h>
|
||||
|
||||
#include "GLTexture.h"
|
||||
|
@ -271,6 +274,9 @@ void GLBackend::renderPassDraw(const Batch& batch) {
|
|||
case Batch::COMMAND_drawIndexedInstanced:
|
||||
case Batch::COMMAND_multiDrawIndirect:
|
||||
case Batch::COMMAND_multiDrawIndexedIndirect: {
|
||||
#ifdef GPU_BATCH_DETAILED_TRACING
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "drawcall");
|
||||
#endif
|
||||
// updates for draw calls
|
||||
++_currentDraw;
|
||||
updateInput();
|
||||
|
@ -281,6 +287,94 @@ void GLBackend::renderPassDraw(const Batch& batch) {
|
|||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
#ifdef GPU_BATCH_DETAILED_TRACING
|
||||
//case Batch::COMMAND_setModelTransform:
|
||||
//case Batch::COMMAND_setViewTransform:
|
||||
//case Batch::COMMAND_setProjectionTransform:
|
||||
case Batch::COMMAND_setProjectionJitter:
|
||||
case Batch::COMMAND_setViewportTransform:
|
||||
case Batch::COMMAND_setDepthRangeTransform:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "transform");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_clearFramebuffer:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "clear");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_blit:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "blit");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_setInputFormat:
|
||||
case Batch::COMMAND_setInputBuffer:
|
||||
case Batch::COMMAND_setIndexBuffer:
|
||||
case Batch::COMMAND_setIndirectBuffer: {
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "input");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_setStateBlendFactor:
|
||||
case Batch::COMMAND_setStateScissorRect:
|
||||
case Batch::COMMAND_setPipeline: {
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "pipeline");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_setUniformBuffer:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "ubo");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_setResourceBuffer:
|
||||
case Batch::COMMAND_setResourceTexture:
|
||||
case Batch::COMMAND_setResourceTextureTable:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "resource");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
|
||||
case Batch::COMMAND_setResourceFramebufferSwapChainTexture:
|
||||
case Batch::COMMAND_setFramebuffer:
|
||||
case Batch::COMMAND_setFramebufferSwapChain:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "framebuffer");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_generateTextureMips:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "genMipMaps");
|
||||
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
case Batch::COMMAND_beginQuery:
|
||||
case Batch::COMMAND_endQuery:
|
||||
case Batch::COMMAND_getQuery:
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "query");
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
|
@ -294,6 +388,8 @@ void GLBackend::renderPassDraw(const Batch& batch) {
|
|||
}
|
||||
|
||||
void GLBackend::render(const Batch& batch) {
|
||||
PROFILE_RANGE(render_gpu_gl, batch.getName());
|
||||
|
||||
_transform._skybox = _stereo._skybox = batch.isSkyboxEnabled();
|
||||
// Allow the batch to override the rendering stereo settings
|
||||
// for things like full framebuffer copy operations (deferred lighting passes)
|
||||
|
|
|
@ -20,7 +20,10 @@ namespace gpu {
|
|||
|
||||
~GL41Buffer() {
|
||||
if (_texBuffer) {
|
||||
glDeleteTextures(1, &_texBuffer);
|
||||
auto backend = _backend.lock();
|
||||
if (backend) {
|
||||
backend->releaseTexture(_texBuffer, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,9 +61,9 @@ GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) {
|
|||
|
||||
|
||||
bool GL45Backend::bindResourceBuffer(uint32_t slot, const BufferPointer& buffer) {
|
||||
GLBuffer* object = syncGPUObject((*buffer));
|
||||
if (object) {
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, object->_id);
|
||||
auto bo = getBufferIDUnsynced((*buffer));
|
||||
if (bo) {
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, bo);
|
||||
|
||||
(void)CHECK_GL_ERROR();
|
||||
|
||||
|
|
|
@ -98,6 +98,8 @@ void Batch::clear() {
|
|||
_name = nullptr;
|
||||
_invalidModel = true;
|
||||
_currentModel = Transform();
|
||||
_drawcallUniform = 0;
|
||||
_drawcallUniformReset = 0;
|
||||
_projectionJitter = glm::vec2(0.0f);
|
||||
_enableStereo = true;
|
||||
_enableSkybox = false;
|
||||
|
@ -112,6 +114,13 @@ size_t Batch::cacheData(size_t size, const void* data) {
|
|||
return offset;
|
||||
}
|
||||
|
||||
void Batch::setDrawcallUniform(uint16_t uniform) {
|
||||
_drawcallUniform = uniform;
|
||||
}
|
||||
void Batch::setDrawcallUniformReset(uint16_t uniformReset) {
|
||||
_drawcallUniformReset = uniformReset;
|
||||
}
|
||||
|
||||
void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex) {
|
||||
ADD_COMMAND(draw);
|
||||
|
||||
|
@ -545,7 +554,8 @@ void Batch::captureDrawCallInfoImpl() {
|
|||
}
|
||||
|
||||
auto& drawCallInfos = getDrawCallInfoBuffer();
|
||||
drawCallInfos.emplace_back((uint16)_objects.size() - 1);
|
||||
drawCallInfos.emplace_back((uint16)_objects.size() - 1, _drawcallUniform);
|
||||
_drawcallUniform = _drawcallUniformReset;
|
||||
}
|
||||
|
||||
void Batch::captureDrawCallInfo() {
|
||||
|
@ -679,6 +689,8 @@ void Batch::_glColor4f(float red, float green, float blue, float alpha) {
|
|||
}
|
||||
|
||||
void Batch::finishFrame(BufferUpdates& updates) {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
|
||||
for (auto& mapItem : _namedData) {
|
||||
auto& name = mapItem.first;
|
||||
auto& instance = mapItem.second;
|
||||
|
@ -707,6 +719,7 @@ void Batch::finishFrame(BufferUpdates& updates) {
|
|||
}
|
||||
|
||||
void Batch::flush() {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
for (auto& mapItem : _namedData) {
|
||||
auto& name = mapItem.first;
|
||||
auto& instance = mapItem.second;
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
using Index = uint16_t;
|
||||
|
||||
DrawCallInfo(Index idx) : index(idx) {}
|
||||
DrawCallInfo(Index idx, Index user) : index(idx), unused(user) {}
|
||||
|
||||
Index index { 0 };
|
||||
uint16_t unused { 0 }; // Reserved space for later
|
||||
|
@ -95,6 +96,7 @@ public:
|
|||
~Batch();
|
||||
|
||||
void setName(const char* name);
|
||||
const char* getName() const { return _name; }
|
||||
void clear();
|
||||
|
||||
// Batches may need to override the context level stereo settings
|
||||
|
@ -110,6 +112,14 @@ public:
|
|||
void enableSkybox(bool enable = true);
|
||||
bool isSkyboxEnabled() const;
|
||||
|
||||
// Drawcall Uniform value
|
||||
// One 16bit word uniform value is available during the drawcall
|
||||
// its value must be set before each drawcall
|
||||
void setDrawcallUniform(uint16 uniform);
|
||||
// It is reset to the reset value between each drawcalls
|
||||
// The reset value is 0 by default and can be changed as a batch state with this call
|
||||
void setDrawcallUniformReset(uint16 resetUniform);
|
||||
|
||||
// Drawcalls
|
||||
void draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex = 0);
|
||||
void drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex = 0);
|
||||
|
@ -498,6 +508,9 @@ public:
|
|||
|
||||
NamedBatchDataMap _namedData;
|
||||
|
||||
uint16_t _drawcallUniform{ 0 };
|
||||
uint16_t _drawcallUniformReset{ 0 };
|
||||
|
||||
glm::vec2 _projectionJitter{ 0.0f, 0.0f };
|
||||
bool _enableStereo{ true };
|
||||
bool _enableSkybox { false };
|
||||
|
|
|
@ -84,6 +84,7 @@ void Context::appendFrameBatch(const BatchPointer& batch) {
|
|||
}
|
||||
|
||||
FramePointer Context::endFrame() {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
assert(_frameActive);
|
||||
auto result = _currentFrame;
|
||||
_currentFrame.reset();
|
||||
|
@ -101,10 +102,12 @@ void Context::executeBatch(Batch& batch) const {
|
|||
}
|
||||
|
||||
void Context::recycle() const {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
_backend->recycle();
|
||||
}
|
||||
|
||||
void Context::consumeFrameUpdates(const FramePointer& frame) const {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
frame->preRender();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,14 @@ Frame::~Frame() {
|
|||
}
|
||||
|
||||
void Frame::finish() {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
for (const auto& batch : batches) {
|
||||
batch->finishFrame(bufferUpdates);
|
||||
}
|
||||
}
|
||||
|
||||
void Frame::preRender() {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
for (auto& update : bufferUpdates) {
|
||||
update.apply();
|
||||
}
|
||||
|
|
|
@ -214,6 +214,18 @@ TransformObject getTransformObject() {
|
|||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformModelToWorldAndEyeAndClipPos(cameraTransform, objectTransform, modelPos, worldPos, eyePos, clipPos)@>
|
||||
{ // transformModelToEyeAndClipPos
|
||||
vec4 eyeWAPos;
|
||||
<$transformModelToEyeWorldAlignedPos($cameraTransform$, $objectTransform$, $modelPos$, eyeWAPos)$>
|
||||
<$worldPos$> = vec4(eyeWAPos.xyz + <$cameraTransform$>._viewInverse[3].xyz, 1.0);
|
||||
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * eyeWAPos;
|
||||
<$eyePos$> = vec4((<$cameraTransform$>._view * vec4(eyeWAPos.xyz, 0.0)).xyz, 1.0);
|
||||
|
||||
<$transformStereoClipsSpace($cameraTransform$, $clipPos$)$>
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformModelToEyePos(cameraTransform, objectTransform, modelPos, eyePos)@>
|
||||
{ // transformModelToEyePos
|
||||
vec4 eyeWAPos;
|
||||
|
|
|
@ -20,15 +20,11 @@ using namespace gpu;
|
|||
Material::Material() :
|
||||
_key(0),
|
||||
_schemaBuffer(),
|
||||
_texMapArrayBuffer(),
|
||||
_textureMaps()
|
||||
{
|
||||
// created from nothing: create the Buffer to store the properties
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema));
|
||||
|
||||
TexMapArraySchema TexMapArraySchema;
|
||||
_texMapArrayBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(TexMapArraySchema), (const gpu::Byte*) &TexMapArraySchema));
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
||||
}
|
||||
|
||||
Material::Material(const Material& material) :
|
||||
|
@ -38,12 +34,8 @@ Material::Material(const Material& material) :
|
|||
{
|
||||
// copied: create the Buffer to store the properties, avoid holding a ref to the old Buffer
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema));
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
||||
_schemaBuffer.edit<Schema>() = material._schemaBuffer.get<Schema>();
|
||||
|
||||
TexMapArraySchema texMapArraySchema;
|
||||
_texMapArrayBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(TexMapArraySchema), (const gpu::Byte*) &texMapArraySchema));
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>() = material._texMapArrayBuffer.get<TexMapArraySchema>();
|
||||
}
|
||||
|
||||
Material& Material::operator= (const Material& material) {
|
||||
|
@ -57,13 +49,9 @@ Material& Material::operator= (const Material& material) {
|
|||
|
||||
// copied: create the Buffer to store the properties, avoid holding a ref to the old Buffer
|
||||
Schema schema;
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema));
|
||||
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
|
||||
_schemaBuffer.edit<Schema>() = material._schemaBuffer.get<Schema>();
|
||||
|
||||
TexMapArraySchema texMapArraySchema;
|
||||
_texMapArrayBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(TexMapArraySchema), (const gpu::Byte*) &texMapArraySchema));
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>() = material._texMapArrayBuffer.get<TexMapArraySchema>();
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
@ -137,17 +125,17 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur
|
|||
resetOpacityMap();
|
||||
|
||||
// update the texcoord0 with albedo
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[0] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
_schemaBuffer.edit<Schema>()._texcoordTransforms[0] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
}
|
||||
|
||||
if (channel == MaterialKey::OCCLUSION_MAP) {
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
_schemaBuffer.edit<Schema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
}
|
||||
|
||||
if (channel == MaterialKey::LIGHTMAP_MAP) {
|
||||
// update the texcoord1 with lightmap
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._lightmapParams = (textureMap ? glm::vec4(textureMap->getLightmapOffsetScale(), 0.0, 0.0) : glm::vec4(0.0, 1.0, 0.0, 0.0));
|
||||
_schemaBuffer.edit<Schema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||
_schemaBuffer.edit<Schema>()._lightmapParams = (textureMap ? glm::vec4(textureMap->getLightmapOffsetScale(), 0.0, 0.0) : glm::vec4(0.0, 1.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
|
@ -235,6 +223,6 @@ void Material::setTextureTransforms(const Transform& transform) {
|
|||
}
|
||||
}
|
||||
for (int i = 0; i < NUM_TEXCOORD_TRANSFORMS; i++) {
|
||||
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[i] = transform.getMatrix();
|
||||
_schemaBuffer.edit<Schema>()._texcoordTransforms[i] = transform.getMatrix();
|
||||
}
|
||||
}
|
|
@ -268,6 +268,9 @@ public:
|
|||
|
||||
typedef glm::vec3 Color;
|
||||
|
||||
// Texture Map Array Schema
|
||||
static const int NUM_TEXCOORD_TRANSFORMS{ 2 };
|
||||
|
||||
typedef MaterialKey::MapChannel MapChannel;
|
||||
typedef std::map<MapChannel, TextureMapPointer> TextureMaps;
|
||||
typedef std::bitset<MaterialKey::NUM_MAP_CHANNELS> MapFlags;
|
||||
|
@ -323,6 +326,11 @@ public:
|
|||
|
||||
// for alignment beauty, Material size == Mat4x4
|
||||
|
||||
// Texture Coord Transform Array
|
||||
glm::mat4 _texcoordTransforms[NUM_TEXCOORD_TRANSFORMS];
|
||||
|
||||
glm::vec4 _lightmapParams{ 0.0, 1.0, 0.0, 0.0 };
|
||||
|
||||
Schema() {}
|
||||
};
|
||||
|
||||
|
@ -340,17 +348,6 @@ public:
|
|||
// conversion from legacy material properties to PBR equivalent
|
||||
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
|
||||
|
||||
// Texture Map Array Schema
|
||||
static const int NUM_TEXCOORD_TRANSFORMS{ 2 };
|
||||
class TexMapArraySchema {
|
||||
public:
|
||||
glm::mat4 _texcoordTransforms[NUM_TEXCOORD_TRANSFORMS];
|
||||
glm::vec4 _lightmapParams{ 0.0, 1.0, 0.0, 0.0 };
|
||||
TexMapArraySchema() {}
|
||||
};
|
||||
|
||||
const UniformBufferView& getTexMapArrayBuffer() const { return _texMapArrayBuffer; }
|
||||
|
||||
int getTextureCount() const { calculateMaterialInfo(); return _textureCount; }
|
||||
size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; }
|
||||
bool hasTextureInfo() const { return _hasCalculatedTextureInfo; }
|
||||
|
@ -370,7 +367,6 @@ protected:
|
|||
private:
|
||||
mutable MaterialKey _key;
|
||||
mutable UniformBufferView _schemaBuffer;
|
||||
mutable UniformBufferView _texMapArrayBuffer;
|
||||
mutable gpu::TextureTablePointer _textureTable{ std::make_shared<gpu::TextureTable>() };
|
||||
|
||||
TextureMaps _textureMaps;
|
||||
|
|
|
@ -13,6 +13,31 @@
|
|||
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
struct TexMapArray {
|
||||
mat4 _texcoordTransforms0;
|
||||
mat4 _texcoordTransforms1;
|
||||
vec4 _lightmapParams;
|
||||
};
|
||||
|
||||
<@func declareMaterialTexMapArrayBuffer()@>
|
||||
|
||||
<@func evalTexMapArrayTexcoord0(texMapArray, inTexcoord0, outTexcoord0)@>
|
||||
{
|
||||
<$outTexcoord0$> = (<$texMapArray$>._texcoordTransforms0 * vec4(<$inTexcoord0$>.st, 0.0, 1.0)).st;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalTexMapArrayTexcoord1(texMapArray, inTexcoord1, outTexcoord1)@>
|
||||
{
|
||||
<$outTexcoord1$> = (<$texMapArray$>._texcoordTransforms1 * vec4(<$inTexcoord1$>.st, 0.0, 1.0)).st;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
// The material values (at least the material key) must be precisely bitwise accurate
|
||||
// to what is provided by the uniform buffer, or the material key has the wrong bits
|
||||
|
||||
|
@ -25,11 +50,15 @@ struct Material {
|
|||
|
||||
layout(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
|
||||
Material _mat;
|
||||
TexMapArray _texMapArray;
|
||||
};
|
||||
|
||||
Material getMaterial() {
|
||||
return _mat;
|
||||
}
|
||||
TexMapArray getTexMapArray() {
|
||||
return _texMapArray;
|
||||
}
|
||||
|
||||
vec3 getMaterialEmissive(Material m) { return m._emissiveOpacity.rgb; }
|
||||
float getMaterialOpacity(Material m) { return m._emissiveOpacity.a; }
|
||||
|
|
|
@ -11,41 +11,7 @@
|
|||
<@if not MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
<@def MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
<@func declareMaterialTexMapArrayBuffer()@>
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
struct TexMapArray {
|
||||
// mat4 _texcoordTransforms[MAX_TEXCOORDS];
|
||||
mat4 _texcoordTransforms0;
|
||||
mat4 _texcoordTransforms1;
|
||||
vec4 _lightmapParams;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_TEXMAPARRAY) uniform texMapArrayBuffer {
|
||||
TexMapArray _texMapArray;
|
||||
};
|
||||
|
||||
TexMapArray getTexMapArray() {
|
||||
return _texMapArray;
|
||||
}
|
||||
|
||||
<@func evalTexMapArrayTexcoord0(texMapArray, inTexcoord0, outTexcoord0)@>
|
||||
{
|
||||
<$outTexcoord0$> = (<$texMapArray$>._texcoordTransforms0 * vec4(<$inTexcoord0$>.st, 0.0, 1.0)).st;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalTexMapArrayTexcoord1(texMapArray, inTexcoord1, outTexcoord1)@>
|
||||
{
|
||||
<$outTexcoord1$> = (<$texMapArray$>._texcoordTransforms1 * vec4(<$inTexcoord1$>.st, 0.0, 1.0)).st;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
||||
|
|
82
libraries/render-utils/src/Blendshape.slh
Normal file
82
libraries/render-utils/src/Blendshape.slh
Normal file
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 9/13/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@if not BLENDSHAPE_SLH@>
|
||||
<@def BLENDSHAPE_SLH@>
|
||||
|
||||
<@func declareBlendshape(USE_NORMAL, USE_TANGENT)@>
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
|
||||
uvec4 getPackedBlendshapeOffset(int i) {
|
||||
return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer blendshapeOffsetsBuffer {
|
||||
uvec4 _packedBlendshapeOffsets[];
|
||||
};
|
||||
uvec4 getPackedBlendshapeOffset(int i) {
|
||||
return _packedBlendshapeOffsets[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
struct BlendshapeOffset {
|
||||
vec3 position;
|
||||
<@if USE_NORMAL@>
|
||||
vec3 normal;
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
vec3 tangent;
|
||||
<@endif@>
|
||||
};
|
||||
|
||||
vec3 unpackSnorm3x10_1x2(int packedValue) {
|
||||
const float oneOver511 = 1.0 / 511.0;
|
||||
return vec3(
|
||||
clamp( float( bitfieldExtract(packedValue, 0, 10)) * oneOver511, -1.0, 1.0),
|
||||
clamp( float( bitfieldExtract(packedValue, 10, 10)) * oneOver511, -1.0, 1.0),
|
||||
clamp( float( bitfieldExtract(packedValue, 20, 10)) * oneOver511, -1.0, 1.0)
|
||||
);
|
||||
}
|
||||
|
||||
BlendshapeOffset unpackBlendshapeOffset(uvec4 packedValue) {
|
||||
BlendshapeOffset unpacked;
|
||||
unpacked.position = unpackSnorm3x10_1x2(int(packedValue.y)).xyz * uintBitsToFloat(packedValue.x);
|
||||
<@if USE_NORMAL@>
|
||||
unpacked.normal = unpackSnorm3x10_1x2(int(packedValue.z)).xyz;
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
unpacked.tangent = unpackSnorm3x10_1x2(int(packedValue.w)).xyz;
|
||||
<@endif@>
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
BlendshapeOffset getBlendshapeOffset(int i) {
|
||||
return unpackBlendshapeOffset(getPackedBlendshapeOffset(i));
|
||||
}
|
||||
|
||||
void evalBlendshape(int i, vec4 inPosition, out vec4 position
|
||||
<@if USE_NORMAL@>
|
||||
, vec3 inNormal, out vec3 normal
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
, vec3 inTangent, out vec3 tangent
|
||||
<@endif@>
|
||||
) {
|
||||
BlendshapeOffset blendshapeOffset = getBlendshapeOffset(i);
|
||||
position = inPosition + vec4(blendshapeOffset.position, 0.0);
|
||||
<@if USE_NORMAL@>
|
||||
normal = normalize(inNormal + blendshapeOffset.normal.xyz);
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
tangent = normalize(inTangent + blendshapeOffset.tangent.xyz);
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@endif@> // if not BLENDSHAPE_SLH
|
|
@ -86,9 +86,8 @@ void CauterizedModel::createRenderItemSet() {
|
|||
// Create the render payloads
|
||||
int numParts = (int)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||
if (!fbxGeometry.meshes[i].blendshapes.empty() && _blendedVertexBuffers.find(i) == _blendedVertexBuffers.end()) {
|
||||
initializeBlendshapes(fbxGeometry.meshes[i], i);
|
||||
}
|
||||
initializeBlendshapes(fbxGeometry.meshes[i], i);
|
||||
|
||||
auto ptr = std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
|
||||
_modelMeshRenderItems << std::static_pointer_cast<ModelMeshPartPayload>(ptr);
|
||||
auto material = getGeometry()->getShapeMaterial(shapeID);
|
||||
|
@ -97,7 +96,7 @@ void CauterizedModel::createRenderItemSet() {
|
|||
shapeID++;
|
||||
}
|
||||
}
|
||||
_blendedVertexBuffersInitialized = true;
|
||||
_blendshapeBuffersInitialized = true;
|
||||
} else {
|
||||
Model::createRenderItemSet();
|
||||
}
|
||||
|
@ -176,7 +175,7 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
|
||||
// post the blender if we're not currently waiting for one to finish
|
||||
auto modelBlender = DependencyManager::get<ModelBlender>();
|
||||
if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
|
||||
if (_blendshapeBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
|
||||
_blendedBlendshapeCoefficients = _blendshapeCoefficients;
|
||||
modelBlender->noteRequiresBlend(getThisPointer());
|
||||
}
|
||||
|
|
|
@ -181,8 +181,8 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
args->_batch = &batch;
|
||||
|
||||
auto maskPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder);
|
||||
auto maskSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned());
|
||||
auto maskSkinnedDQPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned().withDualQuatSkinned());
|
||||
auto maskDeformedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed());
|
||||
auto maskDeformedDQPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed().withDualQuatSkinned());
|
||||
|
||||
// Setup camera, projection and viewport for all items
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
|
@ -190,37 +190,37 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
batch.setProjectionJitter(jitter.x, jitter.y);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
std::vector<ShapeKey> skinnedShapeKeys;
|
||||
std::vector<ShapeKey> skinnedDQShapeKeys;
|
||||
std::vector<ShapeKey> deformedShapeKeys;
|
||||
std::vector<ShapeKey> deformedDQShapeKeys;
|
||||
|
||||
// Iterate through all inShapes and render the unskinned
|
||||
args->_shapePipeline = maskPipeline;
|
||||
batch.setPipeline(maskPipeline->pipeline);
|
||||
for (const auto& items : inShapes) {
|
||||
itemBounds.insert(itemBounds.end(), items.second.begin(), items.second.end());
|
||||
if (items.first.isSkinned() && items.first.isDualQuatSkinned()) {
|
||||
skinnedDQShapeKeys.push_back(items.first);
|
||||
} else if (items.first.isSkinned()) {
|
||||
skinnedShapeKeys.push_back(items.first);
|
||||
if (items.first.isDeformed() && items.first.isDualQuatSkinned()) {
|
||||
deformedDQShapeKeys.push_back(items.first);
|
||||
} else if (items.first.isDeformed()) {
|
||||
deformedShapeKeys.push_back(items.first);
|
||||
} else {
|
||||
renderItems(renderContext, items.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Reiterate to render the skinned
|
||||
if (skinnedShapeKeys.size() > 0) {
|
||||
args->_shapePipeline = maskSkinnedPipeline;
|
||||
batch.setPipeline(maskSkinnedPipeline->pipeline);
|
||||
for (const auto& key : skinnedShapeKeys) {
|
||||
if (deformedShapeKeys.size() > 0) {
|
||||
args->_shapePipeline = maskDeformedPipeline;
|
||||
batch.setPipeline(maskDeformedPipeline->pipeline);
|
||||
for (const auto& key : deformedShapeKeys) {
|
||||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Reiterate to render the DQ skinned
|
||||
if (skinnedDQShapeKeys.size() > 0) {
|
||||
args->_shapePipeline = maskSkinnedDQPipeline;
|
||||
batch.setPipeline(maskSkinnedDQPipeline->pipeline);
|
||||
for (const auto& key : skinnedDQShapeKeys) {
|
||||
if (deformedDQShapeKeys.size() > 0) {
|
||||
args->_shapePipeline = maskDeformedDQPipeline;
|
||||
batch.setPipeline(maskDeformedDQPipeline->pipeline);
|
||||
for (const auto& key : deformedDQShapeKeys) {
|
||||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
}
|
||||
|
@ -565,4 +565,5 @@ const render::Varying DrawHighlightTask::addSelectItemJobs(JobModel& task, const
|
|||
const auto selectedMetasAndOpaques = task.addJob<SelectItems>("OpaqueSelection", selectMetaAndOpaqueInput);
|
||||
const auto selectItemInput = SelectItems::Inputs(transparents, selectedMetasAndOpaques, selectionName).asVarying();
|
||||
return task.addJob<SelectItems>("TransparentSelection", selectItemInput);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
LightingModel::LightingModel() {
|
||||
Parameters parameters;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters, sizeof(Parameters)));
|
||||
}
|
||||
|
||||
void LightingModel::setUnlit(bool enable) {
|
||||
|
@ -159,6 +159,34 @@ void LightingModel::setWireframe(bool enable) {
|
|||
bool LightingModel::isWireframeEnabled() const {
|
||||
return (bool)_parametersBuffer.get<Parameters>().enableWireframe;
|
||||
}
|
||||
|
||||
void LightingModel::setBloom(bool enable) {
|
||||
if (enable != isBloomEnabled()) {
|
||||
_parametersBuffer.edit<Parameters>().enableBloom = (float)enable;
|
||||
}
|
||||
}
|
||||
bool LightingModel::isBloomEnabled() const {
|
||||
return (bool)_parametersBuffer.get<Parameters>().enableBloom;
|
||||
}
|
||||
|
||||
void LightingModel::setSkinning(bool enable) {
|
||||
if (enable != isSkinningEnabled()) {
|
||||
_parametersBuffer.edit<Parameters>().enableSkinning = (float)enable;
|
||||
}
|
||||
}
|
||||
bool LightingModel::isSkinningEnabled() const {
|
||||
return (bool)_parametersBuffer.get<Parameters>().enableSkinning;
|
||||
}
|
||||
|
||||
void LightingModel::setBlendshape(bool enable) {
|
||||
if (enable != isBlendshapeEnabled()) {
|
||||
_parametersBuffer.edit<Parameters>().enableBlendshape = (float)enable;
|
||||
}
|
||||
}
|
||||
bool LightingModel::isBlendshapeEnabled() const {
|
||||
return (bool)_parametersBuffer.get<Parameters>().enableBlendshape;
|
||||
}
|
||||
|
||||
MakeLightingModel::MakeLightingModel() {
|
||||
_lightingModel = std::make_shared<LightingModel>();
|
||||
}
|
||||
|
@ -169,6 +197,7 @@ void MakeLightingModel::configure(const Config& config) {
|
|||
_lightingModel->setLightmap(config.enableLightmap);
|
||||
_lightingModel->setBackground(config.enableBackground);
|
||||
_lightingModel->setHaze(config.enableHaze);
|
||||
_lightingModel->setBloom(config.enableBloom);
|
||||
|
||||
_lightingModel->setObscurance(config.enableObscurance);
|
||||
|
||||
|
@ -186,6 +215,9 @@ void MakeLightingModel::configure(const Config& config) {
|
|||
|
||||
_lightingModel->setShowLightContour(config.showLightContour);
|
||||
_lightingModel->setWireframe(config.enableWireframe);
|
||||
|
||||
_lightingModel->setSkinning(config.enableSkinning);
|
||||
_lightingModel->setBlendshape(config.enableBlendshape);
|
||||
}
|
||||
|
||||
void MakeLightingModel::run(const render::RenderContextPointer& renderContext, LightingModelPointer& lightingModel) {
|
||||
|
@ -194,4 +226,6 @@ void MakeLightingModel::run(const render::RenderContextPointer& renderContext, L
|
|||
|
||||
// make sure the enableTexturing flag of the render ARgs is in sync
|
||||
renderContext->args->_enableTexturing = _lightingModel->isMaterialTexturingEnabled();
|
||||
renderContext->args->_enableBlendshape = _lightingModel->isBlendshapeEnabled();
|
||||
renderContext->args->_enableSkinning = _lightingModel->isSkinningEnabled();
|
||||
}
|
|
@ -38,6 +38,8 @@ public:
|
|||
|
||||
void setHaze(bool enable);
|
||||
bool isHazeEnabled() const;
|
||||
void setBloom(bool enable);
|
||||
bool isBloomEnabled() const;
|
||||
|
||||
void setObscurance(bool enable);
|
||||
bool isObscuranceEnabled() const;
|
||||
|
@ -69,6 +71,10 @@ public:
|
|||
|
||||
void setWireframe(bool enable);
|
||||
bool isWireframeEnabled() const;
|
||||
void setSkinning(bool enable);
|
||||
bool isSkinningEnabled() const;
|
||||
void setBlendshape(bool enable);
|
||||
bool isBlendshapeEnabled() const;
|
||||
|
||||
UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
|
||||
|
||||
|
@ -102,9 +108,9 @@ protected:
|
|||
float enableWireframe { 0.0f }; // false by default
|
||||
|
||||
float enableHaze{ 1.0f };
|
||||
float spare1; // Needed for having the LightingModel class aligned on a 4 scalar boundary for gpu
|
||||
float spare2;
|
||||
float spare3;
|
||||
float enableBloom{ 1.0f };
|
||||
float enableSkinning{ 1.0f };
|
||||
float enableBlendshape{ 1.0f };
|
||||
|
||||
Parameters() {}
|
||||
};
|
||||
|
@ -142,6 +148,10 @@ class MakeLightingModelConfig : public render::Job::Config {
|
|||
Q_PROPERTY(bool enableWireframe MEMBER enableWireframe NOTIFY dirty)
|
||||
Q_PROPERTY(bool showLightContour MEMBER showLightContour NOTIFY dirty)
|
||||
|
||||
Q_PROPERTY(bool enableBloom MEMBER enableBloom NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableSkinning MEMBER enableSkinning NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableBlendshape MEMBER enableBlendshape NOTIFY dirty)
|
||||
|
||||
public:
|
||||
MakeLightingModelConfig() : render::Job::Config() {} // Make Lighting Model is always on
|
||||
|
||||
|
@ -167,6 +177,9 @@ public:
|
|||
|
||||
bool enableWireframe { false }; // false by default
|
||||
bool enableHaze{ true };
|
||||
bool enableBloom{ true };
|
||||
bool enableSkinning{ true };
|
||||
bool enableBlendshape{ true };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
|
|
@ -19,7 +19,7 @@ struct LightingModel {
|
|||
vec4 _ScatteringDiffuseSpecularAlbedo;
|
||||
vec4 _AmbientDirectionalPointSpot;
|
||||
vec4 _ShowContourObscuranceWireframe;
|
||||
vec4 _Haze_spareyzw;
|
||||
vec4 _HazeBloomSkinningBlendshape;
|
||||
};
|
||||
|
||||
// See DeferredShader_BufferSlot in DeferredLightingEffect.cpp
|
||||
|
@ -78,7 +78,16 @@ float isWireframeEnabled() {
|
|||
}
|
||||
|
||||
float isHazeEnabled() {
|
||||
return lightingModel._Haze_spareyzw.x;
|
||||
return lightingModel._HazeBloomSkinningBlendshape.x;
|
||||
}
|
||||
float isBloomEnabled() {
|
||||
return lightingModel._HazeBloomSkinningBlendshape.y;
|
||||
}
|
||||
float isSkinningEnabled() {
|
||||
return lightingModel._HazeBloomSkinningBlendshape.z;
|
||||
}
|
||||
float isBlendshapeEnabled() {
|
||||
return lightingModel._HazeBloomSkinningBlendshape.w;
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
|
106
libraries/render-utils/src/MeshDeformer.slh
Normal file
106
libraries/render-utils/src/MeshDeformer.slh
Normal file
|
@ -0,0 +1,106 @@
|
|||
<!
|
||||
// MeshDeformer.slh
|
||||
// Created by Sam Gateau on 9/20/2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
!>
|
||||
<@if not MESH_DEFORMER_SLH@>
|
||||
<@def MESH_DEFORMER_SLH@>
|
||||
// MeshDeformer.slh
|
||||
|
||||
<@func declareMeshDeformer(USE_NORMAL, USE_TANGENT, USE_SKINNING, USE_DUAL_QUATERNION, USE_BLENDSHAPE)@>
|
||||
|
||||
<@if USE_SKINNING@>
|
||||
<@include Skinning.slh@>
|
||||
<$declareSkinning($USE_DUAL_QUATERNION$, $USE_NORMAL$, $USE_TANGENT$)$>
|
||||
<@endif@>
|
||||
|
||||
<@if USE_BLENDSHAPE@>
|
||||
<@include Blendshape.slh@>
|
||||
<$declareBlendshape($USE_NORMAL$, $USE_TANGENT$)$>
|
||||
<@endif@>
|
||||
|
||||
void evalMeshDeformer(vec4 inPosition, out vec4 outPosition
|
||||
<@if USE_NORMAL@>
|
||||
, vec3 inNormal, out vec3 outNormal
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
, vec3 inTangent, out vec3 outTangent
|
||||
<@endif@>
|
||||
<@if USE_SKINNING@>
|
||||
, bool isSkinningEnabled, ivec4 skinClusterIndex, vec4 skinClusterWeight
|
||||
<@endif@>
|
||||
<@if USE_BLENDSHAPE@>
|
||||
, bool isBlendshapeEnabled, int vertexIndex
|
||||
<@endif@>
|
||||
) {
|
||||
|
||||
vec4 _deformedPosition = inPosition;
|
||||
<@if USE_NORMAL@>
|
||||
vec3 _deformedNormal = inNormal;
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
vec3 _deformedTangent = inTangent;
|
||||
<@endif@>
|
||||
|
||||
<@if USE_BLENDSHAPE@>
|
||||
if (isBlendshapeEnabled) {
|
||||
evalBlendshape(vertexIndex, inPosition, _deformedPosition
|
||||
<@if USE_NORMAL@>
|
||||
, inNormal, _deformedNormal
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
, inTangent, _deformedTangent
|
||||
<@endif@>
|
||||
);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if USE_SKINNING@>
|
||||
if (isSkinningEnabled) {
|
||||
|
||||
evalSkinning(inSkinClusterIndex, inSkinClusterWeight, _deformedPosition, _deformedPosition
|
||||
<@if USE_NORMAL@>
|
||||
, _deformedNormal, _deformedNormal
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
, _deformedTangent, _deformedTangent
|
||||
<@endif@>
|
||||
);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
outPosition = _deformedPosition;
|
||||
<@if USE_NORMAL@>
|
||||
outNormal = _deformedNormal;
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
outTangent = _deformedTangent;
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareMeshDeformerActivation(USE_SKINNING, USE_BLENDSHAPE)@>
|
||||
|
||||
const BITFIELD MESH_DEFORMER_BLENDSHAPE_BIT = 0x00000001;
|
||||
const BITFIELD MESH_DEFORMER_SKINNING_BIT = 0x00000002;
|
||||
|
||||
<@if USE_BLENDSHAPE@>
|
||||
bool meshDeformer_doBlendshape(int meshKey) {
|
||||
return ((meshKey & MESH_DEFORMER_BLENDSHAPE_BIT) != 0);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if USE_SKINNING@>
|
||||
bool meshDeformer_doSkinning(int meshKey) {
|
||||
return ((meshKey & MESH_DEFORMER_SKINNING_BIT) != 0);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
<@endif@> // if not MESH_DEFORMER_SLH
|
|
@ -208,9 +208,6 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
|||
|
||||
bool useDualQuaternionSkinning = model->getUseDualQuaternionSkinning();
|
||||
|
||||
if (!model->getFBXGeometry().meshes[meshIndex].blendshapes.isEmpty()) {
|
||||
_blendedVertexBuffer = model->_blendedVertexBuffers[meshIndex];
|
||||
}
|
||||
auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex);
|
||||
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
||||
|
||||
|
@ -240,6 +237,23 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
|||
updateTransformForSkinnedMesh(renderTransform, transform);
|
||||
|
||||
initCache(model);
|
||||
|
||||
if (_isBlendShaped) {
|
||||
auto buffer = model->_blendshapeBuffers.find(meshIndex);
|
||||
if (buffer != model->_blendshapeBuffers.end()) {
|
||||
_blendshapeBuffer = buffer->second;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// On mac AMD, we specifically need to have a _blendshapeBuffer bound when using a deformed mesh pipeline
|
||||
// it cannot be null otherwise we crash in the drawcall using a deformed pipeline with a skinned only (not blendshaped) mesh
|
||||
if ((_isBlendShaped || _isSkinned) && !_blendshapeBuffer) {
|
||||
glm::vec4 data;
|
||||
_blendshapeBuffer = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), reinterpret_cast<const gpu::Byte*>(&data));
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::initCache(const ModelPointer& model) {
|
||||
|
@ -348,10 +362,10 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe
|
|||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
bool isUnlit = drawMaterialKey.isUnlit();
|
||||
|
||||
bool isSkinned = _isSkinned;
|
||||
bool isDeformed = _isBlendShaped || _isSkinned;
|
||||
|
||||
if (isWireframe) {
|
||||
isTranslucent = hasTangents = hasLightmap = isSkinned = false;
|
||||
isTranslucent = hasTangents = hasLightmap = false;
|
||||
}
|
||||
|
||||
ShapeKey::Builder builder;
|
||||
|
@ -369,13 +383,13 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe
|
|||
if (isUnlit) {
|
||||
builder.withUnlit();
|
||||
}
|
||||
if (isSkinned) {
|
||||
builder.withSkinned();
|
||||
if (isDeformed) {
|
||||
builder.withDeformed();
|
||||
}
|
||||
if (isWireframe) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
if (isSkinned && useDualQuaternionSkinning) {
|
||||
if (isDeformed && useDualQuaternionSkinning) {
|
||||
builder.withDualQuatSkinned();
|
||||
}
|
||||
|
||||
|
@ -389,14 +403,10 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
|||
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) {
|
||||
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
||||
if (_isBlendShaped && _blendedVertexBuffer) {
|
||||
batch.setInputBuffer(0, _blendedVertexBuffer, 0, sizeof(glm::vec3));
|
||||
// Stride is 2*sizeof(glm::vec3) because normal and tangents are interleaved
|
||||
batch.setInputBuffer(1, _blendedVertexBuffer, _drawMesh->getNumVertices() * sizeof(glm::vec3), 2 * sizeof(NormalType));
|
||||
batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2));
|
||||
} else {
|
||||
batch.setInputStream(0, _drawMesh->getVertexStream());
|
||||
if (_blendshapeBuffer) {
|
||||
batch.setResourceBuffer(0, _blendshapeBuffer);
|
||||
}
|
||||
batch.setInputStream(0, _drawMesh->getVertexStream());
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, RenderArgs::RenderMode renderMode) const {
|
||||
|
@ -420,6 +430,12 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
//Bind the index buffer and vertex buffer and Blend shapes if needed
|
||||
bindMesh(batch);
|
||||
|
||||
// IF deformed pass the mesh key
|
||||
auto drawcallInfo = (uint16_t) (((_isBlendShaped && args->_enableBlendshape) << 0) | ((_isSkinned && args->_enableSkinning) << 1));
|
||||
if (drawcallInfo) {
|
||||
batch.setDrawcallUniform(drawcallInfo);
|
||||
}
|
||||
|
||||
// apply material properties
|
||||
if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
|
||||
RenderPipelines::bindMaterial(!_drawMaterials.empty() ? _drawMaterials.top().material : DEFAULT_MATERIAL, batch, args->_enableTexturing);
|
||||
|
|
|
@ -26,6 +26,7 @@ class Model;
|
|||
|
||||
class MeshPartPayload {
|
||||
public:
|
||||
|
||||
MeshPartPayload() {}
|
||||
MeshPartPayload(const std::shared_ptr<const graphics::Mesh>& mesh, int partIndex, graphics::MaterialPointer material);
|
||||
virtual ~MeshPartPayload() {}
|
||||
|
@ -136,7 +137,7 @@ public:
|
|||
private:
|
||||
void initCache(const ModelPointer& model);
|
||||
|
||||
gpu::BufferPointer _blendedVertexBuffer;
|
||||
gpu::BufferPointer _blendshapeBuffer;
|
||||
render::ShapeKey _shapeKey { render::ShapeKey::Builder::invalid() };
|
||||
};
|
||||
|
||||
|
|
|
@ -308,12 +308,10 @@ bool Model::updateGeometry() {
|
|||
state.clusterDualQuaternions.resize(mesh.clusters.size());
|
||||
state.clusterMatrices.resize(mesh.clusters.size());
|
||||
_meshStates.push_back(state);
|
||||
if (!mesh.blendshapes.empty() && _blendedVertexBuffers.find(i) == _blendedVertexBuffers.end()) {
|
||||
initializeBlendshapes(mesh, i);
|
||||
}
|
||||
initializeBlendshapes(mesh, i);
|
||||
i++;
|
||||
}
|
||||
_blendedVertexBuffersInitialized = true;
|
||||
_blendshapeBuffersInitialized = true;
|
||||
needFullUpdate = true;
|
||||
emit rigReady();
|
||||
}
|
||||
|
@ -1034,9 +1032,9 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti
|
|||
_modelMeshMaterialNames.clear();
|
||||
_modelMeshRenderItemShapes.clear();
|
||||
|
||||
_blendedVertexBuffers.clear();
|
||||
_normalsAndTangents.clear();
|
||||
_blendedVertexBuffersInitialized = false;
|
||||
_blendshapeBuffers.clear();
|
||||
_blendshapeOffsets.clear();
|
||||
_blendshapeBuffersInitialized = false;
|
||||
|
||||
_addedToScene = false;
|
||||
|
||||
|
@ -1439,7 +1437,7 @@ void Model::updateClusterMatrices() {
|
|||
|
||||
// post the blender if we're not currently waiting for one to finish
|
||||
auto modelBlender = DependencyManager::get<ModelBlender>();
|
||||
if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
|
||||
if (_blendshapeBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
|
||||
_blendedBlendshapeCoefficients = _blendshapeCoefficients;
|
||||
modelBlender->noteRequiresBlend(getThisPointer());
|
||||
}
|
||||
|
@ -1447,9 +1445,9 @@ void Model::updateClusterMatrices() {
|
|||
|
||||
void Model::deleteGeometry() {
|
||||
_deleteGeometryCounter++;
|
||||
_blendedVertexBuffers.clear();
|
||||
_normalsAndTangents.clear();
|
||||
_blendedVertexBuffersInitialized = false;
|
||||
_blendshapeBuffers.clear();
|
||||
_blendshapeOffsets.clear();
|
||||
_blendshapeBuffersInitialized = false;
|
||||
_meshStates.clear();
|
||||
_rig.destroyAnimGraph();
|
||||
_blendedBlendshapeCoefficients.clear();
|
||||
|
@ -1519,9 +1517,7 @@ void Model::createRenderItemSet() {
|
|||
// Create the render payloads
|
||||
int numParts = (int)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||
if (!fbxGeometry.meshes[i].blendshapes.empty() && _blendedVertexBuffers.find(i) == _blendedVertexBuffers.end()) {
|
||||
initializeBlendshapes(fbxGeometry.meshes[i], i);
|
||||
}
|
||||
initializeBlendshapes(fbxGeometry.meshes[i], i);
|
||||
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
|
||||
auto material = getGeometry()->getShapeMaterial(shapeID);
|
||||
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
|
||||
|
@ -1529,7 +1525,7 @@ void Model::createRenderItemSet() {
|
|||
shapeID++;
|
||||
}
|
||||
}
|
||||
_blendedVertexBuffersInitialized = true;
|
||||
_blendshapeBuffersInitialized = true;
|
||||
}
|
||||
|
||||
bool Model::isRenderable() const {
|
||||
|
@ -1615,6 +1611,25 @@ public:
|
|||
};
|
||||
|
||||
|
||||
using packBlendshapeOffsetTo = void(glm::uvec4& packed, const BlendshapeOffsetUnpacked& unpacked);
|
||||
|
||||
void packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10(glm::uvec4& packed, const BlendshapeOffsetUnpacked& unpacked) {
|
||||
float len = glm::compMax(glm::abs(unpacked.positionOffset));
|
||||
glm::vec3 normalizedPos(unpacked.positionOffset);
|
||||
if (len > 1.0f) {
|
||||
normalizedPos /= len;
|
||||
} else {
|
||||
len = 1.0f;
|
||||
}
|
||||
|
||||
packed = glm::uvec4(
|
||||
glm::floatBitsToUint(len),
|
||||
glm::packSnorm3x10_1x2(glm::vec4(normalizedPos, 0.0f)),
|
||||
glm::packSnorm3x10_1x2(glm::vec4(unpacked.normalOffset, 0.0f)),
|
||||
glm::packSnorm3x10_1x2(glm::vec4(unpacked.tangentOffset, 0.0f))
|
||||
);
|
||||
}
|
||||
|
||||
class Blender : public QRunnable {
|
||||
public:
|
||||
|
||||
|
@ -1638,26 +1653,23 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe
|
|||
}
|
||||
|
||||
void Blender::run() {
|
||||
QVector<glm::vec3> vertices;
|
||||
QVector<NormalType> normalsAndTangents;
|
||||
QVector<BlendshapeOffset> blendshapeOffsets;
|
||||
if (_model && _model->isLoaded()) {
|
||||
DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
|
||||
int offset = 0;
|
||||
int normalsAndTangentsOffset = 0;
|
||||
auto meshes = _model->getFBXGeometry().meshes;
|
||||
int meshIndex = 0;
|
||||
foreach(const FBXMesh& mesh, meshes) {
|
||||
auto modelMeshNormalsAndTangents = _model->_normalsAndTangents.find(meshIndex++);
|
||||
if (mesh.blendshapes.isEmpty() || modelMeshNormalsAndTangents == _model->_normalsAndTangents.end()) {
|
||||
auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++);
|
||||
if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vertices += mesh.vertices;
|
||||
normalsAndTangents += modelMeshNormalsAndTangents->second;
|
||||
glm::vec3* meshVertices = vertices.data() + offset;
|
||||
NormalType* meshNormalsAndTangents = normalsAndTangents.data() + normalsAndTangentsOffset;
|
||||
offset += mesh.vertices.size();
|
||||
normalsAndTangentsOffset += modelMeshNormalsAndTangents->second.size();
|
||||
blendshapeOffsets += modelMeshBlendshapeOffsets->second;
|
||||
BlendshapeOffset* meshBlendshapeOffsets = blendshapeOffsets.data() + offset;
|
||||
offset += modelMeshBlendshapeOffsets->second.size();
|
||||
std::vector<BlendshapeOffsetUnpacked> unpackedBlendshapeOffsets(modelMeshBlendshapeOffsets->second.size());
|
||||
|
||||
const float NORMAL_COEFFICIENT_SCALE = 0.01f;
|
||||
for (int i = 0, n = qMin(_blendshapeCoefficients.size(), mesh.blendshapes.size()); i < n; i++) {
|
||||
float vertexCoefficient = _blendshapeCoefficients.at(i);
|
||||
|
@ -1665,40 +1677,41 @@ void Blender::run() {
|
|||
if (vertexCoefficient < EPSILON) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE;
|
||||
const FBXBlendshape& blendshape = mesh.blendshapes.at(i);
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, blendshape.indices.size()), [&](const tbb::blocked_range<int>& range) {
|
||||
for (auto j = range.begin(); j < range.end(); j++) {
|
||||
int index = blendshape.indices.at(j);
|
||||
meshVertices[index] += blendshape.vertices.at(j) * vertexCoefficient;
|
||||
|
||||
glm::vec3 normal = mesh.normals.at(index) + blendshape.normals.at(j) * normalCoefficient;
|
||||
glm::vec3 tangent;
|
||||
if (index < mesh.tangents.size()) {
|
||||
tangent = mesh.tangents.at(index);
|
||||
if ((int)j < blendshape.tangents.size()) {
|
||||
tangent += blendshape.tangents.at(j) * normalCoefficient;
|
||||
}
|
||||
auto& currentBlendshapeOffset = unpackedBlendshapeOffsets[index];
|
||||
currentBlendshapeOffset.positionOffset += blendshape.vertices.at(j) * vertexCoefficient;
|
||||
|
||||
currentBlendshapeOffset.normalOffset += blendshape.normals.at(j) * normalCoefficient;
|
||||
if (j < blendshape.tangents.size()) {
|
||||
currentBlendshapeOffset.tangentOffset += blendshape.tangents.at(j) * normalCoefficient;
|
||||
}
|
||||
#if FBX_PACK_NORMALS
|
||||
glm::uint32 finalNormal;
|
||||
glm::uint32 finalTangent;
|
||||
buffer_helpers::packNormalAndTangent(normal, tangent, finalNormal, finalTangent);
|
||||
#else
|
||||
const auto& finalNormal = normal;
|
||||
const auto& finalTangent = tangent;
|
||||
#endif
|
||||
meshNormalsAndTangents[2 * index] = finalNormal;
|
||||
meshNormalsAndTangents[2 * index + 1] = finalTangent;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Blendshape offsets are generrated, now let's pack it on its way to gpu
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, (int) unpackedBlendshapeOffsets.size()), [&](const tbb::blocked_range<int>& range) {
|
||||
auto unpacked = unpackedBlendshapeOffsets.data() + range.begin();
|
||||
auto packed = meshBlendshapeOffsets + range.begin();
|
||||
for (auto j = range.begin(); j < range.end(); j++) {
|
||||
packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked));
|
||||
|
||||
unpacked++;
|
||||
packed++;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// post the result to the ModelBlender, which will dispatch to the model if still alive
|
||||
QMetaObject::invokeMethod(DependencyManager::get<ModelBlender>().data(), "setBlendedVertices",
|
||||
Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector<glm::vec3>, vertices),
|
||||
Q_ARG(QVector<NormalType>, normalsAndTangents));
|
||||
Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector<BlendshapeOffset>, blendshapeOffsets));
|
||||
}
|
||||
|
||||
bool Model::maybeStartBlender() {
|
||||
|
@ -1709,67 +1722,45 @@ bool Model::maybeStartBlender() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Model::setBlendedVertices(int blendNumber, const QVector<glm::vec3>& vertices, const QVector<NormalType>& normalsAndTangents) {
|
||||
if (!isLoaded() || blendNumber < _appliedBlendNumber || !_blendedVertexBuffersInitialized) {
|
||||
void Model::setBlendedVertices(int blendNumber, const QVector<BlendshapeOffset>& blendshapeOffsets) {
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
if (!isLoaded() || blendNumber < _appliedBlendNumber || !_blendshapeBuffersInitialized) {
|
||||
return;
|
||||
}
|
||||
_appliedBlendNumber = blendNumber;
|
||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||
int index = 0;
|
||||
int normalAndTangentIndex = 0;
|
||||
for (int i = 0; i < fbxGeometry.meshes.size(); i++) {
|
||||
const FBXMesh& mesh = fbxGeometry.meshes.at(i);
|
||||
auto meshNormalsAndTangents = _normalsAndTangents.find(i);
|
||||
const auto& buffer = _blendedVertexBuffers.find(i);
|
||||
if (mesh.blendshapes.isEmpty() || meshNormalsAndTangents == _normalsAndTangents.end() || buffer == _blendedVertexBuffers.end()) {
|
||||
auto meshBlendshapeOffsets = _blendshapeOffsets.find(i);
|
||||
const auto& buffer = _blendshapeBuffers.find(i);
|
||||
if (mesh.blendshapes.isEmpty() || meshBlendshapeOffsets == _blendshapeOffsets.end() || buffer == _blendshapeBuffers.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto vertexCount = mesh.vertices.size();
|
||||
const auto verticesSize = vertexCount * sizeof(glm::vec3);
|
||||
buffer->second->resize(mesh.vertices.size() * sizeof(glm::vec3) + meshNormalsAndTangents->second.size() * sizeof(NormalType));
|
||||
buffer->second->setSubData(0, verticesSize, (gpu::Byte*) vertices.constData() + index * sizeof(glm::vec3));
|
||||
buffer->second->setSubData(verticesSize, meshNormalsAndTangents->second.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data() + normalAndTangentIndex * sizeof(NormalType));
|
||||
const auto blendshapeOffsetSize = meshBlendshapeOffsets->second.size() * sizeof(BlendshapeOffset);
|
||||
buffer->second->setSubData(0, blendshapeOffsetSize, (gpu::Byte*) blendshapeOffsets.constData() + index * sizeof(BlendshapeOffset));
|
||||
|
||||
index += vertexCount;
|
||||
normalAndTangentIndex += meshNormalsAndTangents->second.size();
|
||||
index += meshBlendshapeOffsets->second.size();
|
||||
}
|
||||
}
|
||||
|
||||
void Model::initializeBlendshapes(const FBXMesh& mesh, int index) {
|
||||
_blendedVertexBuffers[index] = std::make_shared<gpu::Buffer>();
|
||||
QVector<NormalType> normalsAndTangents;
|
||||
normalsAndTangents.resize(2 * mesh.normals.size());
|
||||
|
||||
// Interleave normals and tangents
|
||||
// Parallel version for performance
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, mesh.normals.size()), [&](const tbb::blocked_range<int>& range) {
|
||||
auto normalsRange = std::make_pair(mesh.normals.begin() + range.begin(), mesh.normals.begin() + range.end());
|
||||
auto tangentsRange = std::make_pair(mesh.tangents.begin() + range.begin(), mesh.tangents.begin() + range.end());
|
||||
auto normalsAndTangentsIt = normalsAndTangents.begin() + 2 * range.begin();
|
||||
|
||||
for (auto normalIt = normalsRange.first, tangentIt = tangentsRange.first;
|
||||
normalIt != normalsRange.second;
|
||||
++normalIt, ++tangentIt) {
|
||||
#if FBX_PACK_NORMALS
|
||||
glm::uint32 finalNormal;
|
||||
glm::uint32 finalTangent;
|
||||
buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent);
|
||||
#else
|
||||
const auto& finalNormal = *normalIt;
|
||||
const auto& finalTangent = *tangentIt;
|
||||
#endif
|
||||
*normalsAndTangentsIt = finalNormal;
|
||||
++normalsAndTangentsIt;
|
||||
*normalsAndTangentsIt = finalTangent;
|
||||
++normalsAndTangentsIt;
|
||||
if (mesh.blendshapes.empty()) {
|
||||
// mesh doesn't have blendshape, did we allocate one though ?
|
||||
if (_blendshapeBuffers.find(index) != _blendshapeBuffers.end()) {
|
||||
qWarning() << "Mesh does not have Blendshape yet a blendshapeOffset buffer is allocated ?";
|
||||
}
|
||||
});
|
||||
const auto verticesSize = mesh.vertices.size() * sizeof(glm::vec3);
|
||||
_blendedVertexBuffers[index]->resize(mesh.vertices.size() * sizeof(glm::vec3) + normalsAndTangents.size() * sizeof(NormalType));
|
||||
_blendedVertexBuffers[index]->setSubData(0, verticesSize, (const gpu::Byte*) mesh.vertices.constData());
|
||||
_blendedVertexBuffers[index]->setSubData(verticesSize, normalsAndTangents.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data());
|
||||
_normalsAndTangents[index] = normalsAndTangents;
|
||||
return;
|
||||
}
|
||||
// Mesh has blendshape, let s allocate the local buffer if not done yet
|
||||
if (_blendshapeBuffers.find(index) == _blendshapeBuffers.end()) {
|
||||
QVector<BlendshapeOffset> blendshapeOffset;
|
||||
blendshapeOffset.fill(BlendshapeOffset(), mesh.vertices.size());
|
||||
const auto blendshapeOffsetsSize = blendshapeOffset.size() * sizeof(BlendshapeOffset);
|
||||
_blendshapeBuffers[index] = std::make_shared<gpu::Buffer>(blendshapeOffsetsSize, (const gpu::Byte*) blendshapeOffset.constData(), blendshapeOffsetsSize);
|
||||
_blendshapeOffsets[index] = blendshapeOffset;
|
||||
}
|
||||
}
|
||||
|
||||
ModelBlender::ModelBlender() :
|
||||
|
@ -1800,9 +1791,9 @@ void ModelBlender::noteRequiresBlend(ModelPointer model) {
|
|||
}
|
||||
}
|
||||
|
||||
void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, QVector<glm::vec3> vertices, QVector<NormalType> normalsAndTangents) {
|
||||
void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, QVector<BlendshapeOffset> blendshapeOffsets) {
|
||||
if (model) {
|
||||
model->setBlendedVertices(blendNumber, vertices, normalsAndTangents);
|
||||
model->setBlendedVertices(blendNumber, blendshapeOffsets);
|
||||
}
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
|
|
|
@ -75,6 +75,18 @@ struct SortedTriangleSet {
|
|||
int subMeshIndex;
|
||||
};
|
||||
|
||||
struct BlendshapeOffsetPacked {
|
||||
glm::uvec4 packedPosNorTan;
|
||||
};
|
||||
|
||||
struct BlendshapeOffsetUnpacked {
|
||||
glm::vec3 positionOffset;
|
||||
glm::vec3 normalOffset;
|
||||
glm::vec3 tangentOffset;
|
||||
};
|
||||
|
||||
using BlendshapeOffset = BlendshapeOffsetPacked;
|
||||
|
||||
/// A generic 3D model displaying geometry loaded from a URL.
|
||||
class Model : public QObject, public std::enable_shared_from_this<Model>, public scriptable::ModelProvider {
|
||||
Q_OBJECT
|
||||
|
@ -144,7 +156,7 @@ public:
|
|||
bool maybeStartBlender();
|
||||
|
||||
/// Sets blended vertices computed in a separate thread.
|
||||
void setBlendedVertices(int blendNumber, const QVector<glm::vec3>& vertices, const QVector<NormalType>& normalsAndTangents);
|
||||
void setBlendedVertices(int blendNumber, const QVector<BlendshapeOffset>& blendshapeOffsets);
|
||||
|
||||
bool isLoaded() const { return (bool)_renderGeometry && _renderGeometry->isGeometryLoaded(); }
|
||||
bool isAddedToScene() const { return _addedToScene; }
|
||||
|
@ -344,7 +356,7 @@ public:
|
|||
void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName);
|
||||
void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName);
|
||||
|
||||
std::unordered_map<int, QVector<NormalType>> _normalsAndTangents;
|
||||
std::unordered_map<int, QVector<BlendshapeOffset>> _blendshapeOffsets;
|
||||
|
||||
public slots:
|
||||
void loadURLFinished(bool success);
|
||||
|
@ -424,8 +436,8 @@ protected:
|
|||
|
||||
QUrl _url;
|
||||
|
||||
std::unordered_map<int, gpu::BufferPointer> _blendedVertexBuffers;
|
||||
bool _blendedVertexBuffersInitialized { false };
|
||||
std::unordered_map<int, gpu::BufferPointer> _blendshapeBuffers;
|
||||
bool _blendshapeBuffersInitialized{ false };
|
||||
|
||||
QVector<QVector<QSharedPointer<Texture>>> _dilatedTextures;
|
||||
|
||||
|
@ -506,6 +518,7 @@ private:
|
|||
|
||||
Q_DECLARE_METATYPE(ModelPointer)
|
||||
Q_DECLARE_METATYPE(Geometry::WeakPointer)
|
||||
Q_DECLARE_METATYPE(BlendshapeOffset)
|
||||
|
||||
/// Handle management of pending models that need blending
|
||||
class ModelBlender : public QObject, public Dependency {
|
||||
|
@ -520,7 +533,7 @@ public:
|
|||
bool shouldComputeBlendshapes() { return _computeBlendshapes; }
|
||||
|
||||
public slots:
|
||||
void setBlendedVertices(ModelPointer model, int blendNumber, QVector<glm::vec3> vertices, QVector<NormalType> normalsAndTangents);
|
||||
void setBlendedVertices(ModelPointer model, int blendNumber, QVector<BlendshapeOffset> blendshapeOffsets);
|
||||
void setComputeBlendshapes(bool computeBlendshapes) { _computeBlendshapes = computeBlendshapes; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -146,86 +146,86 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
|
||||
// matrix palette skinned
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned(),
|
||||
skin_model, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed(),
|
||||
deformed_model, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents(),
|
||||
skin_model_normal_map, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withTangents(),
|
||||
deformed_model_normal_map, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withFade(),
|
||||
skin_model_fade, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withFade(),
|
||||
deformed_model_fade, batchSetter, itemSetter);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents().withFade(),
|
||||
skin_model_normal_map_fade, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withTangents().withFade(),
|
||||
deformed_model_normal_map_fade, batchSetter, itemSetter);
|
||||
// matrix palette skinned and translucent
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent(),
|
||||
skin_model_translucent, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withTranslucent(),
|
||||
deformed_model_translucent, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(),
|
||||
skin_model_normal_map_translucent, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(),
|
||||
deformed_model_normal_map_translucent, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(),
|
||||
skin_model_translucent_fade, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withTranslucent().withFade(),
|
||||
deformed_model_translucent_fade, batchSetter, itemSetter);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withFade(),
|
||||
skin_model_normal_map_translucent_fade, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withFade(),
|
||||
deformed_model_normal_map_translucent_fade, batchSetter, itemSetter);
|
||||
|
||||
// dual quaternion skinned
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned(),
|
||||
skin_model_dq, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(),
|
||||
deformed_model_dq, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTangents(),
|
||||
skin_model_normal_map_dq, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withTangents(),
|
||||
deformed_model_normal_map_dq, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withFade(),
|
||||
skin_model_fade_dq, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withFade(),
|
||||
deformed_model_fade_dq, batchSetter, itemSetter);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTangents().withFade(),
|
||||
skin_model_normal_map_fade_dq, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withTangents().withFade(),
|
||||
deformed_model_normal_map_fade_dq, batchSetter, itemSetter);
|
||||
// dual quaternion skinned and translucent
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent(),
|
||||
skin_model_translucent_dq, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withTranslucent(),
|
||||
deformed_model_translucent_dq, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent().withTangents(),
|
||||
skin_model_normal_map_translucent_dq, nullptr, nullptr);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withTranslucent().withTangents(),
|
||||
deformed_model_normal_map_translucent_dq, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent().withFade(),
|
||||
skin_model_translucent_fade_dq, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withTranslucent().withFade(),
|
||||
deformed_model_translucent_fade_dq, batchSetter, itemSetter);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent().withTangents().withFade(),
|
||||
skin_model_normal_map_translucent_fade_dq, batchSetter, itemSetter);
|
||||
Key::Builder().withMaterial().withDeformed().withDualQuatSkinned().withTranslucent().withTangents().withFade(),
|
||||
deformed_model_normal_map_translucent_fade_dq, batchSetter, itemSetter);
|
||||
|
||||
// Depth-only
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly(),
|
||||
model_shadow, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly(),
|
||||
skin_model_shadow, nullptr, nullptr);
|
||||
Key::Builder().withDeformed().withDepthOnly(),
|
||||
deformed_model_shadow, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly().withFade(),
|
||||
model_shadow_fade, batchSetter, itemSetter);
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly().withFade(),
|
||||
skin_model_shadow_fade, batchSetter, itemSetter);
|
||||
Key::Builder().withDeformed().withDepthOnly().withFade(),
|
||||
deformed_model_shadow_fade, batchSetter, itemSetter);
|
||||
|
||||
// Now repeat for dual quaternion
|
||||
// Depth-only
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDualQuatSkinned().withDepthOnly(),
|
||||
skin_model_shadow_dq, nullptr, nullptr);
|
||||
Key::Builder().withDeformed().withDualQuatSkinned().withDepthOnly(),
|
||||
deformed_model_shadow_dq, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDualQuatSkinned().withDepthOnly().withFade(),
|
||||
skin_model_shadow_fade_dq, batchSetter, itemSetter);
|
||||
Key::Builder().withDeformed().withDualQuatSkinned().withDepthOnly().withFade(),
|
||||
deformed_model_shadow_fade_dq, batchSetter, itemSetter);
|
||||
}
|
||||
|
||||
void initForwardPipelines(ShapePlumber& plumber) {
|
||||
|
@ -256,21 +256,21 @@ void initForwardPipelines(ShapePlumber& plumber) {
|
|||
addPipeline(Key::Builder().withMaterial().withUnlit(), forward_model_unlit);
|
||||
addPipeline(Key::Builder().withMaterial().withTangents(), forward_model_translucent);
|
||||
|
||||
// Skinned Opaques
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned(), forward_skin_model);
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withTangents(), forward_skin_model_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withDualQuatSkinned(), forward_skin_model_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withTangents().withDualQuatSkinned(), forward_skin_model_normal_map_dq);
|
||||
// Deformed Opaques
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed(), forward_deformed_model);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), forward_deformed_model_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), forward_deformed_model_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), forward_deformed_model_normal_map_dq);
|
||||
|
||||
// Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent(), forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), forward_model_normal_map_translucent);
|
||||
|
||||
// Skinned Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withTranslucent(), forward_skin_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(), forward_skin_translucent_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withTranslucent().withDualQuatSkinned(), forward_skin_translucent_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withDualQuatSkinned(), forward_skin_translucent_normal_map_dq);
|
||||
// Deformed Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), forward_deformed_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), forward_deformed_translucent_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), forward_deformed_translucent_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), forward_deformed_translucent_normal_map_dq);
|
||||
|
||||
forceLightBatchSetter = false;
|
||||
}
|
||||
|
@ -366,32 +366,32 @@ void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state) {
|
|||
using namespace shader::render_utils::program;
|
||||
gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(model_shadow);
|
||||
shapePlumber.addPipeline(
|
||||
ShapeKey::Filter::Builder().withoutSkinned().withoutFade(),
|
||||
ShapeKey::Filter::Builder().withoutDeformed().withoutFade(),
|
||||
modelProgram, state);
|
||||
|
||||
gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(skin_model_shadow);
|
||||
gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(deformed_model_shadow);
|
||||
shapePlumber.addPipeline(
|
||||
ShapeKey::Filter::Builder().withSkinned().withoutDualQuatSkinned().withoutFade(),
|
||||
ShapeKey::Filter::Builder().withDeformed().withoutDualQuatSkinned().withoutFade(),
|
||||
skinProgram, state);
|
||||
|
||||
gpu::ShaderPointer modelFadeProgram = gpu::Shader::createProgram(model_shadow_fade);
|
||||
shapePlumber.addPipeline(
|
||||
ShapeKey::Filter::Builder().withoutSkinned().withFade(),
|
||||
ShapeKey::Filter::Builder().withoutDeformed().withFade(),
|
||||
modelFadeProgram, state);
|
||||
|
||||
gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(skin_model_shadow_fade);
|
||||
gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(deformed_model_shadow_fade);
|
||||
shapePlumber.addPipeline(
|
||||
ShapeKey::Filter::Builder().withSkinned().withoutDualQuatSkinned().withFade(),
|
||||
ShapeKey::Filter::Builder().withDeformed().withoutDualQuatSkinned().withFade(),
|
||||
skinFadeProgram, state);
|
||||
|
||||
gpu::ShaderPointer skinModelShadowDualQuatProgram = gpu::Shader::createProgram(skin_model_shadow_dq);
|
||||
gpu::ShaderPointer skinModelShadowDualQuatProgram = gpu::Shader::createProgram(deformed_model_shadow_dq);
|
||||
shapePlumber.addPipeline(
|
||||
ShapeKey::Filter::Builder().withSkinned().withDualQuatSkinned().withoutFade(),
|
||||
ShapeKey::Filter::Builder().withDeformed().withDualQuatSkinned().withoutFade(),
|
||||
skinModelShadowDualQuatProgram, state);
|
||||
|
||||
gpu::ShaderPointer skinModelShadowFadeDualQuatProgram = gpu::Shader::createProgram(skin_model_shadow_fade_dq);
|
||||
gpu::ShaderPointer skinModelShadowFadeDualQuatProgram = gpu::Shader::createProgram(deformed_model_shadow_fade_dq);
|
||||
shapePlumber.addPipeline(
|
||||
ShapeKey::Filter::Builder().withSkinned().withDualQuatSkinned().withFade(),
|
||||
ShapeKey::Filter::Builder().withDeformed().withDualQuatSkinned().withFade(),
|
||||
skinModelShadowFadeDualQuatProgram, state);
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,6 @@ void RenderPipelines::bindMaterial(const graphics::MaterialPointer& material, gp
|
|||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
||||
batch.setUniformBuffer(gr::Buffer::Material, material->getSchemaBuffer());
|
||||
batch.setUniformBuffer(gr::Buffer::TexMapArray, material->getTexMapArrayBuffer());
|
||||
|
||||
const auto& materialKey = material->getKey();
|
||||
const auto& textureMaps = material->getTextureMaps();
|
||||
|
|
|
@ -249,22 +249,22 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
batch.setViewTransform(viewMat, false);
|
||||
|
||||
auto shadowPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder);
|
||||
auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned());
|
||||
auto shadowSkinnedDQPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned().withDualQuatSkinned());
|
||||
auto shadowDeformedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed());
|
||||
auto shadowDeformedDQPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withDeformed().withDualQuatSkinned());
|
||||
|
||||
std::vector<ShapeKey> skinnedShapeKeys{};
|
||||
std::vector<ShapeKey> skinnedDQShapeKeys{};
|
||||
std::vector<ShapeKey> deformedShapeKeys{};
|
||||
std::vector<ShapeKey> deformedDQShapeKeys{};
|
||||
std::vector<ShapeKey> ownPipelineShapeKeys{};
|
||||
|
||||
// Iterate through all inShapes and render the unskinned
|
||||
args->_shapePipeline = shadowPipeline;
|
||||
batch.setPipeline(shadowPipeline->pipeline);
|
||||
for (auto items : inShapes) {
|
||||
if (items.first.isSkinned()) {
|
||||
if (items.first.isDeformed()) {
|
||||
if (items.first.isDualQuatSkinned()) {
|
||||
skinnedDQShapeKeys.push_back(items.first);
|
||||
deformedDQShapeKeys.push_back(items.first);
|
||||
} else {
|
||||
skinnedShapeKeys.push_back(items.first);
|
||||
deformedShapeKeys.push_back(items.first);
|
||||
}
|
||||
} else if (!items.first.hasOwnPipeline()) {
|
||||
renderItems(renderContext, items.second);
|
||||
|
@ -274,16 +274,16 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
|
|||
}
|
||||
|
||||
// Reiterate to render the skinned
|
||||
args->_shapePipeline = shadowSkinnedPipeline;
|
||||
batch.setPipeline(shadowSkinnedPipeline->pipeline);
|
||||
for (const auto& key : skinnedShapeKeys) {
|
||||
args->_shapePipeline = shadowDeformedPipeline;
|
||||
batch.setPipeline(shadowDeformedPipeline->pipeline);
|
||||
for (const auto& key : deformedShapeKeys) {
|
||||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
|
||||
// Reiterate to render the DQ skinned
|
||||
args->_shapePipeline = shadowSkinnedDQPipeline;
|
||||
batch.setPipeline(shadowSkinnedDQPipeline->pipeline);
|
||||
for (const auto& key : skinnedDQShapeKeys) {
|
||||
args->_shapePipeline = shadowDeformedDQPipeline;
|
||||
batch.setPipeline(shadowDeformedDQPipeline->pipeline);
|
||||
for (const auto& key : deformedDQShapeKeys) {
|
||||
renderItems(renderContext, inShapes.at(key));
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
<@func declareSkinning(USE_DUAL_QUATERNION_SKINNING, USE_NORMAL, USE_TANGENT)@>
|
||||
|
||||
const int MAX_CLUSTERS = 128;
|
||||
const int INDICES_PER_VERTEX = 4;
|
||||
|
||||
<@func declareUseDualQuaternionSkinning(USE_DUAL_QUATERNION_SKINNING)@>
|
||||
|
||||
layout(std140, binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
|
||||
mat4 clusterMatrices[MAX_CLUSTERS];
|
||||
};
|
||||
|
@ -55,7 +55,14 @@ mat4 dualQuatToMat4(vec4 real, vec4 dual) {
|
|||
}
|
||||
|
||||
// dual quaternion linear blending
|
||||
void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) {
|
||||
void evalSkinning(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition
|
||||
<@if USE_NORMAL@>
|
||||
, vec3 inNormal, out vec3 skinnedNormal
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
, vec3 inTangent, out vec3 skinnedTangent
|
||||
<@endif@>
|
||||
) {
|
||||
|
||||
// linearly blend scale and dual quaternion components
|
||||
vec4 sAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
@ -102,166 +109,57 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio
|
|||
sAccum.w = 1.0;
|
||||
skinnedPosition = m * (sAccum * inPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal,
|
||||
out vec4 skinnedPosition, out vec3 skinnedNormal) {
|
||||
|
||||
// linearly blend scale and dual quaternion components
|
||||
vec4 sAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 cAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1];
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||
float clusterWeight = skinClusterWeight[i];
|
||||
|
||||
vec4 scale = clusterMatrix[0];
|
||||
vec4 real = clusterMatrix[1];
|
||||
vec4 dual = clusterMatrix[2];
|
||||
vec4 cauterizedPos = clusterMatrix[3];
|
||||
|
||||
// to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity.
|
||||
float dqClusterWeight = clusterWeight;
|
||||
if (dot(real, polarityReference) < 0.0) {
|
||||
dqClusterWeight = -clusterWeight;
|
||||
}
|
||||
|
||||
sAccum += scale * clusterWeight;
|
||||
rAccum += real * dqClusterWeight;
|
||||
dAccum += dual * dqClusterWeight;
|
||||
cAccum += cauterizedPos * clusterWeight;
|
||||
}
|
||||
|
||||
// normalize dual quaternion
|
||||
float norm = length(rAccum);
|
||||
rAccum /= norm;
|
||||
dAccum /= norm;
|
||||
|
||||
// conversion from dual quaternion to 4x4 matrix.
|
||||
mat4 m = dualQuatToMat4(rAccum, dAccum);
|
||||
|
||||
// sAccum.w indicates the amount of cauterization for this vertex.
|
||||
// 0 indicates no cauterization and 1 indicates full cauterization.
|
||||
// TODO: make this cauterization smoother or implement full dual-quaternion scale support.
|
||||
const float CAUTERIZATION_THRESHOLD = 0.1;
|
||||
if (sAccum.w > CAUTERIZATION_THRESHOLD) {
|
||||
skinnedPosition = cAccum;
|
||||
} else {
|
||||
sAccum.w = 1.0;
|
||||
skinnedPosition = m * (sAccum * inPosition);
|
||||
}
|
||||
|
||||
skinnedNormal = vec3(m * vec4(inNormal, 0));
|
||||
}
|
||||
|
||||
void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent,
|
||||
out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) {
|
||||
|
||||
// linearly blend scale and dual quaternion components
|
||||
vec4 sAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 cAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1];
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||
float clusterWeight = skinClusterWeight[i];
|
||||
|
||||
vec4 scale = clusterMatrix[0];
|
||||
vec4 real = clusterMatrix[1];
|
||||
vec4 dual = clusterMatrix[2];
|
||||
vec4 cauterizedPos = clusterMatrix[3];
|
||||
|
||||
// to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity.
|
||||
float dqClusterWeight = clusterWeight;
|
||||
if (dot(real, polarityReference) < 0.0) {
|
||||
dqClusterWeight = -clusterWeight;
|
||||
}
|
||||
|
||||
sAccum += scale * clusterWeight;
|
||||
rAccum += real * dqClusterWeight;
|
||||
dAccum += dual * dqClusterWeight;
|
||||
cAccum += cauterizedPos * clusterWeight;
|
||||
}
|
||||
|
||||
// normalize dual quaternion
|
||||
float norm = length(rAccum);
|
||||
rAccum /= norm;
|
||||
dAccum /= norm;
|
||||
|
||||
// conversion from dual quaternion to 4x4 matrix.
|
||||
mat4 m = dualQuatToMat4(rAccum, dAccum);
|
||||
|
||||
// sAccum.w indicates the amount of cauterization for this vertex.
|
||||
// 0 indicates no cauterization and 1 indicates full cauterization.
|
||||
// TODO: make this cauterization smoother or implement full dual-quaternion scale support.
|
||||
const float CAUTERIZATION_THRESHOLD = 0.1;
|
||||
if (sAccum.w > CAUTERIZATION_THRESHOLD) {
|
||||
skinnedPosition = cAccum;
|
||||
} else {
|
||||
sAccum.w = 1.0;
|
||||
skinnedPosition = m * (sAccum * inPosition);
|
||||
}
|
||||
|
||||
<@if USE_NORMAL@>
|
||||
skinnedNormal = vec3(m * vec4(inNormal, 0));
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
skinnedTangent = vec3(m * vec4(inTangent, 0));
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
<@else@> // USE_DUAL_QUATERNION_SKINNING
|
||||
<@else@> // NOT USE_DUAL_QUATERNION_SKINNING
|
||||
|
||||
void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) {
|
||||
vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||
float clusterWeight = skinClusterWeight[i];
|
||||
newPosition += clusterMatrix * inPosition * clusterWeight;
|
||||
}
|
||||
|
||||
skinnedPosition = newPosition;
|
||||
}
|
||||
|
||||
void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal,
|
||||
out vec4 skinnedPosition, out vec3 skinnedNormal) {
|
||||
vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 newNormal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||
float clusterWeight = skinClusterWeight[i];
|
||||
newPosition += clusterMatrix * inPosition * clusterWeight;
|
||||
newNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight;
|
||||
}
|
||||
|
||||
skinnedPosition = newPosition;
|
||||
skinnedNormal = newNormal.xyz;
|
||||
}
|
||||
|
||||
void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent,
|
||||
out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) {
|
||||
// LiNEAR BLENDING
|
||||
void evalSkinning(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition
|
||||
<@if USE_NORMAL@>
|
||||
, vec3 inNormal, out vec3 skinnedNormal
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
, vec3 inTangent, out vec3 skinnedTangent
|
||||
<@endif@>
|
||||
) {
|
||||
vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
<@if USE_NORMAL@>
|
||||
vec4 newNormal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
vec4 newTangent = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
<@endif@>
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||
float clusterWeight = skinClusterWeight[i];
|
||||
newPosition += clusterMatrix * inPosition * clusterWeight;
|
||||
<@if USE_NORMAL@>
|
||||
newNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight;
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
newTangent += clusterMatrix * vec4(inTangent.xyz, 0.0) * clusterWeight;
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
skinnedPosition = newPosition;
|
||||
<@if USE_NORMAL@>
|
||||
skinnedNormal = newNormal.xyz;
|
||||
<@endif@>
|
||||
<@if USE_TANGENT@>
|
||||
skinnedTangent = newTangent.xyz;
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
<@endif@> // if USE_DUAL_QUATERNION_SKINNING
|
||||
|
||||
<@endfunc@> // func declareUseDualQuaternionSkinning(USE_DUAL_QUATERNION_SKINNING)
|
||||
<@endfunc@> // func declareSkinning()
|
||||
|
||||
<@endif@> // if not SKINNING_SLH
|
||||
|
|
|
@ -78,7 +78,7 @@ void SoftAttachmentModel::updateClusterMatrices() {
|
|||
|
||||
// post the blender if we're not currently waiting for one to finish
|
||||
auto modelBlender = DependencyManager::get<ModelBlender>();
|
||||
if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
|
||||
if (_blendshapeBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
|
||||
_blendedBlendshapeCoefficients = _blendshapeCoefficients;
|
||||
modelBlender->noteRequiresBlend(getThisPointer());
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// skin_model_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -17,25 +15,30 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Skinning.slh@>
|
||||
<$declareUseDualQuaternionSkinning()$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include MeshDeformer.slh@>
|
||||
<$declareMeshDeformer(1, _SCRIBE_NULL, 1, _SCRIBE_NULL, 1)$>
|
||||
<$declareMeshDeformerActivation(1, 1)$>
|
||||
|
||||
<@include LightingModel.slh@>
|
||||
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 interpolatedNormal = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
|
||||
vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 deformedNormal = vec3(0.0, 0.0, 0.0);
|
||||
evalMeshDeformer(inPosition, deformedPosition, inNormal.xyz, deformedNormal,
|
||||
meshDeformer_doSkinning(_drawCallInfo.y), inSkinClusterIndex, inSkinClusterWeight,
|
||||
meshDeformer_doBlendshape(_drawCallInfo.y), gl_VertexID);
|
||||
|
||||
// pass along the color
|
||||
_color.rgb = color_sRGBToLinear(inColor.rgb);
|
||||
|
@ -43,12 +46,11 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, position, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, position, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, interpolatedNormal.xyz, _normalWS.xyz)$>
|
||||
<$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$>
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// skin_model_fade_dq.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -17,25 +15,28 @@
|
|||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include Skinning.slh@>
|
||||
<$declareUseDualQuaternionSkinning(1)$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include MeshDeformer.slh@>
|
||||
<$declareMeshDeformer(1, _SCRIBE_NULL, 1, 1, 1)$>
|
||||
<$declareMeshDeformerActivation(1, 1)$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 interpolatedNormal = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
|
||||
vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 deformedNormal = vec3(0.0, 0.0, 0.0);
|
||||
evalMeshDeformer(inPosition, deformedPosition, inNormal.xyz, deformedNormal,
|
||||
meshDeformer_doSkinning(_drawCallInfo.y), inSkinClusterIndex, inSkinClusterWeight,
|
||||
meshDeformer_doBlendshape(_drawCallInfo.y), gl_VertexID);
|
||||
|
||||
// pass along the color
|
||||
_color.rgb = color_sRGBToLinear(inColor.rgb);
|
||||
|
@ -43,12 +44,11 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, position, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, position, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, interpolatedNormal.xyz, _normalWS.xyz)$>
|
||||
<$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$>
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_map_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 04/24/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -15,34 +13,44 @@
|
|||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include MeshDeformer.slh@>
|
||||
<$declareMeshDeformer(1, 1, 1, _SCRIBE_NULL, 1)$>
|
||||
<$declareMeshDeformerActivation(1, 1)$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 deformedNormal = vec3(0.0, 0.0, 0.0);
|
||||
vec3 deformedTangent = vec3(0.0, 0.0, 0.0);
|
||||
evalMeshDeformer(inPosition, deformedPosition, inNormal.xyz, deformedNormal, inTangent.xyz, deformedTangent,
|
||||
meshDeformer_doSkinning(_drawCallInfo.y), inSkinClusterIndex, inSkinClusterWeight,
|
||||
meshDeformer_doBlendshape(_drawCallInfo.y), gl_VertexID);
|
||||
|
||||
// pass along the color
|
||||
_color.rgb = color_sRGBToLinear(inColor.rgb);
|
||||
_color.a = inColor.a;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
<$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$>
|
||||
<$transformModelToWorldDir(cam, obj, deformedTangent, _tangentWS.xyz)$>
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_translucent_normal_map.vert
|
||||
// vertex shader
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Olivier Prat on 23/01/18.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -14,33 +13,45 @@
|
|||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include MeshDeformer.slh@>
|
||||
<$declareMeshDeformer(1, 1, 1, 1, 1)$>
|
||||
<$declareMeshDeformerActivation(1, 1)$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec3 deformedNormal = vec3(0.0, 0.0, 0.0);
|
||||
vec3 deformedTangent = vec3(0.0, 0.0, 0.0);
|
||||
evalMeshDeformer(inPosition, deformedPosition, inNormal.xyz, deformedNormal, inTangent.xyz, deformedTangent,
|
||||
meshDeformer_doSkinning(_drawCallInfo.y), inSkinClusterIndex, inSkinClusterWeight,
|
||||
meshDeformer_doBlendshape(_drawCallInfo.y), gl_VertexID);
|
||||
|
||||
// pass along the color
|
||||
_color.rgb = color_sRGBToLinear(inColor.rgb);
|
||||
_color.a = inColor.a;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
<$transformModelToWorldAndEyeAndClipPos(cam, obj, deformedPosition, _positionWS, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, deformedNormal, _normalWS.xyz)$>
|
||||
<$transformModelToWorldDir(cam, obj, deformedTangent, _tangentWS.xyz)$>
|
||||
}
|
37
libraries/render-utils/src/deformed_model_shadow.slv
Normal file
37
libraries/render-utils/src/deformed_model_shadow.slv
Normal file
|
@ -0,0 +1,37 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include MeshDeformer.slh@>
|
||||
<$declareMeshDeformer(_SCRIBE_NULL, _SCRIBE_NULL, 1, _SCRIBE_NULL, 1)$>
|
||||
<$declareMeshDeformerActivation(1, 1)$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
evalMeshDeformer(inPosition, deformedPosition,
|
||||
meshDeformer_doSkinning(_drawCallInfo.y), inSkinClusterIndex, inSkinClusterWeight,
|
||||
meshDeformer_doBlendshape(_drawCallInfo.y), gl_VertexID);
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, deformedPosition, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, deformedPosition, _positionWS)$>
|
||||
}
|
||||
|
36
libraries/render-utils/src/deformed_model_shadow_dq.slv
Normal file
36
libraries/render-utils/src/deformed_model_shadow_dq.slv
Normal file
|
@ -0,0 +1,36 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include MeshDeformer.slh@>
|
||||
<$declareMeshDeformer(_SCRIBE_NULL, _SCRIBE_NULL, 1, 1, 1)$>
|
||||
<$declareMeshDeformerActivation(1, 1)$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec4 deformedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
evalMeshDeformer(inPosition, deformedPosition,
|
||||
meshDeformer_doSkinning(_drawCallInfo.y), inSkinClusterIndex, inSkinClusterWeight,
|
||||
meshDeformer_doBlendshape(_drawCallInfo.y), gl_VertexID);
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, deformedPosition, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, deformedPosition, _positionWS)$>
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.vert
|
||||
// vertex shader
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Andrzej Kapolka on 10/14/13.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
@ -15,12 +14,14 @@
|
|||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
|
@ -32,11 +33,11 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldAndEyeAndClipPos(cam, obj, inPosition, _positionWS, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 04/24/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
_color.rgb = color_sRGBToLinear(inColor.rgb);
|
||||
_color.a = inColor.w;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 11/21/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color in linear space
|
||||
_color.rgb = color_sRGBToLinear(inColor.xyz);
|
||||
|
||||
// and the texture coordinates
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color in linear space
|
||||
_color.rgb = color_sRGBToLinear(inColor.xyz);
|
||||
_color.a = 1.0;
|
||||
|
||||
// and the texture coordinates
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_map.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 11/21/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color in linear space
|
||||
_color.rgb = color_sRGBToLinear(inColor.xyz);
|
||||
_color.a = 1.0;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_lightmap_normal_map_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
// pass along the color in linear space
|
||||
_color.rgb = color_sRGBToLinear(inColor.xyz);
|
||||
_color.a = 1.0;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_map.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 10/14/13.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
@ -22,7 +20,7 @@
|
|||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
|
@ -36,12 +34,12 @@ void main(void) {
|
|||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldAndEyeAndClipPos(cam, obj, inPosition, _positionWS, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// <$_SCRIBE_FILENAME$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 3/24/14.
|
||||
// Created by Hifi Engine Team.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
@ -18,9 +16,14 @@
|
|||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_shadow_fade.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/045/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_translucent.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 15/01/18.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include graphics/MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||
|
||||
void main(void) {
|
||||
_color.rgb = color_sRGBToLinear(inColor.rgb);
|
||||
_color.a = inColor.a;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord01.xy)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord01.zw)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model
|
||||
FRAGMENT model
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_dq
|
||||
FRAGMENT model
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model
|
||||
FRAGMENT model_fade
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_dq
|
||||
FRAGMENT model_fade
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_normal_map
|
||||
FRAGMENT model_normal_map
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_normal_map_dq
|
||||
FRAGMENT model_normal_map
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_normal_map
|
||||
FRAGMENT model_normal_map_fade
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_normal_map_dq
|
||||
FRAGMENT model_normal_map_fade
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_normal_map_fade
|
||||
VERTEX deformed_model_normal_map
|
||||
FRAGMENT model_translucent_normal_map
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_normal_map_fade_dq
|
||||
VERTEX deformed_model_normal_map_dq
|
||||
FRAGMENT model_translucent_normal_map
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_normal_map_fade
|
||||
VERTEX deformed_model_normal_map
|
||||
FRAGMENT model_translucent_normal_map_fade
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_normal_map_fade_dq
|
||||
VERTEX deformed_model_normal_map_dq
|
||||
FRAGMENT model_translucent_normal_map_fade
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_shadow
|
||||
FRAGMENT model_shadow
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_shadow_dq
|
||||
FRAGMENT model_shadow
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_shadow
|
||||
FRAGMENT model_shadow_fade
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_shadow_dq
|
||||
FRAGMENT model_shadow_fade
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_fade
|
||||
VERTEX deformed_model
|
||||
FRAGMENT model_translucent
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_fade_dq
|
||||
VERTEX deformed_model_dq
|
||||
FRAGMENT model_translucent
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_fade
|
||||
VERTEX deformed_model
|
||||
FRAGMENT model_translucent_fade
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_fade_dq
|
||||
VERTEX deformed_model_dq
|
||||
FRAGMENT model_translucent_fade
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model
|
||||
VERTEX deformed_model
|
||||
FRAGMENT forward_model
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_dq
|
||||
FRAGMENT forward_model
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_normal_map
|
||||
VERTEX deformed_model_normal_map
|
||||
FRAGMENT forward_model_normal_map
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_normal_map_dq
|
||||
FRAGMENT forward_model_normal_map
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model
|
||||
VERTEX deformed_model
|
||||
FRAGMENT forward_model_translucent
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_dq
|
||||
VERTEX deformed_model_dq
|
||||
FRAGMENT forward_model_translucent
|
|
@ -1,2 +1,2 @@
|
|||
VERTEX skin_model_normal_map
|
||||
VERTEX deformed_model_normal_map
|
||||
FRAGMENT forward_model_translucent
|
|
@ -0,0 +1,2 @@
|
|||
VERTEX deformed_model_normal_map_dq
|
||||
FRAGMENT forward_model_translucent
|
|
@ -1,2 +0,0 @@
|
|||
VERTEX skin_model_dq
|
||||
FRAGMENT forward_model
|
|
@ -1,2 +0,0 @@
|
|||
VERTEX skin_model_normal_map_dq
|
||||
FRAGMENT forward_model_normal_map
|
|
@ -1,2 +0,0 @@
|
|||
VERTEX skin_model_normal_map_dq
|
||||
FRAGMENT forward_model_translucent
|
|
@ -0,0 +1 @@
|
|||
VERTEX model
|
|
@ -0,0 +1 @@
|
|||
VERTEX model
|
|
@ -0,0 +1 @@
|
|||
VERTEX model
|
|
@ -0,0 +1 @@
|
|||
VERTEX model_normal_map
|
|
@ -0,0 +1 @@
|
|||
VERTEX model_normal_map
|
|
@ -0,0 +1 @@
|
|||
VERTEX model_normal_map
|
|
@ -0,0 +1 @@
|
|||
VERTEX model_shadow
|
|
@ -0,0 +1 @@
|
|||
VERTEX model
|
|
@ -1 +1 @@
|
|||
VERTEX model_fade
|
||||
VERTEX model
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
VERTEX model_normal_map
|
|
@ -1 +1 @@
|
|||
VERTEX model_translucent_normal_map
|
||||
VERTEX model_normal_map
|
||||
|
|
|
@ -1 +1 @@
|
|||
VERTEX model_fade
|
||||
VERTEX model
|
||||
|
|
|
@ -1 +1 @@
|
|||
VERTEX model_fade
|
||||
VERTEX model
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_fade
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_fade
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_normal_map
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_normal_map
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_normal_map_fade
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_normal_map_fade
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_shadow
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_shadow
|
|
@ -1 +0,0 @@
|
|||
FRAGMENT model_shadow
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue