mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 05:48:39 +02:00
shuffling the rendering steps to get to render transparent and light it correctly
This commit is contained in:
parent
aa5e6fa1b0
commit
8d3a3221b0
16 changed files with 271 additions and 44 deletions
|
@ -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); }
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#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:
|
||||
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
namespace gpu {
|
||||
|
||||
class GPUObject;
|
||||
class GPUObject {
|
||||
public:
|
||||
GPUObject() {}
|
||||
virtual ~GPUObject() {}
|
||||
};
|
||||
|
||||
typedef int Stamp;
|
||||
|
||||
|
|
|
@ -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 <QDebug>
|
||||
|
|
|
@ -103,6 +103,22 @@ TransformCamera getTransformCamera() {
|
|||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
||||
<@if GPU_TRANSFORM_PROFILE == GPU_CORE@>
|
||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||
//return camera._projection * camera._view * object._model * pos; !>
|
||||
{ // 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
|
||||
|
|
|
@ -219,6 +219,7 @@ void DeferredLightingEffect::render() {
|
|||
|
||||
QSize framebufferSize = textureCache->getFrameBufferSize();
|
||||
|
||||
// binding the first framebuffer
|
||||
auto freeFBO = DependencyManager::get<GlowEffect>()->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<TextureCache>();
|
||||
QSize framebufferSize = textureCache->getFrameBufferSize();
|
||||
|
||||
auto freeFBO = DependencyManager::get<GlowEffect>()->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) {
|
||||
|
|
|
@ -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<int> _globalLights;
|
||||
std::vector<int> _pointLights;
|
||||
std::vector<int> _spotLights;
|
||||
QVector<PostLightingRenderable*> _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
|
||||
|
|
|
@ -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!!!";
|
||||
}
|
||||
|
|
|
@ -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 <PerfStat.h>
|
||||
|
||||
|
@ -22,9 +26,15 @@ template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPo
|
|||
DependencyManager::get<DeferredLightingEffect>()->prepare();
|
||||
}
|
||||
|
||||
template <> void render::jobRun(const RenderDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
PerformanceTimer perfTimer("RenderDeferred");
|
||||
DependencyManager::get<DeferredLightingEffect>()->render();
|
||||
// renderContext->args->_context->syncCache();
|
||||
}
|
||||
|
||||
template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
PerformanceTimer perfTimer("ResolveDeferred");
|
||||
DependencyManager::get<DeferredLightingEffect>()->render();
|
||||
DependencyManager::get<DeferredLightingEffect>()->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<DeferredLightingEffect>()->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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)$>
|
||||
|
||||
|
|
Loading…
Reference in a new issue