mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 08:04:01 +02:00
Merge pull request #3293 from ey6es/metavoxels
Support for shadows on heightmaps.
This commit is contained in:
commit
5ca28901bd
6 changed files with 190 additions and 13 deletions
|
@ -20,6 +20,9 @@ uniform float heightScale;
|
|||
// the scale between height and color textures
|
||||
uniform float colorScale;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
|
@ -32,13 +35,17 @@ void main(void) {
|
|||
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r;
|
||||
normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0));
|
||||
|
||||
// pass along the scaled/offset texture coordinates
|
||||
gl_TexCoord[0] = (gl_MultiTexCoord0 - vec4(heightScale, heightScale, 0.0, 0.0)) * colorScale;
|
||||
|
||||
// add the height to the position
|
||||
float height = texture2D(heightMap, heightCoord).r;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
||||
position = gl_ModelViewMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
||||
gl_Position = gl_ProjectionMatrix * position;
|
||||
|
||||
// the zero height should be invisible
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, step(height, 0.0));
|
||||
|
||||
// pass along the scaled/offset texture coordinates
|
||||
gl_TexCoord[0] = (gl_MultiTexCoord0 - vec4(heightScale, heightScale, 0.0, 0.0)) * colorScale;
|
||||
|
||||
// and the shadow texture coordinates
|
||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// metavoxel_heightfield.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 7/28/14.
|
||||
// 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
|
||||
//
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the distances to the cascade sections
|
||||
uniform vec3 shadowDistances;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// 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));
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalize(normal), gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 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);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// metavoxel_heightfield.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 7/28/14.
|
||||
// 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
|
||||
//
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalize(normal), gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
}
|
|
@ -760,10 +760,21 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
glBindTexture(GL_TEXTURE_2D, _heightTextureID);
|
||||
|
||||
if (!cursor) {
|
||||
DefaultMetavoxelRendererImplementation::getHeightfieldProgram().setUniformValue(
|
||||
DefaultMetavoxelRendererImplementation::getHeightScaleLocation(), 1.0f / _heightSize);
|
||||
DefaultMetavoxelRendererImplementation::getHeightfieldProgram().setUniformValue(
|
||||
DefaultMetavoxelRendererImplementation::getColorScaleLocation(), (float)_heightSize / innerSize);
|
||||
int heightScaleLocation = DefaultMetavoxelRendererImplementation::getHeightScaleLocation();
|
||||
int colorScaleLocation = DefaultMetavoxelRendererImplementation::getColorScaleLocation();
|
||||
ProgramObject* program = &DefaultMetavoxelRendererImplementation::getHeightfieldProgram();
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SimpleShadows)) {
|
||||
heightScaleLocation = DefaultMetavoxelRendererImplementation::getShadowMapHeightScaleLocation();
|
||||
colorScaleLocation = DefaultMetavoxelRendererImplementation::getShadowMapColorScaleLocation();
|
||||
program = &DefaultMetavoxelRendererImplementation::getShadowMapHeightfieldProgram();
|
||||
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||
heightScaleLocation = DefaultMetavoxelRendererImplementation::getCascadedShadowMapHeightScaleLocation();
|
||||
colorScaleLocation = DefaultMetavoxelRendererImplementation::getCascadedShadowMapColorScaleLocation();
|
||||
program = &DefaultMetavoxelRendererImplementation::getCascadedShadowMapHeightfieldProgram();
|
||||
}
|
||||
program->setUniformValue(heightScaleLocation, 1.0f / _heightSize);
|
||||
program->setUniformValue(colorScaleLocation, (float)_heightSize / innerSize);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
||||
}
|
||||
|
@ -858,6 +869,35 @@ void DefaultMetavoxelRendererImplementation::init() {
|
|||
_colorScaleLocation = _heightfieldProgram.uniformLocation("colorScale");
|
||||
_heightfieldProgram.release();
|
||||
|
||||
_shadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
"shaders/metavoxel_heightfield.vert");
|
||||
_shadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
"shaders/metavoxel_heightfield_shadow_map.frag");
|
||||
_shadowMapHeightfieldProgram.link();
|
||||
|
||||
_shadowMapHeightfieldProgram.bind();
|
||||
_shadowMapHeightfieldProgram.setUniformValue("heightMap", 0);
|
||||
_shadowMapHeightfieldProgram.setUniformValue("diffuseMap", 1);
|
||||
_shadowMapHeightfieldProgram.setUniformValue("shadowMap", 2);
|
||||
_shadowMapHeightScaleLocation = _shadowMapHeightfieldProgram.uniformLocation("heightScale");
|
||||
_shadowMapColorScaleLocation = _shadowMapHeightfieldProgram.uniformLocation("colorScale");
|
||||
_shadowMapHeightfieldProgram.release();
|
||||
|
||||
_cascadedShadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
"shaders/metavoxel_heightfield.vert");
|
||||
_cascadedShadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
"shaders/metavoxel_heightfield_cascaded_shadow_map.frag");
|
||||
_cascadedShadowMapHeightfieldProgram.link();
|
||||
|
||||
_cascadedShadowMapHeightfieldProgram.bind();
|
||||
_cascadedShadowMapHeightfieldProgram.setUniformValue("heightMap", 0);
|
||||
_cascadedShadowMapHeightfieldProgram.setUniformValue("diffuseMap", 1);
|
||||
_cascadedShadowMapHeightfieldProgram.setUniformValue("shadowMap", 2);
|
||||
_cascadedShadowMapHeightScaleLocation = _cascadedShadowMapHeightfieldProgram.uniformLocation("heightScale");
|
||||
_cascadedShadowMapColorScaleLocation = _cascadedShadowMapHeightfieldProgram.uniformLocation("colorScale");
|
||||
_shadowDistancesLocation = _cascadedShadowMapHeightfieldProgram.uniformLocation("shadowDistances");
|
||||
_cascadedShadowMapHeightfieldProgram.release();
|
||||
|
||||
_heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
"shaders/metavoxel_heightfield_cursor.vert");
|
||||
_heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
|
@ -1394,15 +1434,34 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
|||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
_heightfieldProgram.bind();
|
||||
ProgramObject* program = &_heightfieldProgram;
|
||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||
program = &_cascadedShadowMapHeightfieldProgram;
|
||||
program->bind();
|
||||
program->setUniform(_shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
||||
|
||||
} else {
|
||||
program = &_shadowMapHeightfieldProgram;
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
program->bind();
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
|
||||
data.guide(heightfieldRenderVisitor);
|
||||
|
||||
_heightfieldProgram.release();
|
||||
program->release();
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
|
@ -1416,6 +1475,13 @@ int DefaultMetavoxelRendererImplementation::_pointScaleLocation;
|
|||
ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldProgram;
|
||||
int DefaultMetavoxelRendererImplementation::_heightScaleLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_colorScaleLocation;
|
||||
ProgramObject DefaultMetavoxelRendererImplementation::_shadowMapHeightfieldProgram;
|
||||
int DefaultMetavoxelRendererImplementation::_shadowMapHeightScaleLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_shadowMapColorScaleLocation;
|
||||
ProgramObject DefaultMetavoxelRendererImplementation::_cascadedShadowMapHeightfieldProgram;
|
||||
int DefaultMetavoxelRendererImplementation::_cascadedShadowMapHeightScaleLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_cascadedShadowMapColorScaleLocation;
|
||||
int DefaultMetavoxelRendererImplementation::_shadowDistancesLocation;
|
||||
ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldCursorProgram;
|
||||
|
||||
static void enableClipPlane(GLenum plane, float x, float y, float z, float w) {
|
||||
|
|
|
@ -223,6 +223,14 @@ public:
|
|||
static int getHeightScaleLocation() { return _heightScaleLocation; }
|
||||
static int getColorScaleLocation() { return _colorScaleLocation; }
|
||||
|
||||
static ProgramObject& getShadowMapHeightfieldProgram() { return _shadowMapHeightfieldProgram; }
|
||||
static int getShadowMapHeightScaleLocation() { return _shadowMapHeightScaleLocation; }
|
||||
static int getShadowMapColorScaleLocation() { return _shadowMapColorScaleLocation; }
|
||||
|
||||
static ProgramObject& getCascadedShadowMapHeightfieldProgram() { return _cascadedShadowMapHeightfieldProgram; }
|
||||
static int getCascadedShadowMapHeightScaleLocation() { return _cascadedShadowMapHeightScaleLocation; }
|
||||
static int getCascadedShadowMapColorScaleLocation() { return _cascadedShadowMapColorScaleLocation; }
|
||||
|
||||
static ProgramObject& getHeightfieldCursorProgram() { return _heightfieldCursorProgram; }
|
||||
|
||||
Q_INVOKABLE DefaultMetavoxelRendererImplementation();
|
||||
|
@ -240,6 +248,15 @@ private:
|
|||
static int _heightScaleLocation;
|
||||
static int _colorScaleLocation;
|
||||
|
||||
static ProgramObject _shadowMapHeightfieldProgram;
|
||||
static int _shadowMapHeightScaleLocation;
|
||||
static int _shadowMapColorScaleLocation;
|
||||
|
||||
static ProgramObject _cascadedShadowMapHeightfieldProgram;
|
||||
static int _cascadedShadowMapHeightScaleLocation;
|
||||
static int _cascadedShadowMapColorScaleLocation;
|
||||
static int _shadowDistancesLocation;
|
||||
|
||||
static ProgramObject _heightfieldCursorProgram;
|
||||
};
|
||||
|
||||
|
|
|
@ -1449,9 +1449,11 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re
|
|||
if (cascadedShadows) {
|
||||
activeProgram->setUniform(activeLocations->shadowDistances, Application::getInstance()->getShadowDistances());
|
||||
}
|
||||
activeProgram->setUniformValueArray(activeLocations->localLightDirections,
|
||||
(const GLfloat*)_localLightDirections, MAX_LOCAL_LIGHTS, 4);
|
||||
|
||||
if (mode != SHADOW_RENDER_MODE) {
|
||||
activeProgram->setUniformValueArray(activeLocations->localLightDirections,
|
||||
(const GLfloat*)_localLightDirections, MAX_LOCAL_LIGHTS, 4);
|
||||
}
|
||||
|
||||
if (mesh.blendshapes.isEmpty()) {
|
||||
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
|
||||
activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
||||
|
|
Loading…
Reference in a new issue