Skip to content

Commit

Permalink
Model Renderer|GL: Eye direction in the model shader
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Aug 12, 2014
1 parent d39dd52 commit 7f582f7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 33 deletions.
4 changes: 3 additions & 1 deletion doomsday/client/include/render/modelrenderer.h
Expand Up @@ -75,11 +75,13 @@ class ModelRenderer
/**
* Sets up the transformation matrices.
*
* @param eyeDir Direction of the eye in local space (relative to object).
* @param modelToLocal Transformation from model space to the object's local space
* (object's local frame in world space).
* @param localToView Transformation from local space to projected view space.
*/
void setTransformation(de::Matrix4f const &modelToLocal,
void setTransformation(de::Vector3f const &eyeDir,
de::Matrix4f const &modelToLocal,
de::Matrix4f const &localToView);

void clearLights();
Expand Down
Expand Up @@ -5,7 +5,8 @@ group model {
vertex = "
uniform highp mat4 uMvpMatrix;
uniform highp mat4 uBoneMatrices[64];
uniform highp vec4 uLightDirs[4];
uniform highp vec3 uLightDirs[4];
uniform highp vec3 uEyeDir;

attribute highp vec4 aVertex;
attribute highp vec3 aNormal;
Expand All @@ -20,6 +21,7 @@ group model {
varying highp vec2 vUV;
varying highp vec2 vNormalUV;
varying highp vec3 vLightDirs[4]; // tangent space
varying highp vec3 vEyeDir; // tangent space

highp vec3 transformVector(highp vec3 dir, highp mat4 matrix) {
return (matrix * vec4(dir, 0.0)).xyz;
Expand All @@ -38,16 +40,19 @@ group model {
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 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].xyz * tangentSpace;
vLightDirs[1] = uLightDirs[1].xyz * tangentSpace;
vLightDirs[2] = uLightDirs[2].xyz * tangentSpace;
vLightDirs[3] = uLightDirs[3].xyz * tangentSpace;
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 = uEyeDir * tangentSpace;

vUV = aBounds.xy + aUV * aBounds.zw;
vNormalUV = aBounds2.xy + aUV * aBounds2.zw;
Expand All @@ -59,6 +64,7 @@ group model {
varying highp vec2 vUV;
varying highp vec2 vNormalUV;
varying highp vec3 vLightDirs[4]; // tangent space
varying highp vec3 vEyeDir; // tangent space

highp vec3 normalVector() {
return (texture2D(uTex, vNormalUV).xyz * 2.0) - 1.0;
Expand All @@ -79,6 +85,8 @@ group model {
diffuseLight(2, normal) +
diffuseLight(3, normal);
gl_FragColor.a = 1.0;

gl_FragColor.rgb = vec3(normalize(vEyeDir).z);
}"
}
}
41 changes: 18 additions & 23 deletions doomsday/client/src/render/modelrenderer.cpp
Expand Up @@ -40,27 +40,20 @@ DENG2_PIMPL(ModelRenderer)
{
#define MAX_LIGHTS 4

filesys::AssetObserver observer;
filesys::AssetObserver observer { "model\\..*" };
ModelBank bank;
std::unique_ptr<AtlasTexture> atlas;
GLProgram program; /// @todo Specific models may want to use a custom program.
GLUniform uMvpMatrix;
GLUniform uTex;
GLUniform uLightDirs;
GLUniform uLightIntensities;
GLUniform uMvpMatrix { "uMvpMatrix", GLUniform::Mat4 };
GLUniform uTex { "uTex", GLUniform::Sampler2D };
GLUniform uEyeDir { "uEyeDir", GLUniform::Vec3 };
GLUniform uLightDirs { "uLightDirs", GLUniform::Vec3Array, MAX_LIGHTS };
GLUniform uLightIntensities { "uLightIntensities", GLUniform::Vec4Array, MAX_LIGHTS };
Matrix4f inverseLocal;
int lightCount;
Id defaultNormals;

Instance(Public *i)
: Base(i)
, observer("model\\..*") // all model assets
, uMvpMatrix ("uMvpMatrix", GLUniform::Mat4)
, uTex ("uTex", GLUniform::Sampler2D)
, uLightDirs ("uLightDirs", GLUniform::Vec4Array, MAX_LIGHTS)
, uLightIntensities("uLightIntensities", GLUniform::Vec4Array, MAX_LIGHTS)
, lightCount(0)
, defaultNormals(Id::None)
int lightCount = 0;
Id defaultNormals { Id::None };

Instance(Public *i) : Base(i)
{
observer.audienceForAvailability() += this;
bank.audienceForLoad() += this;
Expand All @@ -71,6 +64,7 @@ DENG2_PIMPL(ModelRenderer)
ClientApp::shaders().build(program, "model.skeletal.normal_emission")
<< uMvpMatrix
<< uTex
<< uEyeDir
<< uLightDirs
<< uLightIntensities;

Expand Down Expand Up @@ -157,7 +151,6 @@ DENG2_PIMPL(ModelRenderer)

auto const asset = App::asset(path);

// Prepare the animations for the model.
std::unique_ptr<AuxiliaryData> aux(new AuxiliaryData);

// Determine the coordinate system of the model.
Expand Down Expand Up @@ -211,7 +204,7 @@ DENG2_PIMPL(ModelRenderer)
// TODO: Check for a possible timeline and calculate time factors accordingly.
}

// Store the animation sequence lookup in the bank.
// Store the additional information in the bank.
bank.setUserData(path, aux.release());
}
};
Expand Down Expand Up @@ -246,10 +239,12 @@ ModelRenderer::StateAnims const *ModelRenderer::animations(DotPath const &modelI
return 0;
}

void ModelRenderer::setTransformation(Matrix4f const &modelToLocal, Matrix4f const &localToView)
{
void ModelRenderer::setTransformation(Vector3f const &eyeDir, Matrix4f const &modelToLocal,
Matrix4f const &localToView)
{
d->uMvpMatrix = localToView * modelToLocal;
d->inverseLocal = modelToLocal.inverse();
d->uEyeDir = (d->inverseLocal * eyeDir).normalize();
}

void ModelRenderer::clearLights()
Expand All @@ -258,7 +253,7 @@ void ModelRenderer::clearLights()

for(int i = 0; i < MAX_LIGHTS; ++i)
{
d->uLightDirs .set(i, Vector4f());
d->uLightDirs .set(i, Vector3f());
d->uLightIntensities.set(i, Vector4f());
}
}
Expand All @@ -268,7 +263,7 @@ void ModelRenderer::addLight(Vector3f const &direction, Vector3f const &intensit
if(d->lightCount == MAX_LIGHTS) return;

int idx = d->lightCount;
d->uLightDirs .set(idx, Vector4f((d->inverseLocal * direction).normalize(), 1));
d->uLightDirs .set(idx, (d->inverseLocal * direction).normalize());
d->uLightIntensities.set(idx, Vector4f(intensity, 0));

d->lightCount++;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/render/rend_model.cpp
Expand Up @@ -1162,7 +1162,7 @@ void Rend_DrawModel2(vissprite_t const &spr)
}

// Set up a suitable matrix for the pose.
rend.setTransformation(localMat, viewMat);
rend.setTransformation(vOrigin - spr.pose.mid().xzy(), localMat, viewMat);

// Lighting vectors and ambient color.
rend.clearLights();
Expand Down

0 comments on commit 7f582f7

Please sign in to comment.