sRGBAfloat cRenderWorker::EnvMapping(const sShaderInputData &input) { sRGBAfloat envReflect; CVector3 reflect; double dot = -input.viewVector.Dot(input.normal); reflect = input.normal * 2.0 * dot + input.viewVector; double alphaTexture = reflect.GetAlpha() + M_PI; double betaTexture = reflect.GetBeta(); double texWidth = data->textures.envmapTexture.Width(); double texHeight = data->textures.envmapTexture.Height(); if (betaTexture > 0.5 * M_PI) betaTexture = 0.5 * M_PI - betaTexture; if (betaTexture < -0.5 * M_PI) betaTexture = -0.5 * M_PI + betaTexture; double dtx = (alphaTexture / (2.0 * M_PI)) * texWidth + texWidth * 8.25; double dty = (betaTexture / (M_PI) + 0.5) * texHeight + texHeight * 8.0; dtx = fmod(dtx, texWidth); dty = fmod(dty, texHeight); if (dtx < 0) dtx = 0; if (dty < 0) dty = 0; envReflect.R = data->textures.envmapTexture.Pixel(dtx, dty).R / 256.0; envReflect.G = data->textures.envmapTexture.Pixel(dtx, dty).G / 256.0; envReflect.B = data->textures.envmapTexture.Pixel(dtx, dty).B / 256.0; return envReflect; }
sRGBAfloat cRenderWorker::EnvMapping(const sShaderInputData &input) { sRGBAfloat envReflect; CVector3 reflect; double dot = -input.viewVector.Dot(input.normal); reflect = input.normal * 2.0 * dot + input.viewVector; double alphaTexture = -reflect.GetAlpha() + M_PI; double betaTexture = -reflect.GetBeta(); double texWidth = data->textures.envmapTexture.Width(); double texHeight = data->textures.envmapTexture.Height(); if (betaTexture > 0.5 * M_PI) betaTexture = 0.5 * M_PI - betaTexture; if (betaTexture < -0.5 * M_PI) betaTexture = -0.5 * M_PI + betaTexture; double dtx = (alphaTexture / (2.0 * M_PI)) * texWidth + texWidth * 8.25; double dty = (betaTexture / (M_PI) + 0.5) * texHeight + texHeight * 8.0; dtx = fmod(dtx, texWidth); dty = fmod(dty, texHeight); if (dtx < 0) dtx = 0; if (dty < 0) dty = 0; double reflectance = 1.0; if (input.material->fresnelReflectance) { double n1 = 1.0; double n2 = input.material->transparencyIndexOfRefraction; reflectance = Reflectance(input.normal, input.viewVector, n1, n2); if (reflectance < 0.0) reflectance = 0.0; if (reflectance > 1.0) reflectance = 1.0; } envReflect.R = data->textures.envmapTexture.Pixel(dtx, dty).R * reflectance; envReflect.G = data->textures.envmapTexture.Pixel(dtx, dty).G * reflectance; envReflect.B = data->textures.envmapTexture.Pixel(dtx, dty).B * reflectance; return envReflect; }
CVector2<double> TextureMapping(CVector3 inPoint, CVector3 normalVector, const cObjectData &objectData, const cMaterial *material, CVector3 *textureVectorX, CVector3 *textureVectorY) { CVector2<double> textureCoordinates; CVector3 point = inPoint - objectData.position; point = objectData.rotationMatrix.RotateVector(point); point /= objectData.size; point = material->rotMatrix.RotateVector(point); switch (material->textureMappingType) { case cMaterial::mappingPlanar: { textureCoordinates = CVector2<double>(point.x, point.y); textureCoordinates.x /= -material->textureScale.x; textureCoordinates.y /= material->textureScale.y; textureCoordinates.x -= material->textureCenter.x; textureCoordinates.y -= material->textureCenter.y; if (textureVectorX && textureVectorY) { CVector3 texX(1.0, 0.0, 0.0); texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; CVector3 texY(0.0, -1.0, 0.0); texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } case cMaterial::mappingCylindrical: { double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI); textureCoordinates.x = alphaTexture / (2.0 * M_PI); textureCoordinates.y = -point.z; textureCoordinates.x /= material->textureScale.x; textureCoordinates.y /= material->textureScale.y; textureCoordinates.x -= material->textureCenter.x; textureCoordinates.y -= material->textureCenter.y; if (textureVectorX && textureVectorY) { CVector3 texY(0.0, 0.0, 1.0); CVector3 texX = point.Cross(texY); texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } case cMaterial::mappingSpherical: { double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI); double betaTexture = -point.GetBeta(); textureCoordinates.x = alphaTexture / (2.0 * M_PI); textureCoordinates.y = (betaTexture / M_PI); textureCoordinates.x /= material->textureScale.x; textureCoordinates.y /= material->textureScale.y; textureCoordinates.x -= material->textureCenter.x; textureCoordinates.y -= material->textureCenter.y; CVector3 texY(0.0, 0.0, -1.0); CVector3 texX = texY.Cross(point); texX.Normalize(); texY = texX.Cross(point); if (textureVectorX && textureVectorY) { texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } case cMaterial::mappingCubic: { point /= material->textureScale; point -= material->textureCenter; CVector3 texX, texY; if (fabs(normalVector.x) > fabs(normalVector.y)) { if (fabs(normalVector.x) > fabs(normalVector.z)) { // x if (normalVector.x > 0) textureCoordinates = CVector2<double>(point.y, -point.z); else textureCoordinates = CVector2<double>(-point.y, -point.z); if (textureVectorX && textureVectorY) { if (normalVector.x > 0) { texX = CVector3(0.0, -1.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } else { texX = CVector3(0.0, 1.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } } } else { // z if (normalVector.z > 0) textureCoordinates = CVector2<double>(-point.x, point.y); else textureCoordinates = CVector2<double>(point.x, point.y); if (textureVectorX && textureVectorY) { if (normalVector.z > 0) { texX = CVector3(1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } else { texX = CVector3(-1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } } } } else { if (fabs(normalVector.y) > fabs(normalVector.z)) { // y if (normalVector.y > 0) textureCoordinates = CVector2<double>(-point.x, -point.z); else textureCoordinates = CVector2<double>(point.x, -point.z); if (textureVectorX && textureVectorY) { if (normalVector.y > 0) { texX = CVector3(1.0, 0.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } else { texX = CVector3(-1.0, 0.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } } } else { // z if (normalVector.z > 0) textureCoordinates = CVector2<double>(-point.x, point.y); else textureCoordinates = CVector2<double>(point.x, point.y); if (textureVectorX && textureVectorY) { if (normalVector.z > 0) { texX = CVector3(1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } else { texX = CVector3(-1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } } } } if (textureVectorX && textureVectorY) { texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } } return textureCoordinates; }