private void CameraPreCull(Camera camera) { // Write these once to save CPU if (renderedThisFrame == false && material != null) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); SgtLight.Write(Lit, transform.position, null, null, 1.0f, 1); SgtShadow.Write(Lit, gameObject, 1); } if (CameraOffset != 0.0f) { if (model != null) { model.Revert(); { if (CameraOffset != 0.0f) { var direction = transform.position - camera.transform.position; model.transform.position += direction.normalized * CameraOffset; } } model.Save(camera); } } }
protected void CameraPreRender(Camera camera) { if (material != null) { var observer = default(SgtCamera); if (SgtCamera.TryFind(camera, ref observer) == true) { material.SetFloat("_CameraRollAngle", observer.RollAngle * Mathf.Deg2Rad); } else { material.SetFloat("_CameraRollAngle", 0.0f); } // Write these once to save CPU if (renderedThisFrame == false && material != null) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); SgtLight.Write(Lit, transform.position, transform, null, 1.0f, 2); SgtShadow.Write(Lit, gameObject, 2); } } }
public override void CalculateShadow(SgtLight light) { var direction = default(Vector3); var position = default(Vector3); var color = default(Color); SgtLight.Calculate(light, transform.position, null, null, ref position, ref direction, ref color); var dot = Vector3.Dot(direction, transform.up); var radiusXZ = (transform.lossyScale.x + transform.lossyScale.z) * 0.5f * RadiusMax; var radiusY = transform.lossyScale.y * RadiusMax; var radius = GetRadius(radiusY, radiusXZ, dot * Mathf.PI * 0.5f); var rotation = Quaternion.FromToRotation(direction, Vector3.back); var vector = rotation * transform.up; var spin = Quaternion.LookRotation(Vector3.forward, new Vector2(-vector.x, vector.y)); // Orient the shadow ellipse var scale = SgtHelper.Reciprocal3(new Vector3(radiusXZ, radius, 1.0f)); var shadowT = Matrix4x4.Translate(-transform.position); var shadowR = Matrix4x4.Rotate(spin * rotation); var shadowS = Matrix4x4.Scale(scale); cachedActive = true; cachedMatrix = shadowS * shadowR * shadowT; cachedRatio = SgtHelper.Divide(RadiusMax, RadiusMax - RadiusMin); cachedRadius = SgtHelper.UniformScale(transform.lossyScale) * RadiusMax; cachedTexture = generatedTexture; }
private void CameraPreRender(Camera camera) { if (model != null) { model.Restore(camera); } // Write these once to save CPU if (renderedThisFrame == false) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(Lit, mask); SgtShadow.Find(Lit, mask, lights); SgtShadow.FilterOutSphere(transform.position); SgtShadow.Write(Lit, 2); SgtLight.FilterOut(transform.position); SgtLight.Write(Lit, transform.position, null, null, 1.0f, 2); } }
public override bool CalculateShadow(ref Matrix4x4 matrix, ref float ratio) { var light = default(SgtLight); if (SgtLight.Find(ref light) == true) { var direction = default(Vector3); var position = default(Vector3); var color = default(Color); SgtLight.Calculate(light.CachedLight, transform.position, null, null, ref position, ref direction, ref color); var dot = Vector3.Dot(direction, transform.up); var radiusXZ = (transform.lossyScale.x + transform.lossyScale.z) * 0.5f * RadiusMax; var radiusY = transform.lossyScale.y * RadiusMax; var radius = GetRadius(radiusY, radiusXZ, dot * Mathf.PI * 0.5f); var rotation = Quaternion.FromToRotation(direction, Vector3.back); var vector = rotation * transform.up; var spin = Quaternion.LookRotation(Vector3.forward, new Vector2(-vector.x, vector.y)); // Orient the shadow ellipse var scale = SgtHelper.Reciprocal3(new Vector3(radiusXZ, radius, 1.0f)); var shadowT = SgtHelper.Translation(-transform.position); var shadowR = SgtHelper.Rotation(spin * rotation); var shadowS = SgtHelper.Scaling(scale); matrix = shadowS * shadowR * shadowT; ratio = SgtHelper.Divide(RadiusMax, RadiusMax - RadiusMin); return(true); } return(false); }
public override void CalculateShadow(SgtLight light) { if (Texture != null) { var direction = default(Vector3); var position = default(Vector3); var color = default(Color); SgtLight.Calculate(light, transform.position, null, null, ref position, ref direction, ref color); var rotation = Quaternion.FromToRotation(direction, Vector3.back); var squash = Vector3.Dot(direction, transform.up); // Find how squashed the ellipse is based on light direction var width = transform.lossyScale.x * RadiusMax; var length = transform.lossyScale.z * RadiusMax; var axis = rotation * transform.up; // Find the transformed up axis var spin = Quaternion.LookRotation(Vector3.forward, new Vector2(-axis.x, axis.y)); // Orient the shadow ellipse var scale = SgtHelper.Reciprocal3(new Vector3(width, length * Mathf.Abs(squash), 1.0f)); var skew = Mathf.Tan(SgtHelper.Acos(-squash)); var shadowT = Matrix4x4.Translate(-transform.position); var shadowR = Matrix4x4.Rotate(spin * rotation); // Spin the shadow so lines up with its tilt var shadowS = Matrix4x4.Scale(scale); // Scale the ring into an oval var shadowK = SgtHelper.ShearingZ(new Vector2(0.0f, skew)); // Skew the shadow so it aligns with the ring plane cachedActive = true; cachedMatrix = shadowS * shadowK * shadowR * shadowT; cachedRatio = SgtHelper.Divide(RadiusMax, RadiusMax - RadiusMin); cachedRadius = SgtHelper.UniformScale(transform.lossyScale) * RadiusMax; cachedTexture = Texture; } else { cachedActive = false; } }
public override bool CalculateShadow(ref Matrix4x4 matrix, ref float ratio) { var light = default(SgtLight); if (Texture != null && SgtLight.Find(ref light) == true) { var direction = default(Vector3); var position = default(Vector3); var color = default(Color); SgtLight.Calculate(light.CachedLight, transform.position, null, null, ref position, ref direction, ref color); var rotation = Quaternion.FromToRotation(direction, Vector3.back); var squash = Vector3.Dot(direction, transform.up); // Find how squashed the ellipse is based on light direction var width = transform.lossyScale.x * RadiusMax; var length = transform.lossyScale.z * RadiusMax; var axis = rotation * transform.up; // Find the transformed up axis var spin = Quaternion.LookRotation(Vector3.forward, new Vector2(-axis.x, axis.y)); // Orient the shadow ellipse var scale = SgtHelper.Reciprocal3(new Vector3(width, length * Mathf.Abs(squash), 1.0f)); var skew = Mathf.Tan(SgtHelper.Acos(-squash)); var shadowT = SgtHelper.Translation(-transform.position); var shadowR = SgtHelper.Rotation(spin * rotation); // Spin the shadow so lines up with its tilt var shadowS = SgtHelper.Scaling(scale); // Scale the ring into an oval var shadowK = SgtHelper.ShearingZ(new Vector2(0.0f, skew)); // Skew the shadow so it aligns with the ring plane matrix = shadowS * shadowK * shadowR * shadowT; ratio = SgtHelper.Divide(RadiusMax, RadiusMax - RadiusMin); return(true); } return(false); }
private float GetSky(Camera camera) { if (Lit == true && Night == true) { var mask = 1 << gameObject.layer; var lights = SgtLight.Find(Lit, mask); var lighting = 0.0f; var cameraDirection = (camera.transform.position - transform.position).normalized; for (var i = 0; i < lights.Count && i < 2; i++) { var light = lights[i]; var position = default(Vector3); var direction = default(Vector3); var color = default(Color); SgtLight.Calculate(light, transform.position, null, null, ref position, ref direction, ref color); var dot = Vector3.Dot(direction, cameraDirection) * 0.5f + 0.5f; var night01 = Mathf.InverseLerp(NightEnd, NightStart, dot); var night = SgtEase.Evaluate(NightEase, 1.0f - Mathf.Pow(night01, NightPower)); if (night > lighting) { lighting = night; } } return(Mathf.Lerp(NightSky, Sky, lighting)); } return(Sky); }
protected virtual void LateUpdate() { if (dirtyMaterial == true) { UpdateMaterial(); dirtyMaterial = false; } // Write lights and shadows SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(lit, mask, transform.position); SgtLight.FilterOut(transform.position); SgtShadow.Find(lit, mask, lights); SgtShadow.FilterOutSphere(transform.position); SgtShadow.Write(lit, 2); SgtLight.Write(lit, transform.position, transform, null, scatteringStrength, 2); // Write matrices var scale = radius; var localToWorld = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(scale, scale, scale)); // Double mesh radius so the max thickness caps at 1.0 material.SetMatrix(SgtShader._WorldToLocal, localToWorld.inverse); material.SetMatrix(SgtShader._LocalToWorld, localToWorld); }
protected virtual void LateUpdate() { // Write lights and shadows SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(lit, mask, transform.position); SgtShadow.Find(lit, mask, lights); SgtShadow.FilterOutRing(transform.position); SgtShadow.Write(lit, 2); SgtLight.FilterOut(transform.position); SgtLight.Write(lit, transform.position, null, null, scatteringStrength, 2); // Update scrolling? if (detail == true) { if (Application.isPlaying == true) { detailOffset += detailSpeed * Time.deltaTime; } if (material != null) { material.SetVector(SgtShader._DetailOffset, detailOffset); } } }
protected virtual void LateUpdate() { if (generatedMesh == null || dirtyMesh == true) { Rebuild(); } if (generatedMesh != null && material != null) { Properties.SetFloat(SgtShader._WaterLevel, waterLevel); // Write direction of nearest light? if (material.GetFloat("_HasNight") == 1.0f) { var mask = 1 << gameObject.layer; var lights = SgtLight.Find(true, mask, transform.position); SgtLight.FilterOut(transform.position); if (lights.Count > 0) { var position = Vector3.zero; var direction = Vector3.forward; var color = Color.white; SgtLight.Calculate(lights[0], transform.position, default(Transform), default(Transform), ref position, ref direction, ref color); properties.SetVector(Shader.PropertyToID("_NightDirection"), -direction); } } } }
protected virtual void LateUpdate() { // The lights and shadows may have moved, so write them if (innerMaterial != null && outerMaterial != null) { SgtHelper.SetTempMaterial(innerMaterial, outerMaterial); SgtLight.Write(Lit, transform.position, transform, null, ScatteringStrength, 2); SgtShadow.Write(Lit, gameObject, 2); } }
private void CameraPreRender(Camera camera) { if (model != null) { model.Restore(camera); } // Write camera-dependant shader values if (innerMaterial != null && outerMaterial != null) { var localPosition = cachedTransform.InverseTransformPoint(camera.transform.position); var localDistance = localPosition.magnitude; var height01 = Mathf.InverseLerp(OuterRadius, InnerMeshRadius, localDistance); var innerThickness = default(float); var outerThickness = default(float); var innerRatio = SgtHelper.Divide(InnerMeshRadius, OuterRadius); var middleRatio = Mathf.Lerp(innerRatio, 1.0f, Middle); var distance = SgtHelper.Divide(localDistance, OuterRadius); var innerDensity = 1.0f - InnerFog; var outerDensity = 1.0f - OuterFog; SgtHelper.CalculateHorizonThickness(innerRatio, middleRatio, distance, out innerThickness, out outerThickness); innerMaterial.SetFloat(SgtShader._HorizonLengthRecip, SgtHelper.Reciprocal(innerThickness * innerDensity)); outerMaterial.SetFloat(SgtShader._HorizonLengthRecip, SgtHelper.Reciprocal(outerThickness * outerDensity)); if (OuterDepthTex != null) { #if UNITY_EDITOR SgtHelper.MakeTextureReadable(OuterDepthTex); #endif outerMaterial.SetFloat(SgtShader._Sky, GetSky(camera) * OuterDepthTex.GetPixelBilinear(height01 / outerDensity, 0.0f).a); } var scale = SgtHelper.Divide(OuterMeshRadius, OuterRadius); var worldToLocal = Matrix4x4.Scale(new Vector3(scale, scale, scale)) * cachedTransform.worldToLocalMatrix; // cachedTransform might not be set here, so use the property innerMaterial.SetMatrix(SgtShader._WorldToLocal, worldToLocal); outerMaterial.SetMatrix(SgtShader._WorldToLocal, worldToLocal); // Write lights and shadows SgtHelper.SetTempMaterial(innerMaterial, outerMaterial); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(Lit, mask); SgtShadow.Find(Lit, mask, lights); SgtShadow.FilterOutSphere(transform.position); SgtShadow.Write(Lit, 2); SgtLight.FilterOut(transform.position); SgtLight.Write(Lit, transform.position, cachedTransform, null, ScatteringStrength, 2); } }
private void CameraPreRender(Camera camera) { // Write these once to save CPU if (renderedThisFrame == false && material != null) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); SgtLight.Write(Lit, transform.position, null, null, ScatteringStrength, 2); SgtShadow.Write(Lit, gameObject, 2); } }
protected virtual void CameraPreRender(Camera camera) { if (material != null) { SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(true, mask, transform.position); SgtShadow.Find(true, mask, lights); SgtShadow.FilterOutSphere(transform.position); SgtShadow.FilterOutMiss(transform.position, SgtHelper.UniformScale(transform.lossyScale) * Radius); SgtShadow.Write(true, 2); } }
protected virtual void LateUpdate() { // Write lights and shadows SgtHelper.SetTempMaterial(generatedMaterial); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(lit, mask, cachedTransform.position); SgtShadow.Find(lit, mask, lights); SgtShadow.FilterOutSphere(cachedTransform.position); SgtShadow.Write(lit, 2); SgtLight.FilterOut(cachedTransform.position); SgtLight.Write(lit, cachedTransform.position, null, null, 1.0f, 2); }
private void CameraPreRender(Camera camera) { if (material != null) { var cameraPosition = camera.transform.position; var localCameraPosition = transform.InverseTransformPoint(cameraPosition); var localDistance = localCameraPosition.magnitude; var scaleDistance = SgtHelper.Divide(localDistance, Radius); if (scaleDistance > 1.0f) { SgtHelper.EnableKeyword("SGT_A", material); // Outside } else { SgtHelper.DisableKeyword("SGT_A", material); // Outside if (DepthTex != null) { #if UNITY_EDITOR SgtHelper.MakeTextureReadable(DepthTex); #endif material.SetFloat("_Sky", Sky * DepthTex.GetPixelBilinear(1.0f - scaleDistance, 0.0f).a); } } // Write these once to save CPU if (renderedThisFrame == false) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); SgtLight.Write(Lit, transform.position, transform, null, ScatteringStrength, 2); SgtShadow.Write(Lit, gameObject, 2); // Write matrices var localToWorld = transform.localToWorldMatrix * SgtHelper.Scaling(Radius * 2.0f); // Double mesh radius so the max thickness caps at 1.0 material.SetMatrix("_WorldToLocal", localToWorld.inverse); material.SetMatrix("_LocalToWorld", localToWorld); } } }
private void CameraPreRender(Camera camera) { if (material != null) { var cameraPosition = camera.transform.position; var localCameraPosition = transform.InverseTransformPoint(cameraPosition); var localDistance = localCameraPosition.magnitude; var scaleDistance = SgtHelper.Divide(localDistance, Radius); if (DepthTex != null) { #if UNITY_EDITOR SgtHelper.MakeTextureReadable(DepthTex); #endif material.SetFloat(SgtShader._Sky, Sky * DepthTex.GetPixelBilinear(1.0f - scaleDistance, 0.0f).a); } // Write these once to save CPU if (renderedThisFrame == false) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(Lit, mask, transform.position); SgtLight.FilterOut(transform.position); SgtShadow.Find(Lit, mask, lights); SgtShadow.FilterOutSphere(transform.position); SgtShadow.Write(Lit, 2); SgtLight.Write(Lit, transform.position, transform, null, ScatteringStrength, 2); // Write matrices var scale = Radius; var localToWorld = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(scale, scale, scale)); // Double mesh radius so the max thickness caps at 1.0 material.SetMatrix(SgtShader._WorldToLocal, localToWorld.inverse); material.SetMatrix(SgtShader._LocalToWorld, localToWorld); } } }
protected virtual void OnDrawGizmosSelected() { var mask = 1 << gameObject.layer; var lights = SgtLight.Find(true, mask); if (SgtHelper.Enabled(this) == true && lights.Count > 0) { CalculateShadow(lights[0]); if (cachedActive == true) { Gizmos.matrix = cachedMatrix.inverse; var distA = 0.0f; var distB = 1.0f; var scale = 1.0f * Mathf.Deg2Rad; var inner = SgtHelper.Divide(RadiusMin, RadiusMax); for (var i = 1; i < 10; i++) { var posA = new Vector3(0.0f, 0.0f, distA); var posB = new Vector3(0.0f, 0.0f, distB); Gizmos.color = new Color(1.0f, 1.0f, 1.0f, Mathf.Pow(0.75f, i) * 0.125f); for (var a = 1; a <= 360; a++) { posA.x = posB.x = Mathf.Sin(a * scale); posA.y = posB.y = Mathf.Cos(a * scale); Gizmos.DrawLine(posA, posB); posA.x = posB.x = posA.x * inner; posA.y = posB.y = posA.y * inner; Gizmos.DrawLine(posA, posB); } distA = distB; distB = distB * 2.0f; } } } }
protected virtual void LateUpdate() { var scale = SgtHelper.Divide(outerMeshRadius, OuterRadius); var worldToLocal = Matrix4x4.Scale(new Vector3(scale, scale, scale)) * cachedTransform.worldToLocalMatrix; innerMaterial.SetMatrix(SgtShader._WorldToLocal, worldToLocal); outerMaterial.SetMatrix(SgtShader._WorldToLocal, worldToLocal); // Write lights and shadows SgtHelper.SetTempMaterial(innerMaterial, outerMaterial); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(lit, mask, cachedTransform.position); SgtShadow.Find(lit, mask, lights); SgtShadow.FilterOutSphere(cachedTransform.position); SgtShadow.Write(lit, 2); SgtLight.FilterOut(cachedTransform.position); SgtLight.Write(lit, cachedTransform.position, cachedTransform, null, scatteringStrength, 2); }
private void CameraPreRender(Camera camera) { // Write these once to save CPU if (renderedThisFrame == false && material != null) { renderedThisFrame = true; // Write lights and shadows SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(Lit, mask); SgtShadow.Find(Lit, mask, lights); SgtShadow.FilterOutRing(transform.position); SgtShadow.Write(Lit, mask, 2); SgtLight.FilterOut(transform.position); SgtLight.Write(Lit, transform.position, null, null, ScatteringStrength, 2); } }
protected override void LateUpdate() { base.LateUpdate(); if (Application.isPlaying == true) { orbitOffset += Time.deltaTime * orbitSpeed; } material.SetFloat(SgtShader._Age, orbitOffset); // Write lights and shadows SgtHelper.SetTempMaterial(material); var mask = 1 << gameObject.layer; var lights = SgtLight.Find(lit, mask, transform.position); SgtShadow.Find(lit, mask, lights); SgtShadow.FilterOutRing(transform.position); SgtShadow.Write(lit, 2); SgtLight.Write(lit, transform.position, transform, null, 1.0f, 2); }
private float GetSky(Vector3 eye, float localDistance) { var height01 = Mathf.InverseLerp(OuterRadius, innerMeshRadius, localDistance); var mul = outerDepthTex.GetPixelBilinear(height01 / (1.0f - outerFog), 0.0f).a; if (lit == true && night == true) { var mask = 1 << gameObject.layer; var lights = SgtLight.Find(lit, mask, cachedTransform.position); var lighting = 0.0f; var cameraDirection = (eye - cachedTransform.position).normalized; for (var i = 0; i < lights.Count && i < 2; i++) { var light = lights[i]; var position = default(Vector3); var direction = default(Vector3); var color = default(Color); SgtLight.Calculate(light, cachedTransform.position, null, null, ref position, ref direction, ref color); var dot = Vector3.Dot(direction, cameraDirection) * 0.5f + 0.5f; var night01 = Mathf.InverseLerp(nightEnd, nightStart, dot); var night = SgtEase.Evaluate(nightEase, 1.0f - Mathf.Pow(night01, nightPower)); if (night > lighting) { lighting = night; } } return(Mathf.Lerp(nightSky, sky, lighting) * mul); } return(sky * mul); }
public static void Write(bool lit, GameObject root, int maxShadows) { var shadowCount = 0; if (lit == true) { var light = default(SgtLight); if (SgtLight.Find(ref light) == true) { var shadow = FirstInstance; for (var i = 0; i < InstanceCount; i++) { if (shadow.gameObject != root) { var matrix = default(Matrix4x4); var ratio = default(float); if (shadow.CalculateShadow(ref matrix, ref ratio) == true) { var properties = GetShadowProperties(shadowCount++); for (var j = SgtHelper.tempMaterials.Count - 1; j >= 0; j--) { var tempMaterial = SgtHelper.tempMaterials[j]; if (tempMaterial != null) { tempMaterial.SetTexture(properties.Texture, shadow.GetTexture()); tempMaterial.SetMatrix(properties.Matrix, matrix); tempMaterial.SetFloat(properties.Ratio, ratio); } } } if (shadowCount >= maxShadows) { break; } } shadow = shadow.NextInstance; } } } for (var i = 0; i <= maxShadows; i++) { var keyword = GetShadowKeyword(i); if (lit == true && i == shadowCount) { SgtHelper.EnableKeyword(keyword); } else { SgtHelper.DisableKeyword(keyword); } } }
public abstract void CalculateShadow(SgtLight light);
protected virtual void OnEnable() { cachedLight = GetComponent <SgtLight>(); }