mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 13:24:02 +02:00
merge upstream/master into andrew/inertia
This commit is contained in:
commit
11de33b98b
6 changed files with 143 additions and 41 deletions
|
@ -2514,7 +2514,7 @@ void Application::updateShadowMap() {
|
||||||
QOpenGLFramebufferObject* fbo = DependencyManager::get<TextureCache>()->getShadowFramebufferObject();
|
QOpenGLFramebufferObject* fbo = DependencyManager::get<TextureCache>()->getShadowFramebufferObject();
|
||||||
fbo->bind();
|
fbo->bind();
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glm::vec3 lightDirection = -getSunDirection();
|
glm::vec3 lightDirection = -getSunDirection();
|
||||||
glm::quat rotation = rotationBetween(IDENTITY_FRONT, lightDirection);
|
glm::quat rotation = rotationBetween(IDENTITY_FRONT, lightDirection);
|
||||||
|
@ -2539,8 +2539,10 @@ void Application::updateShadowMap() {
|
||||||
const glm::vec2& coord = MAP_COORDS[i];
|
const glm::vec2& coord = MAP_COORDS[i];
|
||||||
glViewport(coord.s * fbo->width(), coord.t * fbo->height(), targetSize, targetSize);
|
glViewport(coord.s * fbo->width(), coord.t * fbo->height(), targetSize, targetSize);
|
||||||
|
|
||||||
|
// if simple shadow then since the resolution is twice as much as with cascaded, cover 2 regions with the map, not just one
|
||||||
|
int regionIncrement = (matrixCount == 1 ? 2 : 1);
|
||||||
float nearScale = SHADOW_MATRIX_DISTANCES[i] * frustumScale;
|
float nearScale = SHADOW_MATRIX_DISTANCES[i] * frustumScale;
|
||||||
float farScale = SHADOW_MATRIX_DISTANCES[i + 1] * frustumScale;
|
float farScale = SHADOW_MATRIX_DISTANCES[i + regionIncrement] * frustumScale;
|
||||||
glm::vec3 points[] = {
|
glm::vec3 points[] = {
|
||||||
glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale),
|
glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale),
|
||||||
glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale),
|
glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale),
|
||||||
|
@ -2626,7 +2628,7 @@ void Application::updateShadowMap() {
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("entities");
|
PerformanceTimer perfTimer("entities");
|
||||||
// _entities.render(RenderArgs::SHADOW_RENDER_MODE);
|
_entities.render(RenderArgs::SHADOW_RENDER_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render JS/scriptable overlays
|
// render JS/scriptable overlays
|
||||||
|
|
|
@ -166,7 +166,14 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
// TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
|
// TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
|
||||||
// is significantly more expensive. Is there a way to call this that doesn't cost us as much?
|
// is significantly more expensive. Is there a way to call this that doesn't cost us as much?
|
||||||
PerformanceTimer perfTimer("model->render");
|
PerformanceTimer perfTimer("model->render");
|
||||||
|
// filter out if not needed to render
|
||||||
|
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
|
||||||
|
if (isMoving() || isAnimatingSomething()) {
|
||||||
_model->renderInScene(alpha, args);
|
_model->renderInScene(alpha, args);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_model->renderInScene(alpha, args);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we couldn't get a model, then just draw a cube
|
// if we couldn't get a model, then just draw a cube
|
||||||
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
|
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
|
||||||
|
|
115
libraries/render-utils/src/Shadow.slh
Executable file
115
libraries/render-utils/src/Shadow.slh
Executable file
|
@ -0,0 +1,115 @@
|
||||||
|
<!
|
||||||
|
// Shadow.slh
|
||||||
|
// libraries/render-utils/src
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 1/4/15.
|
||||||
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
!>
|
||||||
|
<@if not SHADOW_SLH@>
|
||||||
|
<@def SHADOW_SLH@>
|
||||||
|
|
||||||
|
// the shadow texture
|
||||||
|
uniform sampler2DShadow shadowMap;
|
||||||
|
|
||||||
|
// Fetching it
|
||||||
|
float fetchShadow(vec3 texcoord) {
|
||||||
|
<@if GLPROFILE == PC_GL @>
|
||||||
|
return texture(shadowMap, texcoord);
|
||||||
|
<@elif GLPROFILE == MAC_GL@>
|
||||||
|
return shadow2D(shadowMap, texcoord).r;
|
||||||
|
<@else@>
|
||||||
|
return shadow2D(shadowMap, texcoord).r;
|
||||||
|
<@endif@>
|
||||||
|
}
|
||||||
|
|
||||||
|
// the distances to the cascade sections
|
||||||
|
uniform vec3 shadowDistances;
|
||||||
|
|
||||||
|
// the inverse of the size of the shadow map
|
||||||
|
uniform float shadowScale;
|
||||||
|
|
||||||
|
vec2 samples[8] = vec2[8](
|
||||||
|
vec2(-2.0, -2.0),
|
||||||
|
vec2(2.0, -2.0),
|
||||||
|
vec2(2.0, 2.0),
|
||||||
|
vec2(-2.0, 2.0),
|
||||||
|
vec2(1.0, 0.0),
|
||||||
|
vec2(0.0, 1.0),
|
||||||
|
vec2(-1.0, 0.0),
|
||||||
|
vec2(0.0, -1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
vec4 evalShadowTexcoord(vec4 position) {
|
||||||
|
// compute the corresponding texture coordinates
|
||||||
|
vec3 shadowTexcoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position));
|
||||||
|
return vec4(shadowTexcoord, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 evalCascadedShadowTexcoord(vec4 position) {
|
||||||
|
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||||
|
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||||
|
vec3 shadowTexcoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||||
|
dot(gl_EyePlaneR[shadowIndex], position));
|
||||||
|
|
||||||
|
return vec4(shadowTexcoord, shadowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float evalShadowAttenuationPCF(vec4 shadowTexcoord) {
|
||||||
|
float radiusScale = (shadowTexcoord.w + 1.0);
|
||||||
|
float shadowAttenuation = (0.25 * (
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[0], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[1], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[2], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[3], 0.0))
|
||||||
|
));
|
||||||
|
|
||||||
|
if ((shadowAttenuation > 0) && (shadowAttenuation < 1.0)) {
|
||||||
|
radiusScale *= 0.5;
|
||||||
|
shadowAttenuation = 0.5 * shadowAttenuation + (0.125 * (
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[4], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[5], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[6], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[7], 0.0))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return shadowAttenuation;
|
||||||
|
}
|
||||||
|
|
||||||
|
float evalShadowAttenuationBasic(vec4 shadowTexcoord) {
|
||||||
|
float radiusScale = 0.5;
|
||||||
|
float shadowAttenuation = (0.25 * (
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[0], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[1], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[2], 0.0)) +
|
||||||
|
fetchShadow(shadowTexcoord.xyz + radiusScale * shadowScale * vec3(samples[3], 0.0))
|
||||||
|
));
|
||||||
|
return shadowAttenuation;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
colorArray[1].xyz = vec3(1.0, 0.0, 0.0);
|
||||||
|
colorArray[2].xyz = vec3(0.0, 1.0, 0.0);
|
||||||
|
colorArray[3].xyz = vec3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
vec2 offsetArray[4];
|
||||||
|
offsetArray[0] = vec2(0.0, 0.0);
|
||||||
|
offsetArray[1] = vec2(0.5, 0.0);
|
||||||
|
offsetArray[2] = vec2(0.0, 0.5);
|
||||||
|
offsetArray[3] = vec2(0.5, 0.5);
|
||||||
|
|
||||||
|
return shadowAttenuation * colorArray[int(shadowTexcoord.w)];
|
||||||
|
// return shadowAttenuation * vec3(2.0*(shadowTexcoord.xy - offsetArray[int(shadowTexcoord.w)]), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
<@endif@>
|
|
@ -299,15 +299,16 @@ QOpenGLFramebufferObject* TextureCache::getShadowFramebufferObject() {
|
||||||
|
|
||||||
glGenTextures(1, &_shadowDepthTextureID);
|
glGenTextures(1, &_shadowDepthTextureID);
|
||||||
glBindTexture(GL_TEXTURE_2D, _shadowDepthTextureID);
|
glBindTexture(GL_TEXTURE_2D, _shadowDepthTextureID);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE,
|
||||||
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
const float DISTANT_BORDER[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
const float DISTANT_BORDER[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, DISTANT_BORDER);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, DISTANT_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
_shadowFramebufferObject->bind();
|
_shadowFramebufferObject->bind();
|
||||||
|
|
|
@ -24,14 +24,8 @@ uniform sampler2D specularMap;
|
||||||
// the depth texture
|
// the depth texture
|
||||||
uniform sampler2D depthMap;
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
// the shadow texture
|
// Everything about shadow
|
||||||
uniform sampler2DShadow shadowMap;
|
<@include Shadow.slh@>
|
||||||
|
|
||||||
// the distances to the cascade sections
|
|
||||||
uniform vec3 shadowDistances;
|
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
uniform float shadowScale;
|
|
||||||
|
|
||||||
// the distance to the near clip plane
|
// the distance to the near clip plane
|
||||||
uniform float near;
|
uniform float near;
|
||||||
|
@ -55,17 +49,9 @@ void main(void) {
|
||||||
float z = near / (depthVal * depthScale - 1.0);
|
float z = near / (depthVal * depthScale - 1.0);
|
||||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||||
|
|
||||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
// Eval shadow Texcoord and then Attenuation
|
||||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
vec4 shadowTexcoord = evalCascadedShadowTexcoord(position);
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
|
||||||
dot(gl_EyePlaneR[shadowIndex], position));
|
|
||||||
|
|
||||||
// evaluate the shadow test but only relevant for light facing fragments
|
|
||||||
float shadowAttenuation = (0.25 *
|
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r));
|
|
||||||
|
|
||||||
// get the normal from the map
|
// get the normal from the map
|
||||||
vec3 normalizedNormal = normalize(normalVal.xyz * 2.0 - vec3(1.0));
|
vec3 normalizedNormal = normalize(normalVal.xyz * 2.0 - vec3(1.0));
|
||||||
|
@ -75,7 +61,7 @@ void main(void) {
|
||||||
|
|
||||||
// Light mapped or not ?
|
// Light mapped or not ?
|
||||||
if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) {
|
if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) {
|
||||||
normalVal.a = 0.0;
|
normalVal.a = 1.0;
|
||||||
|
|
||||||
// need to catch normals perpendicular to the projection plane hence the magic number for the threshold
|
// need to catch normals perpendicular to the projection plane hence the magic number for the threshold
|
||||||
// it should be just 0, but we have innacurracy so we need to overshoot
|
// it should be just 0, but we have innacurracy so we need to overshoot
|
||||||
|
|
|
@ -24,11 +24,8 @@ uniform sampler2D specularMap;
|
||||||
// the depth texture
|
// the depth texture
|
||||||
uniform sampler2D depthMap;
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
// the shadow texture
|
// Everything about shadow
|
||||||
uniform sampler2DShadow shadowMap;
|
<@include Shadow.slh@>
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
uniform float shadowScale;
|
|
||||||
|
|
||||||
// the distance to the near clip plane
|
// the distance to the near clip plane
|
||||||
uniform float near;
|
uniform float near;
|
||||||
|
@ -52,15 +49,9 @@ void main(void) {
|
||||||
float z = near / (depthVal * depthScale - 1.0);
|
float z = near / (depthVal * depthScale - 1.0);
|
||||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||||
|
|
||||||
// compute the corresponding texture coordinates
|
// Eval shadow Texcoord and then Attenuation
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position));
|
vec4 shadowTexcoord = evalShadowTexcoord(position);
|
||||||
|
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
|
||||||
// evaluate the shadow test but only relevant for light facing fragments
|
|
||||||
float shadowAttenuation = (0.25 *
|
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r));
|
|
||||||
|
|
||||||
// get the normal from the map
|
// get the normal from the map
|
||||||
vec3 normalizedNormal = normalize(normalVal.xyz * 2.0 - vec3(1.0));
|
vec3 normalizedNormal = normalize(normalVal.xyz * 2.0 - vec3(1.0));
|
||||||
|
|
Loading…
Reference in a new issue