public IrrlichtNETCP.Vector3D CalculateSphericalCameraCoordinates(IrrlichtNETCP.Vector3D camPos, IrrlichtNETCP.Vector3D targetPos) { float xCamRotationAnglePHI, xCamRotationAngleTHETA; IrrlichtNETCP.Vector3D result = new IrrlichtNETCP.Vector3D(); // result is spherical coordinates as a 3D vector in (radius, theta, phi) order IrrlichtNETCP.Vector3D relCamPos = camPos - targetPos; float camDistance = (float)Math.Sqrt(relCamPos.DotProduct(relCamPos)); xCamRotationAnglePHI = 0.5f * (float)Math.PI - (float)Math.Asin((double)(relCamPos.Y / camDistance)); if (xCamRotationAnglePHI < 0.0) { xCamRotationAnglePHI += 2.0f * (float)Math.PI; } if (Math.Abs(relCamPos.X) > 0.0) { xCamRotationAngleTHETA = (float)Math.Atan((double)(relCamPos.Z / relCamPos.X)); if (relCamPos.X < 0.0f) { xCamRotationAngleTHETA += (float)Math.PI; } if (xCamRotationAngleTHETA < 0.0) { xCamRotationAngleTHETA += 2.0f * (float)Math.PI; } } else { if (relCamPos.Z > 0) { xCamRotationAngleTHETA = 0.5f * (float)Math.PI; // 90 deg } else { xCamRotationAngleTHETA = 1.5f * (float)Math.PI; // 270 deg } } result.Set(camDistance, xCamRotationAngleTHETA, xCamRotationAnglePHI); return result; }
public override void ShaderEvent(IrrlichtNETCP.MaterialRendererServices services, int userData) { base.ShaderEvent(services, userData); }
public override void ShaderEvent(IrrlichtNETCP.MaterialRendererServices services, int userData) { if (updateOnce) { return; } else { updateOnce = true; } if (Reference.Viewer.SkyQuality == Viewer.ShaderLevelType.High) { Matrix4 worldViewProj = Reference.VideoDriver.GetTransform(TransformationState.Projection); worldViewProj *= Reference.VideoDriver.GetTransform(TransformationState.View); worldViewProj *= Reference.VideoDriver.GetTransform(TransformationState.World); services.SetVertexShaderConstant("WVPMatrix", worldViewProj.ToShader()); } Vector3D camPos, camPosXZ; camPosXZ = camPos = new Vector3D(Reference.Viewer.Camera.Position.X, Reference.Viewer.Camera.Position.Y, Reference.Viewer.Camera.Position.Z); camPosXZ.Y = 0f; //// Sun position calculation SkyMaths.AltAzAngles sunAngles = SkyMaths.CalculateSunPosition(julianDay + (float)worldTime.TimeOfDay.TotalDays, LATITUDE); sunPosition = SkyMaths.MoveAroundPoint(camPosXZ, 12500f, sunAngles.azimuth, -sunAngles.altitude); if (sunNode != null) sunNode.Position = sunPosition * 0.4f; //// Moon position (approximate inverse of the sun, l0lz.) moonPosition = sunPosition; moonPosition.X *= -1.0f; moonPosition.Y *= -1.0f; moonPosition.Z *= -1.0f; moonPosition = moonPosition.Normalize(); if (moonNode != null) moonNode.Position = moonPosition * 9000.0f; // Set the sun normalized vector and the sunTheta to the shader Vector3D sunNormedPos = new Vector3D(); sunNormedPos = sunPosition - camPosXZ; sunNormedPos = sunNormedPos.Normalize(); float sunTheta = SkyMaths.VectorToTheta(sunNormedPos); // Sun lightning direction Vector3D sunDirection = new Vector3D(); sunDirection = sunPosition - camPosXZ; sunDirection = sunDirection.Normalize(); // Stars and moon opacity moonIntensity = SkyMaths.Saturate(SkyMaths.Lerp(sunAngles.altitude, 0f, SUN_SET)) * 0.95f; moonIntensity += 0.05f; // A hack to kill the orange tones in the nightsky float darkness = 1f - (moonIntensity - 0.05f); // Calculate the constant matrices SkyMaths.xyYColor _zenithColors = SkyMaths.SkyZenithColor(turbidity, sunTheta); Vector3D _zenithColorsVector = new Vector3D(_zenithColors.x, _zenithColors.y, _zenithColors.Y); SkyMaths.xyYCoeffs _distribCoeffs = SkyMaths.DistributionCoefficients(turbidity); if (Reference.Viewer.SkyQuality == Viewer.ShaderLevelType.High) { services.SetVertexShaderConstant("SunTheta", sunTheta); services.SetVertexShaderConstant("SunVector", sunNormedPos.ToShader()); services.SetVertexShaderConstant("NightDarkness", darkness); services.SetVertexShaderConstant("ZenithColor", _zenithColorsVector.ToShader()); for (int i = 0; i < 5; i++) { services.SetVertexShaderConstant("_xDistribCoeffs[" + i + "]", _distribCoeffs.x[i]); services.SetVertexShaderConstant("_yDistribCoeffs[" + i + "]", _distribCoeffs.y[i]); services.SetVertexShaderConstant("_YDistribCoeffs[" + i + "]", _distribCoeffs.Y[i]); } // Set the adaptative luminance and gamma corrections float gamma = 1f / (1.6f + (turbidity - 2f) * 0.1f); services.SetVertexShaderConstant("InvGammaCorrection", 1.5f * gamma); services.SetVertexShaderConstant("InvPowLumFactor", gamma); services.SetVertexShaderConstant("InvNegMaxLum", -1.25f / SkyMaths.MaximumLuminance(turbidity, sunTheta, _zenithColors, _distribCoeffs)); float calcAlpha = ((12 - 1) * 60 * 60 + (60 - 1) * 60 + 60) - ((worldTime.Hour - 1) * 60 * 60 + (worldTime.Minute - 1) * 60 + worldTime.Second); calcAlpha = 1 - Math.Abs(calcAlpha) / cloudChangeSec; calcAlpha = Util.Clamp<float>(calcAlpha, 0, 1); calcAlpha = calcAlpha * calcAlpha; float minAlpha = 0.05f; calcAlpha = (calcAlpha * 1.5f) + minAlpha; calcAlpha = Util.Clamp<float>(calcAlpha, 0, 1); services.SetPixelShaderConstant("CloudAlpha", calcAlpha); services.SetPixelShaderConstant("BlendingRate", 0); } // Clouds coloring float[] atmoCol = SkyMaths.AtmosphereColor(turbidity, sunTheta, _zenithColors, _distribCoeffs); Vector3D atmoColVec = new Vector3D(atmoCol[0], atmoCol[1], atmoCol[2]); float dayState = SkyMaths.Saturate(SkyMaths.Lerp(sunAngles.altitude, (float)(Math.PI * 1f / (6f - turbidity / 2f)), SUN_RISE)); // Sun lightning intensity float sunIntensity = SkyMaths.Saturate(SkyMaths.Lerp(sunAngles.altitude, SUN_SET, SUN_RISE)); base.ShaderEvent(services, userData); }