static Matrix4<T> LookAtWithVector(const Vector3<T>& eye, const Vector3<T>& lookVector, const Vector3<T>& up) { Vector3<T> z = lookVector.Normalized(); Vector3<T> x = up.Cross(z).Normalized(); Vector3<T> y = z.Cross(x).Normalized(); Matrix4<T> m; m.x = Vector4<T>(x, 0); m.y = Vector4<T>(y, 0); m.z = Vector4<T>(z, 0); m.w = Vector4<T>(0, 0, 0, 1); Vector4<T> eyePrime = m * Vector4<T>(-eye, 1); m = m.Transposed(); m.w = eyePrime; return m; }
static Matrix4<T> Translate(T x, T y, T z) { Matrix4 m; m.x.x = 1; m.x.y = 0; m.x.z = 0; m.x.w = 0; m.y.x = 0; m.y.y = 1; m.y.z = 0; m.y.w = 0; m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0; m.w.x = x; m.w.y = y; m.w.z = z; m.w.w = 1; return m.Transposed(); }
static Matrix4<T> Translate(const Vector3<T>& v) { Matrix4 m; m.x.x = 1; m.x.y = 0; m.x.z = 0; m.x.w = 0; m.y.x = 0; m.y.y = 1; m.y.z = 0; m.y.w = 0; m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0; m.w.x = v.x; m.w.y = v.y; m.w.z = v.z; m.w.w = 1; return m.Transposed(); }
static Matrix4<T> LookAt(const Vector3<T>& eye, const Vector3<T>& target, const Vector3<T>& up) { Vector3<T> z = (eye - target).Normalized(); Vector3<T> x = up.Cross(z).Normalized(); Vector3<T> y = z.Cross(x).Normalized(); Matrix4<T> m; m.x = Vector4<T>(x, 0.0f); m.y = Vector4<T>(y, 0.0f); m.z = Vector4<T>(z, 0.0f); m.w = Vector4<T>(0, 0, 0, 1); Vector4<T> eyePrime = m * Vector4<T>(-eye, 1); m = m.Transposed(); m.w = eyePrime; return m; }
GLColorBuffer GLCameraBlurFilter::Filter(GLColorBuffer input, float radialBlur) { SPADES_MARK_FUNCTION(); if(radialBlur > 0.f) radialBlur = 1.f - radialBlur; else radialBlur = 1.f; bool hasRadialBlur = radialBlur < .9999f; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); dev->Enable(IGLDevice::Blend, false); static GLProgramAttribute programPosition("positionAttribute"); static GLProgramUniform programTexture("texture"); static GLProgramUniform programDepthTexture("depthTexture"); static GLProgramUniform programReverseMatrix("reverseMatrix"); static GLProgramUniform programShutterTimeScale("shutterTimeScale"); programPosition(program); programTexture(program); programDepthTexture(program); programReverseMatrix(program); programShutterTimeScale(program); const client::SceneDefinition& def = renderer->GetSceneDef(); Matrix4 newMatrix = Matrix4::Identity(); newMatrix.m[0] = def.viewAxis[0].x; newMatrix.m[1] = def.viewAxis[1].x; newMatrix.m[2] = def.viewAxis[2].x; newMatrix.m[4] = def.viewAxis[0].y; newMatrix.m[5] = def.viewAxis[1].y; newMatrix.m[6] = def.viewAxis[2].y; newMatrix.m[8] = def.viewAxis[0].z; newMatrix.m[9] = def.viewAxis[1].z; newMatrix.m[10] = def.viewAxis[2].z; // othrogonal matrix can be reversed fast Matrix4 inverseNewMatrix = newMatrix.Transposed(); Matrix4 diffMatrix = prevMatrix * inverseNewMatrix; prevMatrix = newMatrix; Matrix4 reverseMatrix = ReverseMatrix(diffMatrix); if(diffMatrix.m[0] < .3f || diffMatrix.m[5] < .3f || diffMatrix.m[10] < .3f){ // too much change if(hasRadialBlur) { diffMatrix = Matrix4::Identity(); }else{ // skip blur return input; } } float movePixels = MyACos(diffMatrix.m[0]); float shutterTimeScale = .3f; movePixels = std::max(movePixels, MyACos(diffMatrix.m[5])); movePixels = std::max(movePixels, MyACos(diffMatrix.m[10])); movePixels = tanf(movePixels) / tanf(def.fovX * .5f); movePixels *= (float)dev->ScreenWidth() * .5f; movePixels *= shutterTimeScale; movePixels = std::max(movePixels, (1.f - radialBlur) * dev->ScreenWidth() * 0.5f); if(movePixels < 1.f){ // too less change, skip camera blur return input; } int levels = (int)ceilf(logf(movePixels) / logf(5.f)); if(levels <= 0) levels = 1; if(hasRadialBlur) radialBlur *= radialBlur; reverseMatrix = Matrix4::Scale(radialBlur, radialBlur, 1.f) * reverseMatrix; program->Use(); programTexture.SetValue(0); programDepthTexture.SetValue(1); programReverseMatrix.SetValue(reverseMatrix); // composite to the final image GLColorBuffer buf = input; qr.SetCoordAttributeIndex(programPosition()); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, renderer->GetFramebufferManager()->GetDepthTexture()); dev->ActiveTexture(0); for(int i = 0; i < levels; i++){ GLProfiler measure(dev, "Apply [%d / %d]", i+1,levels); GLColorBuffer output = input.GetManager()->CreateBufferHandle(); programShutterTimeScale.SetValue(shutterTimeScale); dev->BindTexture(IGLDevice::Texture2D, buf.GetTexture()); dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer()); dev->Viewport(0, 0, output.GetWidth(), output.GetHeight()); qr.Draw(); dev->BindTexture(IGLDevice::Texture2D, 0); shutterTimeScale /= 5.f; buf = output; } dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, 0); dev->ActiveTexture(0); return buf; }