From 8d3a3221b030f979814765c44f617dd48cc51713 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sat, 6 Jun 2015 09:50:56 -0700 Subject: [PATCH] shuffling the rendering steps to get to render transparent and light it correctly --- examples/utilities/tools/renderEngineDebug.js | 6 +- libraries/gpu/src/gpu/Context.h | 10 +- libraries/gpu/src/gpu/Format.h | 6 +- libraries/gpu/src/gpu/Resource.cpp | 2 - libraries/gpu/src/gpu/Transform.slh | 16 +++ .../src/DeferredLightingEffect.cpp | 35 +++++-- .../render-utils/src/DeferredLightingEffect.h | 15 +-- libraries/render-utils/src/Model.cpp | 6 ++ .../render-utils/src/RenderDeferredTask.cpp | 99 ++++++++++++++++++- .../render-utils/src/RenderDeferredTask.h | 16 ++- libraries/render-utils/src/TextureCache.cpp | 10 ++ libraries/render-utils/src/TextureCache.h | 4 + libraries/render-utils/src/model.slv | 5 +- .../render-utils/src/model_translucent.slf | 71 ++++++++++++- libraries/render-utils/src/skin_model.slv | 5 +- .../src/skin_model_normal_map.slv | 9 +- 16 files changed, 271 insertions(+), 44 deletions(-) diff --git a/examples/utilities/tools/renderEngineDebug.js b/examples/utilities/tools/renderEngineDebug.js index 3893b8b90e..79b0010210 100755 --- a/examples/utilities/tools/renderEngineDebug.js +++ b/examples/utilities/tools/renderEngineDebug.js @@ -66,19 +66,19 @@ panel.newCheckbox("Enable Render Transparent", function(value) { return (value); } ); -panel.newSlider("Num Feed Transparents", 0, 1000, +panel.newSlider("Num Feed Transparents", 0, 100, function(value) { }, function() { return Scene.getEngineNumFeedTransparentItems(); }, function(value) { return (value); } ); -panel.newSlider("Num Drawn Transparents", 0, 1000, +panel.newSlider("Num Drawn Transparents", 0, 100, function(value) { }, function() { return Scene.getEngineNumDrawnTransparentItems(); }, function(value) { return (value); } ); -panel.newSlider("Max Drawn Transparents", -1, 1000, +panel.newSlider("Max Drawn Transparents", -1, 100, function(value) { Scene.setEngineMaxDrawnTransparentItems(value); }, function() { return Scene.getEngineMaxDrawnTransparentItems(); }, function(value) { return (value); } diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 99021d2731..98ddc7fb64 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -13,6 +13,8 @@ #include +#include "Batch.h" + #include "Resource.h" #include "Texture.h" #include "Pipeline.h" @@ -20,14 +22,6 @@ namespace gpu { -class GPUObject { -public: - GPUObject() {} - virtual ~GPUObject() {} -}; - -class Batch; - class Backend { public: diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 3ee32ffc56..7cf913430d 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -16,7 +16,11 @@ namespace gpu { -class GPUObject; +class GPUObject { +public: + GPUObject() {} + virtual ~GPUObject() {} +}; typedef int Stamp; diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index 7d2757e15c..046cf9fe40 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -8,8 +8,6 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -#include "Context.h" #include "Resource.h" #include diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 57a367fdba..65f97981f1 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -103,6 +103,22 @@ TransformCamera getTransformCamera() { <@endif@> <@endfunc@> +<@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> + + { // transformModelToClipPos + vec4 _worldpos = (<$objectTransform$>._model * <$modelPos$>); + <$eyePos$> = (<$cameraTransform$>._viewInverse * _worldpos); + vec4 _eyepos =(<$objectTransform$>._model * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0); + <$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos; + } +<@else@> + <$eyePos$> = gl_ModelViewMatrix * <$modelPos$>; + <$clipPos$> = gl_ModelViewProjectionMatrix * <$modelPos$>; +<@endif@> +<@endfunc@> + <@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@> <@if GPU_TRANSFORM_PROFILE == GPU_CORE@> { // transformModelToEyeDir diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 4398c1c3cc..c953107b79 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -219,6 +219,7 @@ void DeferredLightingEffect::render() { QSize framebufferSize = textureCache->getFrameBufferSize(); + // binding the first framebuffer auto freeFBO = DependencyManager::get()->getFreeFramebuffer(); glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(freeFBO)); @@ -489,11 +490,20 @@ void DeferredLightingEffect::render() { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); + // glDisable(GL_FRAMEBUFFER_SRGB); + // End of the Lighting pass +} + +void DeferredLightingEffect::copyBack(RenderArgs* args) { + auto textureCache = DependencyManager::get(); + QSize framebufferSize = textureCache->getFrameBufferSize(); + + auto freeFBO = DependencyManager::get()->getFreeFramebuffer(); + //freeFBO->release(); glBindFramebuffer(GL_FRAMEBUFFER, 0); - // glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_CULL_FACE); @@ -516,6 +526,18 @@ void DeferredLightingEffect::render() { glPushMatrix(); glLoadIdentity(); + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + const int VIEWPORT_X_INDEX = 0; + const int VIEWPORT_Y_INDEX = 1; + const int VIEWPORT_WIDTH_INDEX = 2; + const int VIEWPORT_HEIGHT_INDEX = 3; + + float sMin = viewport[VIEWPORT_X_INDEX] / (float)framebufferSize.width(); + float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)framebufferSize.width(); + float tMin = viewport[VIEWPORT_Y_INDEX] / (float)framebufferSize.height(); + float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)framebufferSize.height(); + renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); glBindTexture(GL_TEXTURE_2D, 0); @@ -531,12 +553,11 @@ void DeferredLightingEffect::render() { glMatrixMode(GL_MODELVIEW); glPopMatrix(); - - // now render the objects we held back until after deferred lighting - foreach (PostLightingRenderable* renderable, _postLightingRenderables) { - renderable->renderPostLighting(); - } - _postLightingRenderables.clear(); +} + +void DeferredLightingEffect::setupTransparent(RenderArgs* args) { + auto globalLight = _allocatedLights[_globalLights.front()]; + args->_batch->setUniformBuffer(4, globalLight->getSchemaBuffer()); } void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 58e5e35829..e8e402f27a 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -23,7 +23,7 @@ #include "model/Stage.h" class AbstractViewStateInterface; -class PostLightingRenderable; +class RenderArgs; /// Handles deferred lighting for the bits that require it (voxels...) class DeferredLightingEffect : public Dependency { @@ -66,11 +66,11 @@ public: void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), float intensity = 0.5f, const glm::quat& orientation = glm::quat(), float exponent = 0.0f, float cutoff = PI); - /// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object). - void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); } - void prepare(); void render(); + void copyBack(RenderArgs* args); + + void setupTransparent(RenderArgs* args); // update global lighting void setAmbientLightMode(int preset); @@ -153,7 +153,6 @@ private: std::vector _globalLights; std::vector _pointLights; std::vector _spotLights; - QVector _postLightingRenderables; AbstractViewStateInterface* _viewState; @@ -162,10 +161,4 @@ private: model::SkyboxPointer _skybox; }; -/// Simple interface for objects that require something to be rendered after deferred lighting. -class PostLightingRenderable { -public: - virtual void renderPostLighting() = 0; -}; - #endif // hifi_DeferredLightingEffect_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 473b843099..e1af8c69b2 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -112,6 +112,7 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key, slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4)); gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); gpu::Shader::makeProgram(*program, slotBindings); @@ -2158,6 +2159,11 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran const FBXMeshPart& part = mesh.parts.at(partIndex); model::MaterialPointer material = part._material; + float shininess = 0; + if (translucent) { + shininess = material->getShininess(); + } + if (material == nullptr) { // qCDebug(renderutils) << "WARNING: material == nullptr!!!"; } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 1fccb57cee..7fc27be5f2 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -10,7 +10,11 @@ // #include "RenderDeferredTask.h" +#include "gpu/Batch.h" #include "gpu/Context.h" +#include "DeferredLightingEffect.h" +#include "ViewFrustum.h" +#include "RenderArgs.h" #include @@ -22,9 +26,15 @@ template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPo DependencyManager::get()->prepare(); } +template <> void render::jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("RenderDeferred"); + DependencyManager::get()->render(); +// renderContext->args->_context->syncCache(); +} + template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("ResolveDeferred"); - DependencyManager::get()->render(); + DependencyManager::get()->copyBack(renderContext->args); } @@ -34,10 +44,11 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(DrawBackground())); _jobs.push_back(Job(DrawOpaque())); _jobs.push_back(Job(DrawLight())); - _jobs.push_back(Job(DrawTransparent())); _jobs.push_back(Job(ResetGLState())); + _jobs.push_back(Job(RenderDeferred())); _jobs.push_back(Job(ResolveDeferred())); - + _jobs.push_back(Job(DrawTransparentDeferred())); + _jobs.push_back(Job(ResetGLState())); } RenderDeferredTask::~RenderDeferredTask() { @@ -62,3 +73,85 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend job.run(sceneContext, renderContext); } }; + + + +template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawTransparentDeferred"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render transparents + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape()); + + ItemIDs inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + ItemIDs& renderedItems = inItems; + + renderContext->_numFeedTransparentItems = renderedItems.size(); + + ItemIDs culledItems; + if (renderContext->_cullTransparent) { + cullItems(sceneContext, renderContext, inItems, culledItems); + renderedItems = culledItems; + } + + renderContext->_numDrawnTransparentItems = renderedItems.size(); + + ItemIDs sortedItems; + if (renderContext->_sortTransparent) { + depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items! + renderedItems = sortedItems; + } + + if (renderContext->_renderTransparent) { + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; + + DependencyManager::get()->setupTransparent(renderContext->args); + + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + + const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; + const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + + /* // render translucent meshes afterwards + { + GLenum buffers[2]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + batch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD; + } + + renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems); +*/ + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + batch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; + } + + + renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems); + + args->_context->render((*args->_batch)); + args->_batch = nullptr; + } +} diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 318859e71c..17971dbfac 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -14,8 +14,6 @@ #include "render/DrawTask.h" -#include "DeferredLightingEffect.h" - class PrepareDeferred { public: }; @@ -23,6 +21,13 @@ namespace render { template <> void jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); } +class RenderDeferred { +public: +}; +namespace render { +template <> void jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +} + class ResolveDeferred { public: }; @@ -30,6 +35,13 @@ namespace render { template <> void jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); } +class DrawTransparentDeferred { +public: +}; +namespace render { +template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +} + class RenderDeferredTask : public render::Task { public: diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 97385cb060..354db7bc8d 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -52,6 +52,8 @@ void TextureCache::setFrameBufferSize(QSize frameBufferSize) { _primaryNormalTexture.reset(); _primarySpecularTexture.reset(); + _transparentFramebuffer.reset(); + _secondaryFramebuffer.reset(); _tertiaryFramebuffer.reset(); @@ -264,6 +266,14 @@ void TextureCache::setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool nor batch._glDrawBuffers(bufferCount, buffers); } +gpu::FramebufferPointer TextureCache::getTransparentFramebuffer() { + if (!_transparentFramebuffer) { + _transparentFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height())); + _transparentFramebuffer->setDepthStencilBuffer(getPrimaryDepthTexture(), getPrimaryDepthTexture()->getTexelFormat()); + } + return _transparentFramebuffer; +} + gpu::FramebufferPointer TextureCache::getSecondaryFramebuffer() { if (!_secondaryFramebuffer) { _secondaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height())); diff --git a/libraries/render-utils/src/TextureCache.h b/libraries/render-utils/src/TextureCache.h index ba7176b2a4..f5f9d976a8 100644 --- a/libraries/render-utils/src/TextureCache.h +++ b/libraries/render-utils/src/TextureCache.h @@ -71,6 +71,8 @@ public: gpu::TexturePointer getPrimaryNormalTexture(); gpu::TexturePointer getPrimarySpecularTexture(); + gpu::FramebufferPointer getTransparentFramebuffer(); + /// Returns the ID of the primary framebuffer object's depth texture. This contains the Z buffer used in rendering. GLuint getPrimaryDepthTextureID(); GLuint getPrimaryColorTextureID(); @@ -124,6 +126,8 @@ private: gpu::FramebufferPointer _primaryFramebuffer; void createPrimaryFramebuffer(); + gpu::FramebufferPointer _transparentFramebuffer; + gpu::FramebufferPointer _secondaryFramebuffer; gpu::FramebufferPointer _tertiaryFramebuffer; diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index 97b5eb640b..2d22c0df51 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -19,6 +19,9 @@ const int MAX_TEXCOORDS = 2; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +// interpolated eye position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -35,7 +38,7 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeAndClipPos(cam, obj, gl_Vertex, interpolatedPosition, gl_Position)$> <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 9b34951f88..9d39bf98a1 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -11,8 +11,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include DeferredBufferWrite.slh@> + <@include model/Material.slh@> @@ -39,4 +38,72 @@ void main(void) { // set the diffuse data // gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); +}*/!> +<@include model/Material.slh@> + +// Everything about global lighting + +<@include DeferredLighting.slh@> +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + + +// Everything about light +<@include model/Light.slh@> + +// The view Matrix +//uniform mat4 invViewMat; + +vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + + // Need the light now + Light light = getLight(); + TransformCamera cam = getTransformCamera(); + mat4 invViewMat = cam._viewInverse; + + vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); + vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); + vec3 fragEyeDir = normalize(fragEyeVector.xyz); + + vec3 color = diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light); + + vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); + + color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + + return color; +} + +// the diffuse texture +uniform sampler2D diffuseMap; + +// the interpolated view position +varying vec4 interpolatedPosition; + +// the interpolated normal +varying vec4 interpolatedNormal; + +varying vec3 color; + +void main(void) { + vec3 fragPosition = interpolatedPosition.xyz; + + // Fetch diffuse map + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + + Material mat = getMaterial(); + vec3 fragNormal = normalize(interpolatedNormal.xyz); + float fragOpacity = getMaterialOpacity(mat) * diffuse.a; + vec3 fragDiffuse = getMaterialDiffuse(mat) * diffuse.rgb * color; + vec3 fragSpecular = getMaterialSpecular(mat); + float fragGloss = getMaterialShininess(mat); + + vec3 color = evalAmbienGlobalColor(1.0, + fragPosition, + fragNormal, + fragDiffuse, + fragSpecular, + fragGloss); + + gl_FragColor = vec4(color, fragOpacity); } diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index c94fc0d151..459072e747 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -25,6 +25,9 @@ uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; attribute vec4 clusterIndices; attribute vec4 clusterWeights; +// interpolated eye position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -49,7 +52,7 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, position, gl_Position)$> + <$transformModelToWorldAndClipPos(cam, obj, gl_Vertex, interpolatedPosition, gl_Position)$> <$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$> interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index ed552a7aca..3f815ba47e 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -28,6 +28,9 @@ attribute vec3 tangent; attribute vec4 clusterIndices; attribute vec4 clusterWeights; +// interpolated eye position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -37,13 +40,13 @@ varying vec4 interpolatedTangent; varying vec3 color; void main(void) { - vec4 interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0); + vec4 position = vec4(0.0, 0.0, 0.0, 0.0); interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0); interpolatedTangent = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])]; float clusterWeight = clusterWeights[i]; - interpolatedPosition += clusterMatrix * gl_Vertex * clusterWeight; + position += clusterMatrix * gl_Vertex * clusterWeight; interpolatedNormal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; interpolatedTangent += clusterMatrix * vec4(tangent, 0.0) * clusterWeight; } @@ -60,7 +63,7 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, interpolatedPosition, gl_Position)$> + <$transformModelToEyeAndClipPos(cam, obj, position, interpolatedPosition, gl_Position)$> <$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$> <$transformModelToEyeDir(cam, obj, interpolatedTangent.xyz, interpolatedTangent.xyz)$>