mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-18 03:36:22 +02:00
Merge pull request #5814 from samcake/HMDLightingBug
Fixing HMD and stereo lighting bug
This commit is contained in:
commit
f35ffd2ab7
20 changed files with 543 additions and 389 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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@>
|
||||
|
|
|
@ -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@>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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*) ¶meters));
|
||||
_deferredTransformBuffer[1] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters));
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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@>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue