Merge pull request #5814 from samcake/HMDLightingBug

Fixing HMD and stereo lighting bug
This commit is contained in:
Brad Davis 2015-09-15 18:10:26 -07:00
commit f35ffd2ab7
20 changed files with 543 additions and 389 deletions

View file

@ -29,33 +29,40 @@ bool StereoDisplayPlugin::isSupported() const {
// FIXME make this into a setting that can be adjusted
const float DEFAULT_IPD = 0.064f;
const float HALF_DEFAULT_IPD = DEFAULT_IPD / 2.0f;
// Default physical display width (50cm)
const float DEFAULT_SCREEN_WIDTH = 0.5f;
// Default separation = ipd / screenWidth
const float DEFAULT_SEPARATION = DEFAULT_IPD / DEFAULT_SCREEN_WIDTH;
// Default convergence depth: where is the screen plane in the virtual space (which depth)
const float DEFAULT_CONVERGENCE = 0.5f;
glm::mat4 StereoDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const {
// Refer to http://www.nvidia.com/content/gtc-2010/pdfs/2010_gtc2010.pdf on creating
// stereo projection matrices. Do NOT use "toe-in", use translation.
// Updated version: http://developer.download.nvidia.com/assets/gamedev/docs/Siggraph2011-Stereoscopy_From_XY_to_Z-SG.pdf
if (eye == Mono) {
// FIXME provide a combined matrix, needed for proper culling
return baseProjection;
}
float nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
float screenZ = 0.25f; // screen projection plane
// FIXME verify this is the right calculation
float frustumshift = HALF_DEFAULT_IPD * nearZ / screenZ;
float frustumshift = DEFAULT_SEPARATION;
if (eye == Right) {
frustumshift = -frustumshift;
}
return glm::translate(baseProjection, vec3(frustumshift, 0, 0));
auto eyeProjection = baseProjection;
eyeProjection[2][0] += frustumshift;
eyeProjection[3][0] += frustumshift * DEFAULT_CONVERGENCE; // include the eye offset here
return eyeProjection;
}
glm::mat4 StereoDisplayPlugin::getEyePose(Eye eye) const {
float modelviewShift = HALF_DEFAULT_IPD;
if (eye == Left) {
modelviewShift = -modelviewShift;
}
return glm::translate(mat4(), vec3(modelviewShift, 0, 0));
return mat4();
}
std::vector<QAction*> _screenActions;

View file

@ -56,6 +56,15 @@ void Context::setStereoViews(const mat4 eyeViews[2]) {
_backend->setStereoViews(eyeViews);
}
void Context::getStereoProjections(mat4* eyeProjections) const {
_backend->getStereoProjections(eyeProjections);
}
void Context::getStereoViews(mat4* eyeViews) const {
_backend->getStereoViews(eyeViews);
}
void Context::syncCache() {
PROFILE_RANGE(__FUNCTION__);
_backend->syncCache();

View file

@ -61,6 +61,18 @@ public:
}
}
void getStereoProjections(mat4* eyeProjections) const {
for (int i = 0; i < 2; ++i) {
eyeProjections[i] = _stereo._eyeProjections[i];
}
}
void getStereoViews(mat4* eyeViews) const {
for (int i = 0; i < 2; ++i) {
eyeViews[i] = _stereo._eyeViews[i];
}
}
virtual void syncCache() = 0;
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
@ -176,6 +188,8 @@ public:
bool isStereo();
void setStereoProjections(const mat4 eyeProjections[2]);
void setStereoViews(const mat4 eyeViews[2]);
void getStereoProjections(mat4* eyeProjections) const;
void getStereoViews(mat4* eyeViews) const;
void syncCache();
// Downloading the Framebuffer is a synchronous action that is not efficient.

View file

@ -11,7 +11,6 @@
<@if not DEFERRED_BUFFER_SLH@>
<@def DEFERRED_BUFFER_SLH@>
uniform bool stereoMode = false;
// the diffuse texture
uniform sampler2D diffuseMap;
@ -25,17 +24,38 @@ uniform sampler2D specularMap;
// the depth texture
uniform sampler2D depthMap;
// the distance to the near clip plane
uniform float near;
// scale factor for depth: (far - near) / far
uniform float depthScale;
struct DeferredTransform {
mat4 projection;
mat4 viewInverse;
// offset for depth texture coordinates
uniform vec2 depthTexCoordOffset;
vec4 stereoSide_spareABC;
};
layout(std140) uniform deferredTransformBuffer {
DeferredTransform _deferredTransform;
};
DeferredTransform getDeferredTransform() {
return _deferredTransform;
}
// scale for depth texture coordinates
uniform vec2 depthTexCoordScale;
bool getStereoMode(DeferredTransform deferredTransform) {
return (deferredTransform.stereoSide_spareABC.x != 0.0);
}
float getStereoSide(DeferredTransform deferredTransform) {
return (deferredTransform.stereoSide_spareABC.x);
}
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {
vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f);
// compute the view space position using the depth
// basically manually pick the proj matrix components to do the inverse
float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]);
float Xe = (-Ze * nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0];
float Ye = (-Ze * nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1];
return vec4(Xe, Ye, Ze, 1.0f);
}
struct DeferredFragment {
float depthVal;
@ -50,22 +70,20 @@ struct DeferredFragment {
float gloss;
};
DeferredFragment unpackDeferredFragment(vec2 texcoord) {
DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) {
DeferredFragment frag;
frag.depthVal = texture(depthMap, texcoord).r;
frag.normalVal = texture(normalMap, texcoord);
frag.diffuseVal = texture(diffuseMap, texcoord);
frag.specularVal = texture(specularMap, texcoord);
if (stereoMode) {
if (getStereoMode(deferredTransform)) {
if (texcoord.x > 0.5) {
texcoord.x -= 0.5;
}
texcoord.x *= 2.0;
}
// compute the view space position using the depth
float z = near / (frag.depthVal * depthScale - 1.0);
frag.position = vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0);
frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord);
// Unpack the normal from the map
frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0));
@ -78,4 +96,5 @@ DeferredFragment unpackDeferredFragment(vec2 texcoord) {
return frag;
}
<@endif@>

View file

@ -13,6 +13,8 @@
<@include DeferredLighting.slh@>
<@func declareSkyboxMap()@>
uniform samplerCube skyboxMap;
vec4 evalSkyboxLight(vec3 direction, float lod) {
@ -22,6 +24,9 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
return skytexel;
}
<@endfunc@>
<@func declareSphericalHarmonics()@>
struct SphericalHarmonics {
vec4 L00;
vec4 L1m1;
@ -59,13 +64,13 @@ vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) {
// Need one SH
uniform SphericalHarmonics ambientSphere;
<@endfunc@>
// 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) {
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
// Need the light now
Light light = getLight();
@ -82,7 +87,13 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal,
return color;
}
vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
<@endfunc@>
<@func declareEvalAmbientSphereGlobalColor()@>
<$declareSphericalHarmonics()$>
vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
// Need the light now
Light light = getLight();
@ -99,8 +110,14 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no
return color;
}
<@endfunc@>
vec3 evalSkyboxGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
<@func declareEvalSkyboxGlobalColor()@>
<$declareSkyboxMap()$>
<$declareSphericalHarmonics()$>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) {
// Need the light now
Light light = getLight();
@ -116,8 +133,10 @@ vec3 evalSkyboxGlobalColor(float shadowAttenuation, vec3 position, vec3 normal,
return color;
}
<@endfunc@>
vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) {
<@func declareEvalLightmappedColor()@>
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) {
Light light = getLight();
@ -141,5 +160,6 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve
return diffuse * (ambientLight + diffuseLight);
}
<@endfunc@>
<@endif@>

View file

@ -11,6 +11,8 @@
<@if not DEFERRED_LIGHTING_SLH@>
<@def DEFERRED_LIGHTING_SLH@>
<@func declareEvalPBRShading()@>
// Frag Shading returns the diffuse amount as W and the specular rgb as xyz
vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
// Diffuse Lighting
@ -33,6 +35,9 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp
return vec4(reflect, diffuse);
}
<@endfunc@>
<@func declareEvalBlinnRShading()@>
vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
// Diffuse Lighting
@ -49,6 +54,12 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3
return vec4(reflect, diffuse);
}
<@endfunc@>
<$declareEvalPBRShading()$>
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
/*if (gl_FragCoord.x > 1000) {

View file

@ -53,18 +53,13 @@ static const std::string glowIntensityShaderHandle = "glowIntensity";
struct LightLocations {
int shadowDistances;
int shadowScale;
int nearLocation;
int depthScale;
int depthTexCoordOffset;
int depthTexCoordScale;
int radius;
int ambientSphere;
int lightBufferUnit;
int atmosphereBufferUnit;
int invViewMat;
int texcoordMat;
int coneParam;
int stereo;
int deferredTransformBuffer;
};
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
@ -277,6 +272,13 @@ gpu::FramebufferPointer _copyFBO;
void DeferredLightingEffect::render(RenderArgs* args) {
gpu::Batch batch;
// Allocate the parameters buffer used by all the deferred shaders
if (!_deferredTransformBuffer[0]._buffer) {
DeferredTransform parameters;
_deferredTransformBuffer[0] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
_deferredTransformBuffer[1] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
}
// Framebuffer copy operations cannot function as multipass stereo operations.
batch.enableStereo(false);
@ -289,296 +291,289 @@ void DeferredLightingEffect::render(RenderArgs* args) {
_copyFBO = framebufferCache->getFramebuffer();
batch.setFramebuffer(_copyFBO);
// Clearing it
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
// BInd the G-Buffer surfaces
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
auto monoViewport = args->_viewport;
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
// The view frustum is the mono frustum base
auto viewFrustum = args->_viewFrustum;
// Fetch the ViewMatrix;
glm::mat4 invViewMat;
invViewMat = args->_viewFrustum->getView();
// Eval the mono projection
mat4 monoProjMat;
viewFrustum->evalProjectionMatrix(monoProjMat);
auto& program = _directionalLight;
LightLocationsPtr locations = _directionalLightLocations;
// The mono view transform
Transform monoViewTransform;
viewFrustum->evalViewTransform(monoViewTransform);
// FIXME: Note: we've removed the menu items to enable shadows, so this will always be false for now.
// When we add back shadow support, this old approach may likely be removed and completely replaced
// but I've left it in for now.
bool shadowsEnabled = false;
bool cascadeShadowsEnabled = false;
if (shadowsEnabled) {
batch.setResourceTexture(4, framebufferCache->getShadowFramebuffer()->getDepthStencilBuffer());
program = _directionalLightShadowMap;
locations = _directionalLightShadowMapLocations;
if (cascadeShadowsEnabled) {
program = _directionalLightCascadedShadowMap;
locations = _directionalLightCascadedShadowMapLocations;
if (useSkyboxCubemap) {
program = _directionalSkyboxLightCascadedShadowMap;
locations = _directionalSkyboxLightCascadedShadowMapLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLightCascadedShadowMap;
locations = _directionalAmbientSphereLightCascadedShadowMapLocations;
}
batch.setPipeline(program);
batch._glUniform3fv(locations->shadowDistances, 1, (const float*) &_viewState->getShadowDistances());
} else {
if (useSkyboxCubemap) {
program = _directionalSkyboxLightShadowMap;
locations = _directionalSkyboxLightShadowMapLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLightShadowMap;
locations = _directionalAmbientSphereLightShadowMapLocations;
}
batch.setPipeline(program);
// THe mono view matrix coming from the mono view transform
glm::mat4 monoViewMat;
monoViewTransform.getMatrix(monoViewMat);
// Running in stero ?
bool isStereo = args->_context->isStereo();
int numPasses = 1;
mat4 projMats[2];
Transform viewTransforms[2];
ivec4 viewports[2];
vec4 clipQuad[2];
vec2 screenBottomLeftCorners[2];
vec2 screenTopRightCorners[2];
vec4 fetchTexcoordRects[2];
DeferredTransform deferredTransforms[2];
auto geometryCache = DependencyManager::get<GeometryCache>();
if (isStereo) {
numPasses = 2;
mat4 eyeViews[2];
args->_context->getStereoProjections(projMats);
args->_context->getStereoViews(eyeViews);
float halfWidth = 0.5 * sWidth;
for (int i = 0; i < numPasses; i++) {
// In stereo, the 2 sides are layout side by side in the mono viewport and their width is half
int sideWidth = monoViewport.z >> 1;
viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w);
deferredTransforms[i].projection = projMats[i];
auto sideViewMat = eyeViews[i] * monoViewMat;
viewTransforms[i].evalFromRawMatrix(sideViewMat);
deferredTransforms[i].viewInverse = sideViewMat;
deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f);
clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f);
screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f);
fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
}
batch._glUniform1f(locations->shadowScale, 1.0f / framebufferCache->getShadowFramebuffer()->getWidth());
} else {
if (useSkyboxCubemap) {
program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations;
}
batch.setPipeline(program);
viewports[0] = monoViewport;
projMats[0] = monoProjMat;
deferredTransforms[0].projection = monoProjMat;
deferredTransforms[0].viewInverse = monoViewMat;
deferredTransforms[0].stereoSide = 0.0f;
clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f);
screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f);
fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
}
{ // Setup the global lighting
auto globalLight = _allocatedLights[_globalLights.front()];
if (locations->ambientSphere >= 0) {
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
sh = (*_skybox->getCubemap()->getIrradiance());
}
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
}
}
if (useSkyboxCubemap) {
batch.setResourceTexture(5, _skybox->getCubemap());
}
auto eyePoint = viewFrustum->getPosition();
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
if (locations->lightBufferUnit >= 0) {
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
}
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
}
batch._glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
}
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
for (int side = 0; side < numPasses; side++) {
// Render in this side's viewport
batch.setViewportTransform(viewports[side]);
batch.setStateScissorRect(viewports[side]);
batch._glUniform1f(locations->nearLocation, nearVal);
// Sync and Bind the correct DeferredTransform ubo
_deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]);
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]);
float depthScale = (farVal - nearVal) / farVal;
batch._glUniform1f(locations->depthScale, depthScale);
float nearScale = -1.0f / nearVal;
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
batch._glUniform2f(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
bool stereo = args->_context->isStereo();
batch._glUniform1f(locations->stereo, stereo ? 1 : 0);
{
Transform model;
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
batch.setModelTransform(model);
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
glm::vec2 topLeft(-1.0f, -1.0f);
glm::vec2 bottomRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(sMin, tMin);
glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);
glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y);
glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
}
// First Global directional light and ambient pass
{
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
if (useSkyboxCubemap) {
batch.setResourceTexture(5, nullptr);
}
auto& program = _directionalLight;
LightLocationsPtr locations = _directionalLightLocations;
if (shadowsEnabled) {
batch.setResourceTexture(4, nullptr);
}
glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
auto texcoordMat = glm::mat4();
texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f);
texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
// enlarge the scales slightly to account for tesselation
const float SCALE_EXPANSION = 0.05f;
auto eyePoint = args->_viewFrustum->getPosition();
float nearRadius = glm::distance(eyePoint, args->_viewFrustum->getNearTopLeft());
auto geometryCache = DependencyManager::get<GeometryCache>();
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
if (!_pointLights.empty()) {
batch.setPipeline(_pointLight);
batch._glUniform1f(_pointLightLocations->nearLocation, nearVal);
batch._glUniform1f(_pointLightLocations->depthScale, depthScale);
batch._glUniform2f(_pointLightLocations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(_pointLightLocations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
batch._glUniformMatrix4fv(_pointLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
for (auto lightID : _pointLights) {
auto& light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
if (_pointLightLocations->lightBufferUnit >= 0) {
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
// TODO: At some point bring back the shadows...
// Setup the global directional pass pipeline
{
if (useSkyboxCubemap) {
program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations;
}
batch.setPipeline(program);
}
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
{ // Setup the global lighting
auto globalLight = _allocatedLights[_globalLights.front()];
if (locations->ambientSphere >= 0) {
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
sh = (*_skybox->getCubemap()->getIrradiance());
}
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
}
}
if (useSkyboxCubemap) {
batch.setResourceTexture(5, _skybox->getCubemap());
}
if (locations->lightBufferUnit >= 0) {
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
}
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
}
}
{
batch.setModelTransform(Transform());
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
glm::vec2 topLeft(-1.0f, -1.0f);
glm::vec2 bottomRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(sMin, tMin);
glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
}
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
} else {
Transform model;
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
batch.setModelTransform(model);
geometryCache->renderSphere(batch, expandedRadius, 32, 32, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
if (useSkyboxCubemap) {
batch.setResourceTexture(5, nullptr);
}
}
_pointLights.clear();
}
if (!_spotLights.empty()) {
batch.setPipeline(_spotLight);
batch._glUniform1f(_spotLightLocations->nearLocation, nearVal);
batch._glUniform1f(_spotLightLocations->depthScale, depthScale);
batch._glUniform2f(_spotLightLocations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(_spotLightLocations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
batch._glUniformMatrix4fv(_spotLightLocations->invViewMat, 1, false, reinterpret_cast< const float* >(&invViewMat));
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
auto texcoordMat = glm::mat4();
/* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
*/ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f);
texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f);
texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
for (auto lightID : _spotLights) {
auto light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
// enlarge the scales slightly to account for tesselation
const float SCALE_EXPANSION = 0.05f;
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
auto eyeLightPos = eyePoint - light->getPosition();
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
batch.setProjectionTransform(projMats[side]);
batch.setViewTransform(viewTransforms[side]);
const float TANGENT_LENGTH_SCALE = 0.666f;
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
// Splat Point lights
if (!_pointLights.empty()) {
batch.setPipeline(_pointLight);
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if ((eyeHalfPlaneDistance > -nearRadius) &&
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
coneParam.w = 0.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
batch.setProjectionTransform(glm::mat4());
for (auto lightID : _pointLights) {
auto& light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
if (_pointLightLocations->lightBufferUnit >= 0) {
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
}
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
batch.setProjectionTransform(glm::mat4());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
glm::vec2 topLeft(-1.0f, -1.0f);
glm::vec2 bottomRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(sMin, tMin);
glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
} else {
coneParam.w = 1.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
Transform model;
model.setTranslation(light->getPosition());
model.postRotate(light->getOrientation());
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
batch.setModelTransform(model);
auto mesh = getSpotLightMesh();
batch.setIndexBuffer(mesh->getIndexBuffer());
batch.setInputBuffer(0, mesh->getVertexBuffer());
batch.setInputFormat(mesh->getVertexFormat());
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
batch.setProjectionTransform(projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
Transform model;
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
batch.setModelTransform(model);
geometryCache->renderSphere(batch, expandedRadius, 32, 32, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
}
}
}
_spotLights.clear();
}
// Splat spot lights
if (!_spotLights.empty()) {
batch.setPipeline(_spotLight);
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
for (auto lightID : _spotLights) {
auto light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
auto eyeLightPos = eyePoint - light->getPosition();
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
const float TANGENT_LENGTH_SCALE = 0.666f;
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if ((eyeHalfPlaneDistance > -nearRadius) &&
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
coneParam.w = 0.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
batch.setProjectionTransform(glm::mat4());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
batch.setProjectionTransform( projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
coneParam.w = 1.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
Transform model;
model.setTranslation(light->getPosition());
model.postRotate(light->getOrientation());
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
batch.setModelTransform(model);
auto mesh = getSpotLightMesh();
batch.setIndexBuffer(mesh->getIndexBuffer());
batch.setInputBuffer(0, mesh->getVertexBuffer());
batch.setInputFormat(mesh->getVertexFormat());
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
}
}
}
}
// Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target
batch.setResourceTexture(0, nullptr);
batch.setResourceTexture(1, nullptr);
@ -588,6 +583,12 @@ void DeferredLightingEffect::render(RenderArgs* args) {
args->_context->render(batch);
// End of the Lighting pass
if (!_pointLights.empty()) {
_pointLights.clear();
}
if (!_spotLights.empty()) {
_spotLights.clear();
}
}
@ -648,23 +649,22 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
const int ATMOSPHERE_GPU_SLOT = 4;
slotBindings.insert(gpu::Shader::Binding(std::string("atmosphereBufferUnit"), ATMOSPHERE_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), DeferredLightingEffect::DEFERRED_TRANSFORM_BUFFER_SLOT));
gpu::Shader::makeProgram(*program, slotBindings);
locations->stereo = program->getUniforms().findLocation("stereoMode");
locations->shadowDistances = program->getUniforms().findLocation("shadowDistances");
locations->shadowScale = program->getUniforms().findLocation("shadowScale");
locations->nearLocation = program->getUniforms().findLocation("near");
locations->depthScale = program->getUniforms().findLocation("depthScale");
locations->depthTexCoordOffset = program->getUniforms().findLocation("depthTexCoordOffset");
locations->depthTexCoordScale = program->getUniforms().findLocation("depthTexCoordScale");
locations->radius = program->getUniforms().findLocation("radius");
locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00");
locations->invViewMat = program->getUniforms().findLocation("invViewMat");
locations->texcoordMat = program->getUniforms().findLocation("texcoordMat");
locations->coneParam = program->getUniforms().findLocation("coneParam");
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
locations->atmosphereBufferUnit = program->getBuffers().findLocation("atmosphereBufferUnit");
locations->deferredTransformBuffer = program->getBuffers().findLocation("deferredTransformBuffer");
auto state = std::make_shared<gpu::State>();
if (lightVolume) {

View file

@ -32,6 +32,7 @@ class DeferredLightingEffect : public Dependency {
public:
static const int NORMAL_FITTING_MAP_SLOT = 10;
static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2;
void init(AbstractViewStateInterface* viewState);
@ -78,7 +79,7 @@ public:
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
void setGlobalSkybox(const model::SkyboxPointer& skybox);
private:
DeferredLightingEffect() {}
virtual ~DeferredLightingEffect() { }
@ -151,6 +152,19 @@ private:
int _ambientLightMode = 0;
model::AtmospherePointer _atmosphere;
model::SkyboxPointer _skybox;
// Class describing the uniform buffer with all the parameters common to the deferred shaders
class DeferredTransform {
public:
glm::mat4 projection;
glm::mat4 viewInverse;
float stereoSide{ 0.f };
float spareA, spareB, spareC;
DeferredTransform() {}
};
typedef gpu::BufferView UniformBufferView;
UniformBufferView _deferredTransformBuffer[2];
};
class SimpleProgramKey {

View file

@ -111,7 +111,7 @@ float evalShadowAttenuation(vec4 shadowTexcoord) {
return evalShadowAttenuationBasic(shadowTexcoord);
}
<!
vec3 debugShadowMap(float shadowAttenuation, vec4 shadowTexcoord) {
vec3 colorArray[4];
colorArray[0].xyz = vec3(1.0, 1.0, 1.0);
@ -128,5 +128,6 @@ vec3 debugShadowMap(float shadowAttenuation, vec4 shadowTexcoord) {
return shadowAttenuation * colorArray[int(shadowTexcoord.w)];
// return shadowAttenuation * vec3(2.0*(shadowTexcoord.xy - offsetArray[int(shadowTexcoord.w)]), 0);
}
!>
<@endif@>

View file

@ -17,30 +17,34 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientSphereGlobalColor()$>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
1.0,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalAmbienSphereGlobalColor(
deferredTransform.viewInverse,
1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -17,6 +17,9 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientSphereGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
@ -24,7 +27,8 @@ in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position);
@ -32,20 +36,22 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalAmbienSphereGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -16,6 +16,8 @@
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientSphereGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
@ -24,7 +26,8 @@ in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalShadowTexcoord(frag.position);
@ -32,20 +35,22 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalAmbienSphereGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -17,28 +17,34 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientGlobalColor()$>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4( evalLightmappedColor(
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
1.0,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienGlobalColor(1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalAmbienGlobalColor(
deferredTransform.viewInverse,
1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -17,6 +17,9 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
@ -24,7 +27,9 @@ in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position);
@ -32,14 +37,17 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienGlobalColor(shadowAttenuation,
vec3 color = evalAmbienGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,

View file

@ -17,6 +17,9 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
@ -24,7 +27,8 @@ in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalShadowTexcoord(frag.position);
@ -32,19 +36,22 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienGlobalColor(shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalAmbienGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}

View file

@ -3,43 +3,48 @@
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
<!// fragment shader
//
// Created by Sam Gateau on 5/8/2015.
// 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
//
//!>
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalSkyboxGlobalColor()$>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
1.0,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalSkyboxGlobalColor(1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalSkyboxGlobalColor(
deferredTransform.viewInverse,
1.0,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}

View file

@ -17,6 +17,9 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalSkyboxGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
@ -24,7 +27,8 @@ in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position);
@ -32,19 +36,23 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalSkyboxGlobalColor(shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalSkyboxGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}

View file

@ -17,6 +17,9 @@
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalSkyboxGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
@ -24,7 +27,8 @@ in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFragment frag = unpackDeferredFragment(_texCoord0);
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalShadowTexcoord(frag.position);
@ -32,19 +36,22 @@ void main(void) {
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
_fragColor = vec4(evalLightmappedColor(
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz),
1.0);
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalSkyboxGlobalColor(shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
vec3 color = evalSkyboxGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}

View file

@ -21,17 +21,19 @@
// Everything about light
<@include model/Light.slh@>
// The view Matrix
uniform mat4 invViewMat;
in vec4 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
// Grab the fragment data from the uv
vec2 texCoord = _texCoord0.st / _texCoord0.q;
DeferredFragment frag = unpackDeferredFragment(texCoord);
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
mat4 invViewMat = deferredTransform.viewInverse;
// Kill if in front of the light volume
float depth = frag.depthVal;
if (depth < gl_FragCoord.z) {

View file

@ -21,16 +21,17 @@
// Everything about light
<@include model/Light.slh@>
// The view Matrix
uniform mat4 invViewMat;
in vec4 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
// Grab the fragment data from the uv
vec2 texCoord = _texCoord0.st / _texCoord0.q;
DeferredFragment frag = unpackDeferredFragment(texCoord);
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
mat4 invViewMat = deferredTransform.viewInverse;
// Kill if in front of the light volume
float depth = frag.depthVal;