private void CollectPrimitives(out List <PTMaterial> materials, out List <Primitive> primitives, ref List <Texture2D> baseColorTextures, ref List <Texture2D> mroTextures, ref List <Texture2D> normalTextures) { MeshRenderer[] meshRenderers = Object.FindObjectsOfType <MeshRenderer>(); Dictionary <Material, List <Primitive> > primitivesWithMaterial = null; for (int i = 0; i < meshRenderers.Length; i++) { Primitive.CreatePrimitives(meshRenderers[i].gameObject, ref primitivesWithMaterial); } primitives = new List <Primitive>(); materials = new List <PTMaterial>(); float totalLightWeight = 0.0f; if (primitivesWithMaterial != null) { foreach (var kvp in primitivesWithMaterial) { if (kvp.Key == null || kvp.Value == null || kvp.Value.Count == 0) { continue; } PTMaterial ptmat = CreateMaterial(kvp.Key, ref baseColorTextures, ref mroTextures, ref normalTextures); for (int i = 0; i < kvp.Value.Count; i++) { Primitive primitive = kvp.Value[i]; primitive.matId = materials.Count; if (m_EnableNEE && ptmat.emission > 0 && (primitive.primitiveType == PrimitiveType.Sphere || primitive.primitiveType == PrimitiveType.Quad)) { PTLight light = new PTLight(primitive, ptmat); m_Lights.Add(light); float flux = light.GetFlux(); m_LightWeights.Add(flux); totalLightWeight += flux; continue; } primitives.Add(primitive); } materials.Add(ptmat); } } if (m_Lights.Count > 1) { for (int i = 0; i < m_Lights.Count; i++) { primitives.Add(m_Lights[i].primitive); } } for (int i = 0; i < m_LightWeights.Count; i++) { m_LightWeights[i] = m_LightWeights[i] / totalLightWeight; } }
public RenderTexture ExecutePipeline() { if (!IsInitialized) { return(null); } if (m_Lights != null && m_Lights.Count > 0) { float lightProbability = Random.Range(0.0f, 1.0f); float weight = 0.0f; PTLight currentLight = null; for (int i = 0; i < m_Lights.Count; i++) { if (m_LightWeights[i] + weight > lightProbability) { currentLight = m_Lights[i]; break; } weight += m_LightWeights[i]; } if (currentLight != null && (currentLight.primitive.primitiveType == PrimitiveType.Sphere || currentLight.primitive.primitiveType == PrimitiveType.Quad)) { if (currentLight.primitive.primitiveType == PrimitiveType.Sphere) { Sphere lightSphere = currentLight.primitive.CreateSphere(); Vector4 lightPosAndRadius = lightSphere.positionAndRadius; if (currentLight.primitive.IsChanged()) { isLightChanged = true; } m_PathTracingShader.SetVector("_LightCenterAndRadius", lightPosAndRadius); } else if (currentLight.primitive.primitiveType == PrimitiveType.Quad) { Quad lightQuad = currentLight.primitive.CreateQuad(); Vector4 lightRight = lightQuad.right; Vector4 lightForward = lightQuad.forward; Vector3 lightNormal = lightQuad.normal; Vector3 lightPosition = lightQuad.position; if (currentLight.primitive.IsChanged()) { isLightChanged = true; } m_PathTracingShader.SetVector("_LightRight", lightRight); m_PathTracingShader.SetVector("_LightForward", lightForward); m_PathTracingShader.SetVector("_LightPosition", lightPosition); m_PathTracingShader.SetVector("_LightNormal", lightNormal); } int lightMat = currentLight.primitive.matId; m_PathTracingShader.SetInt("_LightMatId", lightMat); m_PathTracingShader.SetInt("_LightPrimivateType", (int)currentLight.primitive.primitiveType); m_PathTracingShader.SetFloat("_LightPDF", currentLight.GetPDF()); } } float h = m_Camera.nearClipPlane * Mathf.Tan(m_Camera.fieldOfView * 0.5f * Mathf.Deg2Rad); float w = h * m_Camera.aspect; m_PathTracingShader.SetFloat("_NearClipPlane", m_Camera.nearClipPlane); m_PathTracingShader.SetFloat("_NearClipWidth", w); m_PathTracingShader.SetFloat("_NearClipHeight", h); m_PathTracingShader.SetMatrix("_PathTracerCameraToWorld", m_Camera.transform.localToWorldMatrix); m_PathTracingShader.SetFloat("_Time", Time.time); if (m_EnableThinLens) { m_PathTracingShader.SetFloat("_ThinLensFocal", focal); m_PathTracingShader.SetFloat("_ThinLensRadius", radius); } m_PathTracingShader.Dispatch(m_KernelIndex, m_DispatchThreadGroupsX, m_DispatchThreadGroupsY, 1); return(m_RenderTexture); }