private void SetupSpotLight(Nigiri renderer, Matrix4x4 viewProj) { _commandBuffer.Clear(); int pass = 1; if (!IsCameraInSpotLightBounds()) { pass = 3; } Mesh mesh = Nigiri.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", Nigiri.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 SetupDirectionalLight(Nigiri renderer, Matrix4x4 viewProj) { if (_commandBuffer == null) { Start(); } _commandBuffer.Clear(); int pass = 4; _material.SetPass(pass); if (Noise) { _material.EnableKeyword("NOISE"); } else { _material.DisableKeyword("NOISE"); } _material.SetVector("_LightDir", new Vector4(_light.transform.forward.x, _light.transform.forward.y, _light.transform.forward.z, 1.0f / (_light.range * _light.range))); _material.SetVector("_LightColor", _light.color * _light.intensity); _material.SetFloat("_MaxRayLength", MaxRayLength); if (_light.cookie == null) { _material.EnableKeyword("DIRECTIONAL"); _material.DisableKeyword("DIRECTIONAL_COOKIE"); } else { _material.EnableKeyword("DIRECTIONAL_COOKIE"); _material.DisableKeyword("DIRECTIONAL"); _material.SetTexture("_LightTexture0", _light.cookie); } Texture nullTexture = null; if (_light.shadows != LightShadows.None) { _material.EnableKeyword("SHADOWS_DEPTH"); _commandBuffer.Blit(nullTexture, renderer.GetVolumeLightBuffer(), _material, pass); if (CustomRenderEvent != null) { CustomRenderEvent(renderer, this, _commandBuffer, viewProj); } } else { _material.DisableKeyword("SHADOWS_DEPTH"); renderer.GlobalCommandBuffer.Blit(nullTexture, renderer.GetVolumeLightBuffer(), _material, pass); if (CustomRenderEvent != null) { CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj); } } }
private void SetupPointLight(Nigiri renderer, Matrix4x4 viewProj) { if (_commandBuffer == null) { Start(); } _commandBuffer.Clear(); int pass = 0; if (!IsCameraInPointLightBounds()) { pass = 2; } _material.SetPass(pass); Mesh mesh = Nigiri.GetPointLightMesh(); float scale = _light.range * 2.0f; Matrix4x4 world = Matrix4x4.TRS(transform.position, _light.transform.rotation, new Vector3(scale, scale, scale)); _material.SetMatrix("_WorldViewProj", viewProj * world); _material.SetMatrix("_WorldView", Camera.current.worldToCameraMatrix * world); if (Noise) { _material.EnableKeyword("NOISE"); } else { _material.DisableKeyword("NOISE"); } _material.SetVector("_LightPos", new Vector4(_light.transform.position.x, _light.transform.position.y, _light.transform.position.z, 1.0f / (_light.range * _light.range))); _material.SetColor("_LightColor", _light.color * _light.intensity); if (_light.cookie == null) { _material.EnableKeyword("POINT"); _material.DisableKeyword("POINT_COOKIE"); } else { Matrix4x4 view = Matrix4x4.TRS(_light.transform.position, _light.transform.rotation, Vector3.one).inverse; _material.SetMatrix("_MyLightMatrix0", view); _material.EnableKeyword("POINT_COOKIE"); _material.DisableKeyword("POINT"); _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) { _material.EnableKeyword("SHADOWS_CUBE"); _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_CUBE"); renderer.GlobalCommandBuffer.DrawMesh(mesh, world, _material, 0, pass); if (CustomRenderEvent != null) { CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj); } } }