From 4696832ec6e072eb0d1b1e3eb79734e3322afd98 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 5 Aug 2014 15:13:50 -0700 Subject: [PATCH] Compute heightfield normals from adjacent values in vertex shader. --- .../resources/shaders/metavoxel_heightfield.vert | 12 ++++++++++-- interface/src/MetavoxelSystem.cpp | 5 +++++ interface/src/MetavoxelSystem.h | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/interface/resources/shaders/metavoxel_heightfield.vert b/interface/resources/shaders/metavoxel_heightfield.vert index 3cf43e87cd..cc4f68e9e0 100644 --- a/interface/resources/shaders/metavoxel_heightfield.vert +++ b/interface/resources/shaders/metavoxel_heightfield.vert @@ -14,18 +14,26 @@ // the height texture uniform sampler2D heightMap; +// the distance between height points in texture space +uniform float heightScale; + // the interpolated normal varying vec4 normal; void main(void) { // transform and store the normal for interpolation - normal = normalize(gl_ModelViewMatrix * vec4(0.0, 1.0, 0.0, 0.0)); + vec2 heightCoord = gl_MultiTexCoord0.st; + float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r - + texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r; + float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r - + texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r; + normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0)); // pass along the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; // add the height to the position - float height = texture2D(heightMap, gl_MultiTexCoord0.st).r; + float height = texture2D(heightMap, heightCoord).r; gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0)); // the zero height should be invisible diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 7aa6bc4080..f66d71070a 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -388,6 +388,9 @@ void HeightfieldBuffer::render() { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _colorTextureID); + DefaultMetavoxelRendererImplementation::getHeightfieldProgram().setUniformValue( + DefaultMetavoxelRendererImplementation::getHeightScaleLocation(), 1.0f / _heightSize); + glDrawRangeElements(GL_QUADS, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); glBindTexture(GL_TEXTURE_2D, 0); @@ -470,6 +473,7 @@ void DefaultMetavoxelRendererImplementation::init() { _heightfieldProgram.bind(); _heightfieldProgram.setUniformValue("heightMap", 0); _heightfieldProgram.setUniformValue("diffuseMap", 1); + _heightScaleLocation = _heightfieldProgram.uniformLocation("heightScale"); _heightfieldProgram.release(); } } @@ -766,6 +770,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox ProgramObject DefaultMetavoxelRendererImplementation::_pointProgram; int DefaultMetavoxelRendererImplementation::_pointScaleLocation; ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldProgram; +int DefaultMetavoxelRendererImplementation::_heightScaleLocation; static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { GLdouble coefficients[] = { x, y, z, w }; diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index abcc929156..e7ee0d2c18 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -191,6 +191,7 @@ public: static void init(); static ProgramObject& getHeightfieldProgram() { return _heightfieldProgram; } + static int getHeightScaleLocation() { return _heightScaleLocation; } Q_INVOKABLE DefaultMetavoxelRendererImplementation(); @@ -204,6 +205,7 @@ private: static int _pointScaleLocation; static ProgramObject _heightfieldProgram; + static int _heightScaleLocation; }; /// Base class for spanner renderers; provides clipping.