#Specular highlight follows the camera rotation

2 messages · Page 1 of 1 (latest)

jade herald
#

I put some code for reference:

  • This is how I calculate the transforms and pass the vectors/quaternions to the vertex shader
namespace RendererUtils {
Transform CumulateTransforms(const Transform& firstTransform, const Transform& otherTransform) {
    const auto position{firstTransform.Rotation * (otherTransform.Position * firstTransform.Scale) + firstTransform.Position};
    const auto rotation{firstTransform.Rotation * otherTransform.Rotation};
    const auto scale{firstTransform.Scale * otherTransform.Scale};

    return Transform{position, rotation, scale};
}

Transform InvertTransform(const Transform& transform) {
    const auto scale{1.f / transform.Scale};
    const auto rotation{glm::inverse(transform.Rotation)};
    const auto position{rotation * (-transform.Position * scale)};

    return Transform{position, rotation, scale};
}
}
RendererUtils::Transform RendererSystem::_calculateViewTransform(const RendererUtils::Transform& transform, const RendererUtils::Transform& cameraTransform) {
    const auto inverseCameraTransform{RendererUtils::InvertTransform(cameraTransform)};

    return RendererUtils::CumulateTransforms(transform, inverseCameraTransform);
}
void RendererSystem::_drawMesh(const Mesh& mesh, const RendererUtils::Transform& meshTransform, const RendererUtils::Transform& cameraTransform) {
    const auto viewTransform{_calculateViewTransform(meshTransform, cameraTransform)};

    assert(_shader);
    _shader->SetUniformVec3("ViewPosition", viewTransform.Position);
    _shader->SetUniformQuat("ViewRotation", viewTransform.Rotation);
    _shader->SetUniformFloat("Scale", viewTransform.Scale);

    _shader->SetBool("HasTextureDiffuse", mesh.GetHasTextureDiffuse());
    _shader->SetBool("HasTextureSpecular", mesh.GetHasTextureSpecular());

    ...
}
#

This is the vertex shader:

#version 460 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (location = 2) in vec3 aNormal;
  
out vec2 TexCoord;
out vec3 FragViewPosition;
out vec3 NormalViewPosition;

uniform vec3 ViewPosition;
uniform vec4 ViewRotation;
uniform float Scale;

uniform mat4 Perspective;

vec3 rotateVectorByQuaternion(vec4 quaternion, vec3 vector);

void main() {
    TexCoord = aTexCoord;

    NormalViewPosition = rotateVectorByQuaternion(ViewRotation, aNormal).xyz;
    vec3 scaledPosition = vec3(aPos.x * Scale, aPos.y * Scale, aPos.z * Scale);
    FragViewPosition = rotateVectorByQuaternion(ViewRotation, scaledPosition).xyz + ViewPosition;

    gl_Position = Perspective * vec4(FragViewPosition, 1.0);
}

vec4 quatMultiply(vec4 first, vec4 second) {
    const float q1x = first.x;
    const float q1y = first.y;
    const float q1z = first.z;
    const float q1w = first.w;

    const float q2x = second.x;
    const float q2y = second.y;
    const float q2z = second.z;
    const float q2w = second.w;

    return vec4(q1w * q2x + q1x * q2w + q1y * q2z - q1z * q2y,
                q1w * q2y + q1y * q2w + q1z * q2x - q1x * q2z,
                q1w * q2z + q1z * q2w + q1x * q2y - q1y * q2x,
                q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z);
}

vec3 rotateVectorByQuaternion(vec4 quaternion, vec3 vector) {
    vec4 quatConj = vec4(-quaternion.x, -quaternion.y, -quaternion.z, quaternion.w);
    vec4 quatPoint = vec4(vector, 0.0);

    vec4 partialQuatMultiply = quatMultiply(quaternion, quatPoint);
    vec4 result = quatMultiply(partialQuatMultiply, quatConj);

    return result.xyz;
}