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:
Sam Gateau 2018-10-04 20:41:28 -07:00 committed by GitHub
commit 46a50b04ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
116 changed files with 966 additions and 1373 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -20,7 +20,10 @@ namespace gpu {
~GL41Buffer() {
if (_texBuffer) {
glDeleteTextures(1, &_texBuffer);
auto backend = _backend.lock();
if (backend) {
backend->releaseTexture(_texBuffer, 0);
}
}
}

View file

@ -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();

View file

@ -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;

View file

@ -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 };

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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;

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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; }

View file

@ -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)@>

View 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

View file

@ -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());
}

View file

@ -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);
}
}

View file

@ -12,7 +12,7 @@
LightingModel::LightingModel() {
Parameters parameters;
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) &parameters));
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) &parameters, 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();
}

View file

@ -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();

View file

@ -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@>

View 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

View file

@ -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);

View file

@ -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() };
};

View file

@ -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);

View file

@ -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:

View file

@ -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();

View file

@ -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));
}

View file

@ -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

View file

@ -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());
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View 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)$>
}

View 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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -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)$>
}

View file

@ -0,0 +1,2 @@
VERTEX deformed_model
FRAGMENT model

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_dq
FRAGMENT model

View file

@ -0,0 +1,2 @@
VERTEX deformed_model
FRAGMENT model_fade

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_dq
FRAGMENT model_fade

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_normal_map
FRAGMENT model_normal_map

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_normal_map_dq
FRAGMENT model_normal_map

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_normal_map
FRAGMENT model_normal_map_fade

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_normal_map_dq
FRAGMENT model_normal_map_fade

View file

@ -1,2 +1,2 @@
VERTEX skin_model_normal_map_fade
VERTEX deformed_model_normal_map
FRAGMENT model_translucent_normal_map

View file

@ -1,2 +1,2 @@
VERTEX skin_model_normal_map_fade_dq
VERTEX deformed_model_normal_map_dq
FRAGMENT model_translucent_normal_map

View file

@ -1,2 +1,2 @@
VERTEX skin_model_normal_map_fade
VERTEX deformed_model_normal_map
FRAGMENT model_translucent_normal_map_fade

View file

@ -1,2 +1,2 @@
VERTEX skin_model_normal_map_fade_dq
VERTEX deformed_model_normal_map_dq
FRAGMENT model_translucent_normal_map_fade

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_shadow
FRAGMENT model_shadow

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_shadow_dq
FRAGMENT model_shadow

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_shadow
FRAGMENT model_shadow_fade

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_shadow_dq
FRAGMENT model_shadow_fade

View file

@ -1,2 +1,2 @@
VERTEX skin_model_fade
VERTEX deformed_model
FRAGMENT model_translucent

View file

@ -1,2 +1,2 @@
VERTEX skin_model_fade_dq
VERTEX deformed_model_dq
FRAGMENT model_translucent

View file

@ -1,2 +1,2 @@
VERTEX skin_model_fade
VERTEX deformed_model
FRAGMENT model_translucent_fade

View file

@ -1,2 +1,2 @@
VERTEX skin_model_fade_dq
VERTEX deformed_model_dq
FRAGMENT model_translucent_fade

View file

@ -1,2 +1,2 @@
VERTEX skin_model
VERTEX deformed_model
FRAGMENT forward_model

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_dq
FRAGMENT forward_model

View file

@ -1,2 +1,2 @@
VERTEX skin_model_normal_map
VERTEX deformed_model_normal_map
FRAGMENT forward_model_normal_map

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_normal_map_dq
FRAGMENT forward_model_normal_map

View file

@ -1,2 +1,2 @@
VERTEX skin_model
VERTEX deformed_model
FRAGMENT forward_model_translucent

View file

@ -1,2 +1,2 @@
VERTEX skin_model_dq
VERTEX deformed_model_dq
FRAGMENT forward_model_translucent

View file

@ -1,2 +1,2 @@
VERTEX skin_model_normal_map
VERTEX deformed_model_normal_map
FRAGMENT forward_model_translucent

View file

@ -0,0 +1,2 @@
VERTEX deformed_model_normal_map_dq
FRAGMENT forward_model_translucent

View file

@ -1,2 +0,0 @@
VERTEX skin_model_dq
FRAGMENT forward_model

View file

@ -1,2 +0,0 @@
VERTEX skin_model_normal_map_dq
FRAGMENT forward_model_normal_map

View file

@ -1,2 +0,0 @@
VERTEX skin_model_normal_map_dq
FRAGMENT forward_model_translucent

View file

@ -0,0 +1 @@
VERTEX model

View file

@ -0,0 +1 @@
VERTEX model

View file

@ -0,0 +1 @@
VERTEX model_normal_map

View file

@ -0,0 +1 @@
VERTEX model_normal_map

View file

@ -0,0 +1 @@
VERTEX model_normal_map

View file

@ -0,0 +1 @@
VERTEX model_shadow

View file

@ -0,0 +1 @@
VERTEX model

View file

@ -1 +1 @@
VERTEX model_fade
VERTEX model

View file

@ -0,0 +1 @@
VERTEX model_normal_map

View file

@ -1 +1 @@
VERTEX model_translucent_normal_map
VERTEX model_normal_map

View file

@ -1 +1 @@
VERTEX model_fade
VERTEX model

View file

@ -1 +1 @@
VERTEX model_fade
VERTEX model

View file

@ -1 +0,0 @@
FRAGMENT model

View file

@ -1 +0,0 @@
FRAGMENT model

View file

@ -1 +0,0 @@
FRAGMENT model_fade

View file

@ -1 +0,0 @@
FRAGMENT model_fade

View file

@ -1 +0,0 @@
FRAGMENT model_normal_map

View file

@ -1 +0,0 @@
FRAGMENT model_normal_map

View file

@ -1 +0,0 @@
FRAGMENT model_normal_map_fade

View file

@ -1 +0,0 @@
FRAGMENT model_normal_map_fade

View file

@ -1 +0,0 @@
FRAGMENT model_shadow

View file

@ -1 +0,0 @@
FRAGMENT model_shadow

View file

@ -1 +0,0 @@
FRAGMENT model_shadow

Some files were not shown because too many files have changed in this diff Show more