示例#1
0
    private void InitRaytracingAccelerationStructure()
    {
        RayTracingAccelerationStructure.RASSettings settings = new RayTracingAccelerationStructure.RASSettings();
        // include default layer, not lights
        settings.layerMask = -1;
        // enable automatic updates
        settings.managementMode = RayTracingAccelerationStructure.ManagementMode.Manual;
        // include all renderer types
        settings.rayTracingModeMask = RayTracingAccelerationStructure.RayTracingModeMask.Everything;

        _accelerationStructure = new RayTracingAccelerationStructure(settings);

        // collect all objects in scene and add them to raytracing scene
        Renderer[] renderers = FindObjectsOfType <Renderer>();
        foreach (Renderer r in renderers)
        {
            if (r.CompareTag("Light"))
            {
                // mask for lights is 0x10 (for shadow rays - dont want to check for intersection in some cases)
                _accelerationStructure.AddInstance(r, null, null, true, false, 0x10);
            }
            else
            {
                _accelerationStructure.AddInstance(r, null, null, true, false, 0x01);
            }
        }

        // build raytracing AS
        _accelerationStructure.Build();
    }
 void Start()
 {
     if (!SystemInfo.supportsRayTracing)
     {
         Debug.Log("Ray Tracing not supported !");
     }
     _Camera        = GetComponent <Camera>();
     _RenderTarget0 = new RenderTexture(_Camera.pixelWidth, _Camera.pixelHeight, 0, RenderTextureFormat.ARGBFloat);
     _RenderTarget0.enableRandomWrite = true;
     _RenderTarget0.Create();
     _RenderTarget1 = new RenderTexture(_RenderTarget0);
     _RenderTarget2 = new RenderTexture(_RenderTarget0);
     RayTracingAccelerationStructure.RASSettings settings = new RayTracingAccelerationStructure.RASSettings();
     settings.layerMask          = ~0;
     settings.managementMode     = RayTracingAccelerationStructure.ManagementMode.Automatic;
     settings.rayTracingModeMask = RayTracingAccelerationStructure.RayTracingModeMask.Everything;
     _AccelerationStructure      = new RayTracingAccelerationStructure(settings);
     Renderer[] renderers = FindObjectsOfType <Renderer>();
     for (int i = 0; i < renderers.Length; i++)
     {
         Material[] materials = renderers[i].sharedMaterials;
         for (int j = 0; j < materials.Length; j++)
         {
             materials[j] = new Material(IndirectDiffuseShader);
         }
         renderers[i].sharedMaterials = materials;
         _AccelerationStructure.AddInstance(renderers[i]);
     }
     _AccelerationStructure.Build();
     PathTracingShader.SetAccelerationStructure("_AccelerationStructure", _AccelerationStructure);
     PathTracingShader.SetTexture("_RenderTarget", _RenderTarget0);
     PathTracingShader.SetShaderPass("PathTracingRTX");
     _Material = new Material(ProgressiveShader);
     Reset();
 }
示例#3
0
    private void InitRaytracingAccelerationStructure()
    {
        RayTracingAccelerationStructure.RASSettings settings = new RayTracingAccelerationStructure.RASSettings();
        // include all layers
        settings.layerMask = ~0;
        // enable automatic updates
        settings.managementMode = RayTracingAccelerationStructure.ManagementMode.Automatic;
        // include all renderer types
        settings.rayTracingModeMask = RayTracingAccelerationStructure.RayTracingModeMask.Everything;

        _rtas = new RayTracingAccelerationStructure(settings);

        // collect all objects in scene and add them to raytracing scene
        Renderer[] renderers = FindObjectsOfType <Renderer>();
        foreach (Renderer r in renderers)
        {
            _rtas.AddInstance(r);
        }

        // build raytracing scene
        _rtas.Build();

        // RTAS could also be the one from (internal)
        // HDRenderPipeline.RequestAccelerationStructure();
        // reset with
        // HDRenderPipeline.ResetPathTracing();
    }
示例#4
0
 public void FillAccelerationStructure(ref RayTracingAccelerationStructure vRayTracingAccelerationStructure)
 {
     foreach (var r in _renderers)
     {
         if (r)
         {
             vRayTracingAccelerationStructure.AddInstance(r, _subMeshFlagArray, _subMeshCutoffArray);
         }
     }
 }
示例#5
0
		protected override void Setup(ScriptableRenderContext ctx, CommandBuffer cmd)
		{
			if (!enableRayTracingOutline) return;
			_outlineRAS = new RayTracingAccelerationStructure();
			if (outlineRenderers != null)
				foreach (var renderer in outlineRenderers)
					if (renderer != null)
						_outlineRAS.AddInstance(renderer);
			_outlineMask = RTHandles.Alloc(Vector2.one, TextureXR.slices, colorFormat: GraphicsFormat.R8_SNorm,
										   dimension: TextureXR.dimension, enableRandomWrite: true,
										   useDynamicScale: true, useMipMap: false,
										   name: "JTRP Ray Tracing Outline Mask");
		}
    private void InitRaytracingAccelerationStructure()
    {
        _rtas = new RayTracingAccelerationStructure();

        // collect all objects in scene and add them to raytracing scene
        Renderer[] renderers = FindObjectsOfType <Renderer>();
        foreach (Renderer r in renderers)
        {
            _rtas.AddInstance(r);
        }

        // build raytrasing scene
        _rtas.Build();
    }
    /// <summary>
    /// build acceleration structure.
    /// </summary>
    public void BuildAccelerationStructure()
    {
        accelerationStructure?.Dispose();
        accelerationStructure = new RayTracingAccelerationStructure();

        var subMeshFlagArray   = new bool[32];
        var subMeshCutoffArray = new bool[32];

        for (var i = 0; i < 32; ++i)
        {
            subMeshFlagArray[i]   = true;
            subMeshCutoffArray[i] = false;
        }
        foreach (var r in colliders)
        {
            accelerationStructure.AddInstance(r, subMeshFlagArray, subMeshCutoffArray);
        }
        accelerationStructure.Build();
    }
示例#8
0
    void CreateRTAS()
    {
        RayTracingAccelerationStructure.RASSettings settings = new RayTracingAccelerationStructure.RASSettings();

        settings.layerMask = ~0;

        settings.managementMode = RayTracingAccelerationStructure.ManagementMode.Automatic;

        settings.rayTracingModeMask = RayTracingAccelerationStructure.RayTracingModeMask.Everything;



        _RTAS = new RayTracingAccelerationStructure(settings);

        renderers = FindObjectsOfType <Renderer>();
        for (int i = 0; i < renderers.Length; i++)
        {
            _RTAS.AddInstance(renderers[i]);
        }
        _RTAS.Build();
    }
    private void InitRaytracingAccelerationStructure()
    {
        RayTracingAccelerationStructure.RASSettings settings = new RayTracingAccelerationStructure.RASSettings();
        // include all layers
        settings.layerMask = ~0;
        // enable automatic updates
        settings.managementMode = RayTracingAccelerationStructure.ManagementMode.Automatic;
        // include all renderer types
        settings.rayTracingModeMask = RayTracingAccelerationStructure.RayTracingModeMask.Everything;

        _rtas = new RayTracingAccelerationStructure(settings);

        // collect all objects in scene and add them to raytracing scene
        Renderer[] renderers = FindObjectsOfType <Renderer>();
        foreach (Renderer r in renderers)
        {
            _rtas.AddInstance(r);
        }

        // build raytrasing scene
        _rtas.Build();
    }
示例#10
0
    public void Update()
    {
        // if loading world is not enabled, build AS and return
        if (!Settings.Instance.loadWorld)
        {
            if (_accelerationStructure != null)
            {
                _accelerationStructure.UpdateInstanceTransform(sun.GetComponent <Renderer>());
                _accelerationStructure.Build();
            }

            return;
        }

        _radius = Settings.Instance.WorldRadius;

        if (runningJobs > 0)
        {
            runningJobs = 0;
            JobHandle.CompleteAll(_jobHandles);
        }
        if (_jobHandlesAlocated)
        {
            _jobHandles.Dispose();
        }
        _jobHandles         = new NativeList <JobHandle>(Allocator.Persistent);
        _jobHandlesAlocated = true;

        // If camera moved to another chunk, generate new chunks in multiple phases
        Vector3Int chunkWherePlayerStands = ChunkWherePlayerStands();

        if ((!chunkWherePlayerStands.Equals(_chunkWherePlayerStood) || _prevRadius != _radius) && phase == Phase.Resting)
        {
            _chunkWherePlayerStood = chunkWherePlayerStands;

            int radiusInChunks = _chunkSize * _radius;
            FindMissingChunks(chunkWherePlayerStands, radiusInChunks);

            if (_toGenerate.Count > 0)
            {
                _iter = _toGenerate.Count - 1;
                phase = Phase.GeneratingBlocks;
            }
            else if (_prevRadius != _radius)
            {
                phase = Phase.RemovingChunks;
            }
            else
            {
                phase = Phase.Resting;
            }

            _prevRadius = _radius;
        }
        else if (phase == Phase.GeneratingBlocks)
        {
            for (; _iter >= 0 && runningJobs < _maxJobsAtOnce * 5; _iter--)
            {
                _jobHandles.Add(_toGenerate[_iter].GenerateBlocks(centroids));
                runningJobs++;
            }

            if (_iter < 0)
            {
                phase = Phase.GeneratingMeshData;
                _iter = _toGenerate.Count - 1;
            }
        }
        else if (phase == Phase.GeneratingMeshData)
        {
            for (; _iter >= 0 && runningJobs <= _maxJobsAtOnce * 4; _iter--)
            {
                if (!_toGenerate[_iter].IsEmpty())
                {
                    _jobHandles.Add(_toGenerate[_iter].GenerateMeshData());
                    _toGenerate[_iter].PrepareMesh();
                    runningJobs++;
                }
            }

            if (_iter < 0)
            {
                phase = Phase.GeneratingFlora;
                _iter = _toGenerate.Count - 1;
            }
        }
        else if (phase == Phase.GeneratingFlora)
        {
            for (; _iter >= 0 && runningJobs <= _maxJobsAtOnce * 4; _iter--)
            {
                if (_toGenerate[_iter].AreTrees())
                {
                    _jobHandles.Add(_toGenerate[_iter].GenerateTrees());
                    runningJobs++;
                }
            }

            if (_iter < 0)
            {
                phase = Phase.FillingMeshes;
                _iter = _toGenerate.Count - 1;
            }
        }
        else if (phase == Phase.FillingMeshes)
        {
            int runningFinishes = 0;

            for (; _iter >= 0 && runningFinishes < 2; _iter--)
            {
                if (!_toGenerate[_iter].IsEmpty())
                {
                    runningFinishes += _toGenerate[_iter].FinishCreatingChunk();
                    _accelerationStructure.AddInstance(_toGenerate[_iter].chunk.GetComponent <Renderer>(), null, null, true, false, 0x01);
                }
            }

            if (_iter < 0)
            {
                phase = Phase.RemovingChunks;
                _toGenerate.Clear();
            }
        }
        else if (phase == Phase.RemovingChunks)
        {
            int radiusInChunks = _chunkSize * _radius;
            RemoveChunks(chunkWherePlayerStands, radiusInChunks);
            phase = Phase.Resting;
        }
        else
        {
            phase = Phase.Resting;
        }

        // Update sun transform and build AS
        if (_accelerationStructure != null)
        {
            _accelerationStructure.UpdateInstanceTransform(sun.GetComponent <Renderer>());
            _accelerationStructure.Build();
        }

        if (phase == Phase.Resting)
        {
            Settings.Instance.reprojectWithIDs = true;
        }
        else
        {
            Settings.Instance.reprojectWithIDs = false;
        }
    }
示例#11
0
        AccelerationStructureStatus AddInstanceToRAS(Renderer currentRenderer,
                                                     bool rayTracedShadow,
                                                     bool aoEnabled, int aoLayerValue,
                                                     bool reflEnabled, int reflLayerValue,
                                                     bool giEnabled, int giLayerValue,
                                                     bool recursiveEnabled, int rrLayerValue,
                                                     bool pathTracingEnabled, int ptLayerValue)
        {
            // Get all the materials of the mesh renderer
            currentRenderer.GetSharedMaterials(materialArray);
            // If the array is null, we are done
            if (materialArray == null)
            {
                return(AccelerationStructureStatus.NullMaterial);
            }

            // For every sub-mesh/sub-material let's build the right flags
            int numSubMeshes = 1;

            if (!(currentRenderer.GetType() == typeof(SkinnedMeshRenderer)))
            {
                currentRenderer.TryGetComponent(out MeshFilter meshFilter);
                if (meshFilter == null || meshFilter.sharedMesh == null)
                {
                    return(AccelerationStructureStatus.MissingMesh);
                }
                numSubMeshes = meshFilter.sharedMesh.subMeshCount;
            }
            else
            {
                SkinnedMeshRenderer skinnedMesh = (SkinnedMeshRenderer)currentRenderer;
                if (skinnedMesh.sharedMesh == null)
                {
                    return(AccelerationStructureStatus.MissingMesh);
                }
                numSubMeshes = skinnedMesh.sharedMesh.subMeshCount;
            }

            // Get the layer of this object
            int objectLayerValue = 1 << currentRenderer.gameObject.layer;

            // We need to build the instance flag for this renderer
            uint instanceFlag = 0x00;

            bool singleSided = false;
            bool materialIsOnlyTransparent = true;
            bool hasTransparentSubMaterial = false;

            for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
            {
                // Initially we consider the potential mesh as invalid
                bool validMesh = false;
                if (materialArray.Count > meshIdx)
                {
                    // Grab the material for the current sub-mesh
                    Material currentMaterial = materialArray[meshIdx];

                    // The material is transparent if either it has the requested keyword or is in the transparent queue range
                    if (currentMaterial != null)
                    {
                        // Mesh is valid given that all requirements are ok
                        validMesh = true;
                        subMeshFlagArray[meshIdx] = true;

                        // Is the sub material transparent?
                        subMeshTransparentArray[meshIdx] = currentMaterial.IsKeywordEnabled("_SURFACE_TYPE_TRANSPARENT") ||
                                                           (HDRenderQueue.k_RenderQueue_Transparent.lowerBound <= currentMaterial.renderQueue &&
                                                            HDRenderQueue.k_RenderQueue_Transparent.upperBound >= currentMaterial.renderQueue);

                        // aggregate the transparency info
                        materialIsOnlyTransparent &= subMeshTransparentArray[meshIdx];
                        hasTransparentSubMaterial |= subMeshTransparentArray[meshIdx];

                        // Is the material alpha tested?
                        subMeshCutoffArray[meshIdx] = currentMaterial.IsKeywordEnabled("_ALPHATEST_ON") ||
                                                      (HDRenderQueue.k_RenderQueue_OpaqueAlphaTest.lowerBound <= currentMaterial.renderQueue &&
                                                       HDRenderQueue.k_RenderQueue_OpaqueAlphaTest.upperBound >= currentMaterial.renderQueue);

                        // Force it to be non single sided if it has the keyword if there is a reason
                        bool doubleSided = currentMaterial.doubleSidedGI || currentMaterial.IsKeywordEnabled("_DOUBLESIDED_ON");
                        singleSided |= !doubleSided;

                        // Check if the material has changed since last time we were here
                        if (!m_MaterialsDirty)
                        {
                            int matId = currentMaterial.GetInstanceID();
                            int matPrevCRC, matCurCRC = currentMaterial.ComputeCRC();
                            if (m_MaterialCRCs.TryGetValue(matId, out matPrevCRC))
                            {
                                m_MaterialCRCs[matId] = matCurCRC;
                                m_MaterialsDirty     |= (matCurCRC != matPrevCRC);
                            }
                            else
                            {
                                m_MaterialCRCs.Add(matId, matCurCRC);
                            }
                        }
                    }
                }

                // If the mesh was not valid, exclude it
                if (!validMesh)
                {
                    subMeshFlagArray[meshIdx]   = false;
                    subMeshCutoffArray[meshIdx] = false;
                    singleSided = true;
                }
            }

            // If the material is considered opaque, but has some transparent sub-materials
            if (!materialIsOnlyTransparent && hasTransparentSubMaterial)
            {
                for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
                {
                    subMeshCutoffArray[meshIdx] = subMeshTransparentArray[meshIdx] ? true : subMeshCutoffArray[meshIdx];
                }
            }

            // Propagate the opacity mask only if all sub materials are opaque
            bool isOpaque = !hasTransparentSubMaterial;

            if (isOpaque)
            {
                instanceFlag |= (uint)(RayTracingRendererFlag.Opaque);
            }

            if (rayTracedShadow || pathTracingEnabled)
            {
                if (hasTransparentSubMaterial)
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode != ShadowCastingMode.Off) ? (uint)(RayTracingRendererFlag.CastShadowTransparent) : 0x00);
                }
                else
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode != ShadowCastingMode.Off) ? (uint)(RayTracingRendererFlag.CastShadowOpaque) : 0x00);
                }
            }

            // We consider a mesh visible by reflection, gi, etc if it is not in the shadow only mode.
            bool meshIsVisible = currentRenderer.shadowCastingMode != ShadowCastingMode.ShadowsOnly;

            if (aoEnabled && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Ambient Occlusion flag if needed
                instanceFlag |= ((aoLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.AmbientOcclusion) : 0x00;
            }

            if (reflEnabled && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Screen Space Reflection if needed
                instanceFlag |= ((reflLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.Reflection) : 0x00;
            }

            if (giEnabled && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Global Illumination if needed
                instanceFlag |= ((giLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.GlobalIllumination) : 0x00;
            }

            if (recursiveEnabled && meshIsVisible)
            {
                // Raise the Global Illumination if needed
                instanceFlag |= ((rrLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.RecursiveRendering) : 0x00;
            }

            if (pathTracingEnabled && meshIsVisible)
            {
                // Raise the Global Illumination if needed
                instanceFlag |= ((ptLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.PathTracing) : 0x00;
            }

            // If the object was not referenced
            if (instanceFlag == 0)
            {
                return(AccelerationStructureStatus.Added);
            }

            // Add it to the acceleration structure
            m_CurrentRAS.AddInstance(currentRenderer, subMeshMask: subMeshFlagArray, subMeshTransparencyFlags: subMeshCutoffArray, enableTriangleCulling: singleSided, mask: instanceFlag);

            // return the status
            return((!materialIsOnlyTransparent && hasTransparentSubMaterial) ? AccelerationStructureStatus.TransparencyIssue : AccelerationStructureStatus.Added);
        }
示例#12
0
        AccelerationStructureStatus AddInstanceToRAS(Renderer currentRenderer,
                                                     bool rayTracedShadow,
                                                     bool aoEnabled, int aoLayerValue,
                                                     bool reflEnabled, int reflLayerValue,
                                                     bool giEnabled, int giLayerValue,
                                                     bool recursiveEnabled, int rrLayerValue,
                                                     bool pathTracingEnabled, int ptLayerValue)
        {
            // Get all the materials of the mesh renderer
            currentRenderer.GetSharedMaterials(materialArray);
            // If the array is null, we are done
            if (materialArray == null)
            {
                return(AccelerationStructureStatus.NullMaterial);
            }

            // For every sub-mesh/sub-material let's build the right flags
            int numSubMeshes = 1;

            if (!(currentRenderer.GetType() == typeof(SkinnedMeshRenderer)))
            {
                currentRenderer.TryGetComponent(out MeshFilter meshFilter);
                if (meshFilter == null || meshFilter.sharedMesh == null)
                {
                    return(AccelerationStructureStatus.MissingMesh);
                }
                numSubMeshes = meshFilter.sharedMesh.subMeshCount;
            }
            else
            {
                SkinnedMeshRenderer skinnedMesh = (SkinnedMeshRenderer)currentRenderer;
                if (skinnedMesh.sharedMesh == null)
                {
                    return(AccelerationStructureStatus.MissingMesh);
                }
                numSubMeshes = skinnedMesh.sharedMesh.subMeshCount;
            }

            // Let's clamp the number of sub-meshes to avoid throwing an unwated error
            numSubMeshes = Mathf.Min(numSubMeshes, maxNumSubMeshes);

            // Get the layer of this object
            int objectLayerValue = 1 << currentRenderer.gameObject.layer;

            // We need to build the instance flag for this renderer
            uint instanceFlag = 0x00;

            bool doubleSided = false;
            bool materialIsOnlyTransparent = true;
            bool hasTransparentSubMaterial = false;

            // We disregard the ray traced shadows option when in Path Tracing
            rayTracedShadow &= !pathTracingEnabled;

            // Deactivate Path Tracing if the object does not belong to the path traced layer(s)
            pathTracingEnabled &= (bool)((ptLayerValue & objectLayerValue) != 0);

            for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
            {
                // Initially we consider the potential mesh as invalid
                bool validMesh = false;
                if (materialArray.Count > meshIdx)
                {
                    // Grab the material for the current sub-mesh
                    Material currentMaterial = materialArray[meshIdx];

                    // Make sure that the material is HDRP's and non-decal
                    if (IsValidRayTracedMaterial(currentMaterial))
                    {
                        // Mesh is valid given that all requirements are ok
                        validMesh = true;

                        // First mark the thing as valid
                        subMeshFlagArray[meshIdx] = RayTracingSubMeshFlags.Enabled;

                        // Evaluate what kind of materials we are dealing with
                        bool alphaTested         = IsAlphaTestedMaterial(currentMaterial);
                        bool transparentMaterial = IsTransparentMaterial(currentMaterial);

                        // Aggregate the transparency info
                        materialIsOnlyTransparent &= transparentMaterial;
                        hasTransparentSubMaterial |= transparentMaterial;

                        // Append the additional flags depending on what kind of sub mesh this is
                        if (!transparentMaterial && !alphaTested)
                        {
                            subMeshFlagArray[meshIdx] |= RayTracingSubMeshFlags.ClosestHitOnly;
                        }
                        else if (transparentMaterial)
                        {
                            subMeshFlagArray[meshIdx] |= RayTracingSubMeshFlags.UniqueAnyHitCalls;
                        }

                        // Check if we want to enable double-sidedness for the mesh
                        // (note that a mix of single and double-sided materials will result in a double-sided mesh in the AS)
                        doubleSided |= currentMaterial.doubleSidedGI || currentMaterial.IsKeywordEnabled("_DOUBLESIDED_ON");

                        // Check if the material has changed since last time we were here
                        if (!m_MaterialsDirty)
                        {
                            int matId = currentMaterial.GetInstanceID();
                            int matPrevCRC, matCurCRC = currentMaterial.ComputeCRC();
                            if (m_MaterialCRCs.TryGetValue(matId, out matPrevCRC))
                            {
                                m_MaterialCRCs[matId] = matCurCRC;
                                m_MaterialsDirty     |= (matCurCRC != matPrevCRC);
                            }
                            else
                            {
                                m_MaterialCRCs.Add(matId, matCurCRC);
                            }
                        }
                    }
                }

                // If the mesh was not valid, exclude it (without affecting sidedness)
                if (!validMesh)
                {
                    subMeshFlagArray[meshIdx] = RayTracingSubMeshFlags.Disabled;
                }
            }

            // If the material is considered opaque, every sub-mesh has to be enabled and with unique any hit calls
            if (!materialIsOnlyTransparent && hasTransparentSubMaterial)
            {
                for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
                {
                    subMeshFlagArray[meshIdx] = RayTracingSubMeshFlags.Enabled | RayTracingSubMeshFlags.UniqueAnyHitCalls;
                }
            }


            // Propagate the opacity mask only if all sub materials are opaque
            bool isOpaque = !hasTransparentSubMaterial;

            if (isOpaque)
            {
                instanceFlag |= (uint)(RayTracingRendererFlag.Opaque);
            }

            if (rayTracedShadow || pathTracingEnabled)
            {
                if (hasTransparentSubMaterial)
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode != ShadowCastingMode.Off) ? (uint)(RayTracingRendererFlag.CastShadowTransparent) : 0x00);
                }
                else
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode != ShadowCastingMode.Off) ? (uint)(RayTracingRendererFlag.CastShadowOpaque) : 0x00);
                }
            }

            // We consider a mesh visible by reflection, gi, etc if it is not in the shadow only mode.
            bool meshIsVisible = currentRenderer.shadowCastingMode != ShadowCastingMode.ShadowsOnly;

            if (aoEnabled && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Ambient Occlusion flag if needed
                instanceFlag |= ((aoLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.AmbientOcclusion) : 0x00;
            }

            if (reflEnabled && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Screen Space Reflection flag if needed
                instanceFlag |= ((reflLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.Reflection) : 0x00;
            }

            if (giEnabled && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Global Illumination flag if needed
                instanceFlag |= ((giLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.GlobalIllumination) : 0x00;
            }

            if (recursiveEnabled && meshIsVisible)
            {
                // Raise the Recursive Rendering flag if needed
                instanceFlag |= ((rrLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.RecursiveRendering) : 0x00;
            }

            if (pathTracingEnabled && meshIsVisible)
            {
                // Raise the Path Tracing flag if needed
                instanceFlag |= (uint)(RayTracingRendererFlag.PathTracing);
            }

            // If the object was not referenced
            if (instanceFlag == 0)
            {
                return(AccelerationStructureStatus.Added);
            }

            // Add it to the acceleration structure
            m_CurrentRAS.AddInstance(currentRenderer, subMeshFlags: subMeshFlagArray, enableTriangleCulling: !doubleSided, mask: instanceFlag);

            // Indicates that a transform has changed in our scene (mesh or light)
            m_TransformDirty |= currentRenderer.transform.hasChanged;
            currentRenderer.transform.hasChanged = false;

            // return the status
            return((!materialIsOnlyTransparent && hasTransparentSubMaterial) ? AccelerationStructureStatus.TransparencyIssue : AccelerationStructureStatus.Added);
        }
示例#13
0
        void AddInstanceToRAS(Renderer currentRenderer,
                              bool rayTracedShadow,
                              bool aoEnabled, int aoLayerValue,
                              bool reflEnabled, int reflLayerValue,
                              bool giEnabled, int giLayerValue,
                              bool recursiveEnabled, int rrLayerValue,
                              bool pathTracingEnabled, int ptLayerValue)
        {
            currentRenderer.GetSharedMaterials(materialArray);
            if (materialArray != null)
            {
                // For every sub-mesh/sub-material let's build the right flags
                int numSubMeshes = materialArray.Count;

                // Get the layer of this object
                int objectLayerValue = 1 << currentRenderer.gameObject.layer;

                // We need to build the instance flag for this renderer
                uint instanceFlag = 0x00;

                bool singleSided           = false;
                bool materialIsTransparent = false;

                for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
                {
                    Material currentMaterial = materialArray[meshIdx];
                    // The material is transparent if either it has the requested keyword or is in the transparent queue range
                    if (currentMaterial != null)
                    {
                        subMeshFlagArray[meshIdx] = true;

                        // Is the material transparent?
                        materialIsTransparent |= currentMaterial.IsKeywordEnabled("_SURFACE_TYPE_TRANSPARENT") ||
                                                 (HDRenderQueue.k_RenderQueue_Transparent.lowerBound <= currentMaterial.renderQueue &&
                                                  HDRenderQueue.k_RenderQueue_Transparent.upperBound >= currentMaterial.renderQueue) ||
                                                 (HDRenderQueue.k_RenderQueue_AllTransparentRaytracing.lowerBound <= currentMaterial.renderQueue &&
                                                  HDRenderQueue.k_RenderQueue_AllTransparentRaytracing.upperBound >= currentMaterial.renderQueue);

                        // Is the material alpha tested?
                        subMeshCutoffArray[meshIdx] = currentMaterial.IsKeywordEnabled("_ALPHATEST_ON") ||
                                                      (HDRenderQueue.k_RenderQueue_OpaqueAlphaTest.lowerBound <= currentMaterial.renderQueue &&
                                                       HDRenderQueue.k_RenderQueue_OpaqueAlphaTest.upperBound >= currentMaterial.renderQueue);

                        // Force it to be non single sided if it has the keyword if there is a reason
                        bool doubleSided = currentMaterial.doubleSidedGI || currentMaterial.IsKeywordEnabled("_DOUBLESIDED_ON");
                        singleSided |= !doubleSided;
                    }
                    else
                    {
                        subMeshFlagArray[meshIdx]   = false;
                        subMeshCutoffArray[meshIdx] = false;
                        singleSided = true;
                    }
                }

                // Propagate the right mask
                instanceFlag |= materialIsTransparent ? (uint)(1 << 1) : (uint)(1 << 0);

                if (rayTracedShadow)
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode == ShadowCastingMode.On) ? (uint)(RayTracingRendererFlag.CastShadow) : 0x00);
                }

                if (aoEnabled && !materialIsTransparent)
                {
                    // Raise the Ambient Occlusion flag if needed
                    instanceFlag |= ((aoLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.AmbientOcclusion) : 0x00;
                }

                if (reflEnabled && !materialIsTransparent)
                {
                    // Raise the Screen Space Reflection if needed
                    instanceFlag |= ((reflLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.Reflection) : 0x00;
                }

                if (giEnabled && !materialIsTransparent)
                {
                    // Raise the Global Illumination if needed
                    instanceFlag |= ((giLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.GlobalIllumination) : 0x00;
                }

                if (recursiveEnabled)
                {
                    // Raise the Global Illumination if needed
                    instanceFlag |= ((rrLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.RecursiveRendering) : 0x00;
                }

                if (pathTracingEnabled)
                {
                    // Raise the Global Illumination if needed
                    instanceFlag |= ((ptLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.PathTracing) : 0x00;
                }

                if (instanceFlag == 0)
                {
                    return;
                }

                // Add it to the acceleration structure
                m_CurrentRAS.AddInstance(currentRenderer, subMeshMask: subMeshFlagArray, subMeshTransparencyFlags: subMeshCutoffArray, enableTriangleCulling: singleSided, mask: instanceFlag);
            }
        }
        AccelerationStructureStatus AddInstanceToRAS(Renderer currentRenderer,
                                                     bool rayTracedShadow,
                                                     bool aoEnabled, int aoLayerValue,
                                                     bool reflEnabled, int reflLayerValue,
                                                     bool giEnabled, int giLayerValue,
                                                     bool recursiveEnabled, int rrLayerValue,
                                                     bool pathTracingEnabled, int ptLayerValue)
        {
            // Get all the materials of the mesh renderer
            currentRenderer.GetSharedMaterials(materialArray);
            // If the array is null, we are done
            if (materialArray == null)
            {
                return(AccelerationStructureStatus.NullMaterial);
            }

            // For every sub-mesh/sub-material let's build the right flags
            currentRenderer.TryGetComponent(out MeshFilter meshFilter);
            if (meshFilter == null || meshFilter.sharedMesh == null)
            {
                return(AccelerationStructureStatus.MissingMesh);
            }
            int numSubMeshes = meshFilter.sharedMesh.subMeshCount;

            // Get the layer of this object
            int objectLayerValue = 1 << currentRenderer.gameObject.layer;

            // We need to build the instance flag for this renderer
            uint instanceFlag = 0x00;

            bool singleSided = false;
            bool materialIsOnlyTransparent = true;
            bool hasTransparentSubMaterial = false;

            for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
            {
                // Intially we consider the potential mesh as invalid
                bool validMesh = false;
                if (materialArray.Count > meshIdx)
                {
                    // Grab the material for the current sub-mesh
                    Material currentMaterial = materialArray[meshIdx];

                    // The material is transparent if either it has the requested keyword or is in the transparent queue range
                    if (currentMaterial != null)
                    {
                        // Mesh is valid given that all requirements are ok
                        validMesh = true;
                        subMeshFlagArray[meshIdx] = true;

                        // Is the sub material transparent?
                        subMeshTransparentArray[meshIdx] = currentMaterial.IsKeywordEnabled("_SURFACE_TYPE_TRANSPARENT") ||
                                                           (HDRenderQueue.k_RenderQueue_Transparent.lowerBound <= currentMaterial.renderQueue &&
                                                            HDRenderQueue.k_RenderQueue_Transparent.upperBound >= currentMaterial.renderQueue) ||
                                                           (HDRenderQueue.k_RenderQueue_AllTransparentRaytracing.lowerBound <= currentMaterial.renderQueue &&
                                                            HDRenderQueue.k_RenderQueue_AllTransparentRaytracing.upperBound >= currentMaterial.renderQueue);

                        // aggregate the transparency info
                        materialIsOnlyTransparent &= subMeshTransparentArray[meshIdx];
                        hasTransparentSubMaterial |= subMeshTransparentArray[meshIdx];

                        // Is the material alpha tested?
                        subMeshCutoffArray[meshIdx] = currentMaterial.IsKeywordEnabled("_ALPHATEST_ON") ||
                                                      (HDRenderQueue.k_RenderQueue_OpaqueAlphaTest.lowerBound <= currentMaterial.renderQueue &&
                                                       HDRenderQueue.k_RenderQueue_OpaqueAlphaTest.upperBound >= currentMaterial.renderQueue);

                        // Force it to be non single sided if it has the keyword if there is a reason
                        bool doubleSided = currentMaterial.doubleSidedGI || currentMaterial.IsKeywordEnabled("_DOUBLESIDED_ON");
                        singleSided |= !doubleSided;
                    }
                }

                // If the mesh was not valid, exclude it
                if (!validMesh)
                {
                    subMeshFlagArray[meshIdx]   = false;
                    subMeshCutoffArray[meshIdx] = false;
                    singleSided = true;
                }
            }

            // If the material is considered opaque, but has some transparent sub-materials
            if (!materialIsOnlyTransparent && hasTransparentSubMaterial)
            {
                for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
                {
                    subMeshCutoffArray[meshIdx] = subMeshTransparentArray[meshIdx] ? true : subMeshCutoffArray[meshIdx];
                }
            }

            // Propagate the right mask
            instanceFlag |= materialIsOnlyTransparent ? (uint)(1 << 1) : (uint)(1 << 0);

            if (rayTracedShadow)
            {
                // Raise the shadow casting flag if needed
                instanceFlag |= ((currentRenderer.shadowCastingMode == ShadowCastingMode.On) ? (uint)(RayTracingRendererFlag.CastShadow) : 0x00);
            }

            if (aoEnabled && !materialIsOnlyTransparent)
            {
                // Raise the Ambient Occlusion flag if needed
                instanceFlag |= ((aoLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.AmbientOcclusion) : 0x00;
            }

            if (reflEnabled && !materialIsOnlyTransparent)
            {
                // Raise the Screen Space Reflection if needed
                instanceFlag |= ((reflLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.Reflection) : 0x00;
            }

            if (giEnabled && !materialIsOnlyTransparent)
            {
                // Raise the Global Illumination if needed
                instanceFlag |= ((giLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.GlobalIllumination) : 0x00;
            }

            if (recursiveEnabled)
            {
                // Raise the Global Illumination if needed
                instanceFlag |= ((rrLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.RecursiveRendering) : 0x00;
            }

            if (pathTracingEnabled)
            {
                // Raise the Global Illumination if needed
                instanceFlag |= ((ptLayerValue & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.PathTracing) : 0x00;
            }

            // If the object was not referenced
            if (instanceFlag == 0)
            {
                return(AccelerationStructureStatus.Added);
            }

            // Add it to the acceleration structure
            m_CurrentRAS.AddInstance(currentRenderer, subMeshMask: subMeshFlagArray, subMeshTransparencyFlags: subMeshCutoffArray, enableTriangleCulling: singleSided, mask: instanceFlag);

            // return the status
            return((!materialIsOnlyTransparent && hasTransparentSubMaterial) ? AccelerationStructureStatus.TransparencyIssue : AccelerationStructureStatus.Added);
        }