private void OnEnable() { Debug.Log("Enabled"); m_mainCamera = Camera.main; #if (UNITY_EDITOR) if (!Application.isPlaying) { if (UnityEditor.SceneView.GetAllSceneCameras().Length > 0) { m_mainCamera = UnityEditor.SceneView.GetAllSceneCameras()[0]; } } #endif m_computeShader = (ComputeShader)Instantiate(m_computeShaderReference); m_cachedNumLods = Mathf.Min(m_LodSettings.Length, 4); m_cachedComputeKernel = m_computeShader.FindKernel("DrawPrep"); #if (UNITY_EDITOR) if (!Application.isPlaying) { m_cachedComputeKernel = m_computeShader.FindKernel("EditorDrawPrep"); } #endif m_cachedShadowComputeKernel = m_computeShader.FindKernel("ShadowDrawPrep"); m_drawCallBounds = new Bounds(Vector3.zero, new Vector3(1440.0f, 600.0f, 1440.0f)); //can maybe have this be something we read from the asset data //Initialize all arrays m_appendBuffers = new ComputeBuffer[m_cachedNumLods]; m_argsBuffersArray = new ComputeBuffer[m_cachedNumLods][]; m_argsArray = new uint[m_cachedNumLods][][]; for (int i = 0; i < m_cachedNumLods; i++) { m_argsBuffersArray[i] = new ComputeBuffer[m_LodSettings[i].mesh.subMeshCount]; m_argsArray[i] = new uint[m_LodSettings[i].mesh.subMeshCount][]; } m_cachedLodShadowSettings = new ShadowCastingMode[m_cachedNumLods]; m_materials = new Material[m_cachedNumLods][]; //Instantiate all the materials so that we do not write over the original materials //for (int i = 0; i < m_cachedNumLods; i++) //{ // m_materials[i] = new Material[m_LodSettings[i].materialReferences.Length]; // for (int j = 0; j < m_LodSettings[i].materialReferences.Length; j++) // { // m_materials[i][j] = Instantiate(m_LodSettings[i].materialReferences[j]) as Material; // } //} //opted to not instantiate so editor gives immediate feedback to material changes for (int i = 0; i < m_cachedNumLods; i++) { int numMaterials = m_LodSettings[i].materialReferences.Length; m_materials[i] = new Material[numMaterials]; for (int j = 0; j < numMaterials; j++) { m_materials[i][j] = m_LodSettings[i].materialReferences[j].material; } } Initialize(); #if (UNITY_EDITOR) if (!Application.isPlaying) { SceneViewInstancing.RegisterIndirectInstancedAsset(this); } #endif }
private void InitComputeShader() { m_instanceCount = m_instanceData.m_instanceCount; m_shadowRegionBuffer = m_shadowCullingManager._m_shadowRegionPlanes; m_computeShader.SetBuffer(m_cachedShadowComputeKernel, "gpuShadowRegionPlanes", m_shadowRegionBuffer); for (int i = 0; i < m_cachedNumLods; i++) { //create the append buffer for a given lod and bind it to the two compute kernels and all materials of that lod m_appendBuffers[i] = new ComputeBuffer(m_instanceCount, 36 * sizeof(float), ComputeBufferType.Counter); m_computeShader.SetBuffer(m_cachedComputeKernel, "lod" + i + "Buffer", m_appendBuffers[i]); m_computeShader.SetBuffer(m_cachedShadowComputeKernel, "lod" + i + "Buffer", m_appendBuffers[i]); //we can cache the strings for performance for (int j = 0; j < m_materials[i].Length; j++) { m_materials[i][j].SetBuffer("batchDataBuffer", m_appendBuffers[i]); } } m_positionBuffer = new ComputeBuffer(m_instanceCount, 4 * sizeof(float)); m_rotationBuffer = new ComputeBuffer(m_instanceCount, 4 * sizeof(float)); if (m_instanceData.m_UseCustomData) { m_customDataBuffer = new ComputeBuffer(m_instanceCount, 4 * sizeof(float)); } else { m_customDataBuffer = null; } for (int i = 0; i < m_cachedNumLods; i++) { for (int j = 0; j < m_LodSettings[i].mesh.subMeshCount; j++) { m_argsArray[i][j] = new uint[5]; m_argsBuffersArray[i][j] = new ComputeBuffer(1, m_argsArray[i][j].Length * sizeof(uint), ComputeBufferType.IndirectArguments); m_argsArray[i][j][0] = (uint)m_LodSettings[i].mesh.GetIndexCount(j); // - index count per instance, m_argsArray[i][j][1] = (uint)m_instanceCount; // - instance count, m_argsArray[i][j][2] = (uint)m_LodSettings[i].mesh.GetIndexStart(j); // - start index location, m_argsArray[i][j][3] = (uint)0; // - base vertex location m_argsArray[i][j][4] = (uint)0; // - start instance location. m_argsBuffersArray[i][j].SetData(m_argsArray[i][j]); } } m_instanceData.m_dataDirty = false; #if (UNITY_EDITOR) if (!Application.isPlaying) { SceneViewInstancing.UnregisterIndirectInstancedAsset(this); SceneViewInstancing.RegisterIndirectInstancedAsset(this); } #endif m_positions = m_instanceData.m_positions; m_rotations = m_instanceData.m_rotations; m_customData = m_instanceData.m_customData; Vector4 aabbExtents = m_LodSettings[0].mesh.bounds.extents; aabbExtents.w = InstancingUtilities.BoundingSphereFromAABB(aabbExtents.x, aabbExtents.y, aabbExtents.z); Vector4 aabbCenter = m_LodSettings[0].mesh.bounds.center; Vector4 screenSpaceLODSize = Vector4.zero; for (int i = 0; i < m_cachedNumLods; i++) { screenSpaceLODSize[i] = Mathf.Pow((m_LodSettings[i].screenSize * 0.5f), 2); } Vector2 screenDim = new Vector2(m_mainCamera.pixelWidth, m_mainCamera.pixelHeight); m_computeShader.SetVector("boundingExtents", aabbExtents); m_computeShader.SetVector("boundingCenter", aabbCenter); m_computeShader.SetVector("screenSpaceLODSize", screenSpaceLODSize); m_computeShader.SetVector("screenDim", screenDim); m_computeShader.SetInt("numLODs", (int)m_cachedNumLods); int[] shadowSettingsArray = new int[m_cachedNumLods]; for (int i = 0; i < m_cachedNumLods; i++) { shadowSettingsArray[i] = (int)m_LodSettings[i].shadowSetting; } m_computeShader.SetInts("castShadowsLOD", shadowSettingsArray); m_positionBuffer.SetData(m_positions); m_rotationBuffer.SetData(m_rotations); if (m_customDataBuffer != null) { m_customDataBuffer.SetData(m_customData); } m_computeShader.SetBuffer(m_cachedComputeKernel, "rotationBuffer", m_rotationBuffer); m_computeShader.SetBuffer(m_cachedComputeKernel, "positionBuffer", m_positionBuffer); if (m_customDataBuffer != null) { m_computeShader.SetBuffer(m_cachedComputeKernel, "customDataBuffer", m_customDataBuffer); } m_computeShader.SetBuffer(m_cachedShadowComputeKernel, "rotationBuffer", m_rotationBuffer); m_computeShader.SetBuffer(m_cachedShadowComputeKernel, "positionBuffer", m_positionBuffer); if (m_customDataBuffer != null) { m_computeShader.SetBuffer(m_cachedShadowComputeKernel, "customDataBuffer", m_customDataBuffer); } }