Skip to content

Commit

Permalink
Renderer|Refactor: Added tangentspace.glsl; moved lighting functions
Browse files Browse the repository at this point in the history
Doomsday will now define the symbols DENG_VERTEX_SHADER or
DENG_FRAGMENT_SHADER when it compiles vertex and fragment shaders.
This allows the included GLSL files to adapt their behavior accordingly.
  • Loading branch information
skyjake committed Nov 1, 2015
1 parent da043bb commit 28d77ca
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 28 deletions.
Expand Up @@ -23,10 +23,28 @@ uniform highp float uEmission; // factor for emissive light
uniform highp vec4 uAmbientLight;
uniform highp vec4 uLightIntensities[4];
uniform highp vec3 uLightDirs[4];
uniform highp vec3 uEyePos;

varying highp vec3 vLightDirs[4]; // tangent space
varying highp vec3 vEyeDir; // tangent space

#ifdef DENG_VERTEX_SHADER

void calculateSurfaceLighting(highp mat3 surface)
{
vLightDirs[0] = uLightDirs[0] * surface;
vLightDirs[1] = uLightDirs[1] * surface;
vLightDirs[2] = uLightDirs[2] * surface;
vLightDirs[3] = uLightDirs[3] * surface;
}

void calculateEyeDirection(highp vec4 vertex, highp mat3 surface)
{
vEyeDir = (uEyePos - vertex.xyz/vertex.w) * surface;
}

#endif // DENG_VERTEX_SHADER

highp vec4 diffuseLightContrib(int index, highp vec3 normal)
{
if(uLightIntensities[index].a <= 0.001)
Expand Down
@@ -0,0 +1,36 @@
/*
* The Doomsday Engine Project
* Common OpenGL Shaders: Tangent space
*
* Copyright (c) 2015 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

attribute highp vec3 aNormal;
attribute highp vec3 aTangent;
attribute highp vec3 aBitangent;

highp vec3 transformVector(highp vec3 dir, highp mat4 matrix)
{
return (matrix * vec4(dir, 0.0)).xyz;
}

highp mat3 tangentSpace(highp mat4 modelSpace)
{
highp vec3 normal = transformVector(aNormal, modelSpace);
highp vec3 tangent = transformVector(aTangent, modelSpace);
highp vec3 bitangent = transformVector(aBitangent, modelSpace);
return mat3(tangent, bitangent, normal);
}
@@ -1,24 +1,21 @@
model {
model.skeletal {
# Shader for skeletal animation and generic per-pixel lighting:
# diffuse color, normal map, emission map, specular intensity.
shader skeletal.normal_specular_emission {
shader normal_specular_emission {
variable uAlpha { value = 1 }
variable uAlphaLimit { value = 0 }
variable uEmission { value = 0 }

# Mapping when used with ModelDrawable.
textureMapping <diffuse, normals, specular, emission>

include.vertex <include/skeletal.glsl,
include.vertex <include/tangentspace.glsl,
include/skeletal.glsl,
include/lighting.glsl>
vertex = "
uniform highp mat4 uMvpMatrix;
uniform highp vec3 uEyePos;

attribute highp vec4 aVertex;
attribute highp vec3 aNormal;
attribute highp vec3 aTangent;
attribute highp vec3 aBitangent;
attribute highp vec2 aUV;
attribute highp vec4 aBounds; // diffuse map
attribute highp vec4 aBounds2; // normal map
Expand All @@ -28,33 +25,18 @@ model {
varying highp vec2 vUV;
varying highp vec4 vUVBounds[4];

highp vec3 transformVector(highp vec3 dir, highp mat4 matrix)
{
return (matrix * vec4(dir, 0.0)).xyz;
}

void main(void)
{
highp mat4 bone = vertexBoneTransform();
highp mat3 surface = tangentSpace(bone);
calculateSurfaceLighting(surface);

// Vertex position.
highp vec4 modelPos = bone * aVertex;
gl_Position = uMvpMatrix * modelPos;

// Tangent space.
highp vec3 normal = transformVector(aNormal, bone);
highp vec3 tangent = transformVector(aTangent, bone);
highp vec3 bitangent = transformVector(aBitangent, bone);
highp mat3 tangentSpace = mat3(tangent, bitangent, normal);

// Light direction in tangent space.
vLightDirs[0] = uLightDirs[0] * tangentSpace;
vLightDirs[1] = uLightDirs[1] * tangentSpace;
vLightDirs[2] = uLightDirs[2] * tangentSpace;
vLightDirs[3] = uLightDirs[3] * tangentSpace;


// Eye direction in tangent space.
vEyeDir = (uEyePos - modelPos.xyz/modelPos.w) * tangentSpace;
calculateEyeDirection(modelPos, surface);

vUV = aUV;
vUVBounds[0] = aBounds;
Expand Down
15 changes: 13 additions & 2 deletions doomsday/sdk/libgui/src/graphics/glshader.cpp
Expand Up @@ -13,7 +13,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#include "de/GLShader"
Expand Down Expand Up @@ -141,9 +141,20 @@ void GLShader::compile(Type shaderType, IByteArray const &source)
d->type = shaderType;
d->alloc();

// Additional predefined symbols for the shader.
QByteArray predefs;
if(shaderType == Vertex)
{
predefs = QByteArray("#define DENG_VERTEX_SHADER\n");
}
else
{
predefs = QByteArray("#define DENG_FRAGMENT_SHADER\n");
}

// Prepare the shader source. This would be the time to substitute any
// remaining symbols in the shader source.
Block src = prefixToSource(source, prefix);
Block src = prefixToSource(source, prefix + predefs);

char const *srcPtr = src.constData();
glShaderSource(d->name, 1, &srcPtr, 0);
Expand Down

0 comments on commit 28d77ca

Please sign in to comment.