private void InitSpotLight(VolumetricLightRenderer renderer, Matrix4x4 viewProj) { int pass = 1; if (!IsCameraInSpotLightBounds()) { pass = 3; } _material.SetFloat(_CosAngle, Mathf.Cos((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad)); _material.EnableKeyword("SPOT"); if (Noise) { _material.EnableKeyword("NOISE"); } else { _material.DisableKeyword("NOISE"); } if (_light.cookie == null) { _material.SetTexture(_LightTexture0, VolumetricLightRenderer.GetDefaultSpotCookie()); } else { _material.SetTexture(_LightTexture0, _light.cookie); } }
/// <summary> /// /// </summary> /// <param name="renderer"></param> /// <param name="viewProj"></param> private void SetupSpotLight(VolumetricLightRenderer renderer, Matrix4x4 viewProj) { _commandBuffer.Clear(); int pass = 1; if (!IsCameraInSpotLightBounds()) { pass = 3; } Mesh mesh = VolumetricLightRenderer.GetSpotLightMesh(); float scale = _light.range; float angleScale = Mathf.Tan((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad) * _light.range; Matrix4x4 world = Matrix4x4.TRS(transform.position, transform.rotation, new Vector3(angleScale, angleScale, scale)); Matrix4x4 view = Matrix4x4.TRS(_light.transform.position, _light.transform.rotation, Vector3.one).inverse; Matrix4x4 clip = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.identity, new Vector3(-0.5f, -0.5f, 1.0f)); Matrix4x4 proj = Matrix4x4.Perspective(_light.spotAngle, 1, 0, 1); _material.SetMatrix("_MyLightMatrix0", clip * proj * view); _material.SetMatrix("_WorldViewProj", viewProj * world); _material.SetVector("_LightPos", new Vector4(_light.transform.position.x, _light.transform.position.y, _light.transform.position.z, 1.0f / (_light.range * _light.range))); _material.SetVector("_LightColor", _light.color * _light.intensity); Vector3 apex = transform.position; Vector3 axis = transform.forward; // plane equation ax + by + cz + d = 0; precompute d here to lighten the shader Vector3 center = apex + axis * _light.range; float d = -Vector3.Dot(center, axis); // update material _material.SetFloat("_PlaneD", d); _material.SetFloat("_CosAngle", Mathf.Cos((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad)); _material.SetVector("_ConeApex", new Vector4(apex.x, apex.y, apex.z)); _material.SetVector("_ConeAxis", new Vector4(axis.x, axis.y, axis.z)); _material.EnableKeyword("SPOT"); if (Noise) { _material.EnableKeyword("NOISE"); } else { _material.DisableKeyword("NOISE"); } if (_light.cookie == null) { _material.SetTexture("_LightTexture0", VolumetricLightRenderer.GetDefaultSpotCookie()); } else { _material.SetTexture("_LightTexture0", _light.cookie); } bool forceShadowsOff = false; if ((_light.transform.position - Camera.current.transform.position).magnitude >= QualitySettings.shadowDistance) { forceShadowsOff = true; } if (_light.shadows != LightShadows.None && forceShadowsOff == false) { clip = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f)); if (_reversedZ) { proj = Matrix4x4.Perspective(_light.spotAngle, 1, _light.range, _light.shadowNearPlane); } else { proj = Matrix4x4.Perspective(_light.spotAngle, 1, _light.shadowNearPlane, _light.range); } Matrix4x4 m = clip * proj; m[0, 2] *= -1; m[1, 2] *= -1; m[2, 2] *= -1; m[3, 2] *= -1; //view = _light.transform.worldToLocalMatrix; _material.SetMatrix("_MyWorld2Shadow", m * view); _material.SetMatrix("_WorldView", m * view); _material.EnableKeyword("SHADOWS_DEPTH"); _commandBuffer.SetGlobalTexture("_ShadowMapTexture", BuiltinRenderTextureType.CurrentActive); _commandBuffer.SetRenderTarget(renderer.GetVolumeLightBuffer()); _commandBuffer.DrawMesh(mesh, world, _material, 0, pass); if (CustomRenderEvent != null) { CustomRenderEvent(renderer, this, _commandBuffer, viewProj); } } else { _material.DisableKeyword("SHADOWS_DEPTH"); renderer.GlobalCommandBuffer.DrawMesh(mesh, world, _material, 0, pass); if (CustomRenderEvent != null) { CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj); } } }
private void VolumetricLightRenderer_PreRenderEvent(VolumetricLightRenderer renderer, Matrix4x4 VP) { if (_light == null || _light.gameObject == null) { VolumetricLightRenderer.PreRenderEvent -= VolumetricLightRenderer_PreRenderEvent; } if (!_light.gameObject.activeInHierarchy || _light.enabled == false) { return; } _material.SetVector("_CameraForward", Camera.current.transform.forward); _material.SetInt("_SampleCount", SampleCount); _material.SetVector("_NoiseVelocity", new Vector4(NoiseVelocity.x, NoiseVelocity.y) * NoiseScale); _material.SetVector("_NoiseData", new Vector4(NoiseScale, NoiseIntensity, NoiseIntensityOffset)); _material.SetVector("_MieG", new Vector4(1 - (MieG * MieG), 1 + (MieG * MieG), 2 * MieG, 1.0f / (4.0f * Mathf.PI))); _material.SetVector("_VolumetricLight", new Vector4(ScatteringCoef, ExtinctionCoef, _light.range, 1.0f - SkyboxExtinctionCoef)); _material.SetTexture("_CameraDepthTexture", null); _material.SetFloat("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Always); if (HeightFog) { _material.EnableKeyword("HEIGHT_FOG"); _material.SetVector("_HeightFog", new Vector4(GroundLevel, HeightScale)); } else { _material.DisableKeyword("HEIGHT_FOG"); } _commandBuffer.Clear(); int pass = 0; if (!IsCameraInSpotLightBounds()) //离相机太远或者角度很偏时 { pass = 1; } Mesh mesh = VolumetricLightRenderer.GetSpotLightMesh(); //Spot mesh随着range变化缩放 //长度确定为_light.range 宽度由_light.spotAngle决定 float scale = _light.range; float angleScale = Mathf.Tan((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad) * _light.range; Matrix4x4 world = Matrix4x4.TRS(transform.position, transform.rotation, new Vector3(angleScale, angleScale, scale)); Matrix4x4 view = Matrix4x4.TRS(_light.transform.position, _light.transform.rotation, Vector3.one).inverse; Matrix4x4 clip = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.identity, new Vector3(-0.5f, -0.5f, 1.0f)); //圆形投影区aspect为1 Matrix4x4 proj = Matrix4x4.Perspective(_light.spotAngle, 1, 0, 1); _material.SetMatrix("_MyLightMatrix0", clip * proj * view); _material.SetMatrix("_WorldViewProj", VP * world); _material.SetVector("_LightPos", new Vector4(_light.transform.position.x, _light.transform.position.y, _light.transform.position.z, 1.0f / (_light.range * _light.range))); _material.SetVector("_LightColor", _light.color * _light.intensity); Vector3 apex = transform.position; Vector3 axis = transform.forward; // plane equation ax + by + cz + d = 0; precompute d here to lighten the shader Vector3 center = apex + axis * _light.range; float d = -Vector3.Dot(center, axis); // update material _material.SetFloat("_PlaneD", d); _material.SetFloat("_CosAngle", Mathf.Cos((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad)); _material.SetVector("_ConeApex", new Vector4(apex.x, apex.y, apex.z)); _material.SetVector("_ConeAxis", new Vector4(axis.x, axis.y, axis.z)); _material.EnableKeyword("SPOT"); if (Noise) { _material.EnableKeyword("NOISE"); } else { _material.DisableKeyword("NOISE"); } if (_light.cookie == null) { _material.SetTexture("_LightTexture0", VolumetricLightRenderer.GetDefaultSpotCookie()); } else { _material.SetTexture("_LightTexture0", _light.cookie); } clip = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f)); if (_reversedZ) { proj = Matrix4x4.Perspective(_light.spotAngle, 1, _light.range, _light.shadowNearPlane); } else { proj = Matrix4x4.Perspective(_light.spotAngle, 1, _light.shadowNearPlane, _light.range); } Matrix4x4 m = clip * proj; m[0, 2] *= -1; m[1, 2] *= -1; m[2, 2] *= -1; m[3, 2] *= -1; //view = _light.transform.worldToLocalMatrix; _material.SetMatrix("_MyWorld2Shadow", m * view); _material.SetMatrix("_WorldView", m * view); _material.EnableKeyword("SHADOWS_DEPTH"); _commandBuffer.SetGlobalTexture("_ShadowMapTexture", BuiltinRenderTextureType.CurrentActive); _commandBuffer.SetRenderTarget(renderer.GetVolumeLightBuffer()); _commandBuffer.DrawMesh(mesh, world, _material, 0, pass); }
private void SetupSpotLight(VolumetricLightRenderer renderer, Matrix4x4 viewProj) { this._commandBuffer.Clear(); int num1 = 1; if (!this.IsCameraInSpotLightBounds()) { num1 = 3; } Mesh spotLightMesh = VolumetricLightRenderer.GetSpotLightMesh(); float range = this._light.get_range(); float num2 = Mathf.Tan((float)(((double)this._light.get_spotAngle() + 1.0) * 0.5 * (Math.PI / 180.0))) * this._light.get_range(); Matrix4x4 matrix4x4_1 = Matrix4x4.TRS(((Component)this).get_transform().get_position(), ((Component)this).get_transform().get_rotation(), new Vector3(num2, num2, range)); Matrix4x4 matrix4x4_2 = Matrix4x4.TRS(((Component)this._light).get_transform().get_position(), ((Component)this._light).get_transform().get_rotation(), Vector3.get_one()); Matrix4x4 inverse = ((Matrix4x4) ref matrix4x4_2).get_inverse(); this._material.SetMatrix("_MyLightMatrix0", Matrix4x4.op_Multiply(Matrix4x4.op_Multiply(Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.get_identity(), new Vector3(-0.5f, -0.5f, 1f)), Matrix4x4.Perspective(this._light.get_spotAngle(), 1f, 0.0f, 1f)), inverse)); this._material.SetMatrix("_WorldViewProj", Matrix4x4.op_Multiply(viewProj, matrix4x4_1)); this._material.SetVector("_LightPos", new Vector4((float)((Component)this._light).get_transform().get_position().x, (float)((Component)this._light).get_transform().get_position().y, (float)((Component)this._light).get_transform().get_position().z, (float)(1.0 / ((double)this._light.get_range() * (double)this._light.get_range())))); this._material.SetVector("_LightColor", Color.op_Implicit(Color.op_Multiply(this._light.get_color(), this._light.get_intensity()))); Vector3 position = ((Component)this).get_transform().get_position(); Vector3 forward = ((Component)this).get_transform().get_forward(); this._material.SetFloat("_PlaneD", -Vector3.Dot(Vector3.op_Addition(position, Vector3.op_Multiply(forward, this._light.get_range())), forward)); this._material.SetFloat("_CosAngle", Mathf.Cos((float)(((double)this._light.get_spotAngle() + 1.0) * 0.5 * (Math.PI / 180.0)))); this._material.SetVector("_ConeApex", new Vector4((float)position.x, (float)position.y, (float)position.z)); this._material.SetVector("_ConeAxis", new Vector4((float)forward.x, (float)forward.y, (float)forward.z)); this._material.EnableKeyword("SPOT"); if (this.Noise) { this._material.EnableKeyword("NOISE"); } else { this._material.DisableKeyword("NOISE"); } if (Object.op_Equality((Object)this._light.get_cookie(), (Object)null)) { this._material.SetTexture("_LightTexture0", VolumetricLightRenderer.GetDefaultSpotCookie()); } else { this._material.SetTexture("_LightTexture0", this._light.get_cookie()); } bool flag = false; Vector3 vector3 = Vector3.op_Subtraction(((Component)this._light).get_transform().get_position(), ((Component)Camera.get_current()).get_transform().get_position()); if ((double)((Vector3) ref vector3).get_magnitude() >= (double)QualitySettings.get_shadowDistance()) { flag = true; } if (this._light.get_shadows() != null && !flag) { Matrix4x4 matrix4x4_3 = Matrix4x4.op_Multiply(Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.get_identity(), new Vector3(0.5f, 0.5f, 0.5f)), !this._reversedZ ? Matrix4x4.Perspective(this._light.get_spotAngle(), 1f, this._light.get_shadowNearPlane(), this._light.get_range()) : Matrix4x4.Perspective(this._light.get_spotAngle(), 1f, this._light.get_range(), this._light.get_shadowNearPlane())); // ISSUE: variable of a reference type Matrix4x4& local1; ((Matrix4x4)(local1 = ref matrix4x4_3)).set_Item(0, 2, ((Matrix4x4) ref local1).get_Item(0, 2) * -1f); // ISSUE: variable of a reference type Matrix4x4& local2; ((Matrix4x4)(local2 = ref matrix4x4_3)).set_Item(1, 2, ((Matrix4x4) ref local2).get_Item(1, 2) * -1f); // ISSUE: variable of a reference type Matrix4x4& local3; ((Matrix4x4)(local3 = ref matrix4x4_3)).set_Item(2, 2, ((Matrix4x4) ref local3).get_Item(2, 2) * -1f); // ISSUE: variable of a reference type Matrix4x4& local4; ((Matrix4x4)(local4 = ref matrix4x4_3)).set_Item(3, 2, ((Matrix4x4) ref local4).get_Item(3, 2) * -1f); this._material.SetMatrix("_MyWorld2Shadow", Matrix4x4.op_Multiply(matrix4x4_3, inverse)); this._material.SetMatrix("_WorldView", Matrix4x4.op_Multiply(matrix4x4_3, inverse)); this._material.EnableKeyword("SHADOWS_DEPTH"); this._commandBuffer.SetGlobalTexture("_ShadowMapTexture", RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)1)); this._commandBuffer.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)renderer.GetVolumeLightBuffer())); this._commandBuffer.DrawMesh(spotLightMesh, matrix4x4_1, this._material, 0, num1); if (this.CustomRenderEvent == null) { return; } this.CustomRenderEvent(renderer, this, this._commandBuffer, viewProj); } else { this._material.DisableKeyword("SHADOWS_DEPTH"); renderer.GlobalCommandBuffer.DrawMesh(spotLightMesh, matrix4x4_1, this._material, 0, num1); if (this.CustomRenderEvent == null) { return; } this.CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj); } }
private void SetupSpotLight(VolumetricLightRenderer renderer, Matrix4x4 viewProj) { int shaderPass = 1; if (!this.IsCameraInSpotLightBounds()) { shaderPass = 3; } Mesh spotLightMesh = VolumetricLightRenderer.GetSpotLightMesh(); float range = this._light.range; float num = Mathf.Tan((this._light.spotAngle + 1f) * 0.5f * 0.0174532924f) * this._light.range; Matrix4x4 matrix4x = Matrix4x4.TRS(base.transform.position, base.transform.rotation, new Vector3(num, num, range)); Matrix4x4 inverse = Matrix4x4.TRS(this._light.transform.position, this._light.transform.rotation, Vector3.one).inverse; Matrix4x4 lhs = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0f), Quaternion.identity, new Vector3(-0.5f, -0.5f, 1f)); Matrix4x4 rhs = Matrix4x4.Perspective(this._light.spotAngle, 1f, 0f, 1f); this._material.SetMatrix("_MyLightMatrix0", lhs * rhs * inverse); this._material.SetMatrix("_WorldViewProj", viewProj * matrix4x); this._material.SetVector("_LightPos", new Vector4(this._light.transform.position.x, this._light.transform.position.y, this._light.transform.position.z, 1f / (this._light.range * this._light.range))); this._material.SetVector("_LightColor", this._light.color * this._light.intensity); Vector3 position = base.transform.position; Vector3 forward = base.transform.forward; Vector3 lhs2 = position + forward * this._light.range; float value = -Vector3.Dot(lhs2, forward); this._material.SetFloat("_PlaneD", value); this._material.SetFloat("_CosAngle", Mathf.Cos((this._light.spotAngle + 1f) * 0.5f * 0.0174532924f)); this._material.SetVector("_ConeApex", new Vector4(position.x, position.y, position.z)); this._material.SetVector("_ConeAxis", new Vector4(forward.x, forward.y, forward.z)); this._material.EnableKeyword("SPOT"); if (this.Noise) { this._material.EnableKeyword("NOISE"); } else { this._material.DisableKeyword("NOISE"); } if (this._light.cookie == null) { this._material.SetTexture("_LightTexture0", VolumetricLightRenderer.GetDefaultSpotCookie()); } else { this._material.SetTexture("_LightTexture0", this._light.cookie); } bool flag = false; if ((this._light.transform.position - Camera.current.transform.position).magnitude >= QualitySettings.shadowDistance) { flag = true; } if (this._light.shadows != LightShadows.None && !flag) { lhs = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f)); if (this._reversedZ) { rhs = Matrix4x4.Perspective(this._light.spotAngle, 1f, this._light.range, this._light.shadowNearPlane); } else { rhs = Matrix4x4.Perspective(this._light.spotAngle, 1f, this._light.shadowNearPlane, this._light.range); } Matrix4x4 lhs3 = lhs * rhs; lhs3[0, 2] = lhs3[0, 2] * -1f; lhs3[1, 2] = lhs3[1, 2] * -1f; lhs3[2, 2] = lhs3[2, 2] * -1f; lhs3[3, 2] = lhs3[3, 2] * -1f; this._material.SetMatrix("_MyWorld2Shadow", lhs3 * inverse); this._material.SetMatrix("_WorldView", lhs3 * inverse); this._material.EnableKeyword("SHADOWS_DEPTH"); this._commandBuffer.SetGlobalTexture("_ShadowMapTexture", BuiltinRenderTextureType.CurrentActive); this._commandBuffer.SetRenderTarget(renderer.GetVolumeLightBuffer()); this._commandBuffer.DrawMesh(spotLightMesh, matrix4x, this._material, 0, shaderPass); if (this.CustomRenderEvent != null) { this.CustomRenderEvent(renderer, this, this._commandBuffer, viewProj); } } else { this._material.DisableKeyword("SHADOWS_DEPTH"); renderer.GlobalCommandBuffer.DrawMesh(spotLightMesh, matrix4x, this._material, 0, shaderPass); if (this.CustomRenderEvent != null) { this.CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj); } } }