public static void RenderIntoCubemap(Camera ownerCamera, Cubemap outCubemap) { int width = outCubemap.width; int height = outCubemap.height; CubemapFace[] array = new CubemapFace[6]; RuntimeHelpers.InitializeArray(array, fieldof(< PrivateImplementationDetails >.$field - DB17E883A647963A26D973378923EF4649801319).FieldHandle); CubemapFace[] array2 = array; Vector3[] array3 = new Vector3[] { new Vector3(0f, 90f, 0f), new Vector3(0f, -90f, 0f), new Vector3(-90f, 0f, 0f), new Vector3(90f, 0f, 0f), new Vector3(0f, 0f, 0f), new Vector3(0f, 180f, 0f) }; RenderTexture active = RenderTexture.active; float fieldOfView = ownerCamera.fieldOfView; float aspect = ownerCamera.aspect; Quaternion rotation = ownerCamera.transform.rotation; RenderTexture renderTexture = new RenderTexture(width, height, 24); renderTexture.antiAliasing = 8; renderTexture.dimension = TextureDimension.Tex2D; renderTexture.hideFlags = HideFlags.HideAndDontSave; Texture2D texture2D = new Texture2D(width, height, TextureFormat.RGB24, false); texture2D.hideFlags = HideFlags.HideAndDontSave; ownerCamera.targetTexture = renderTexture; ownerCamera.fieldOfView = 90f; ownerCamera.aspect = 1f; Color[] array4 = new Color[texture2D.height * texture2D.width]; for (int i = 0; i < array2.Length; i++) { ownerCamera.transform.eulerAngles = array3[i]; ownerCamera.Render(); RenderTexture.active = renderTexture; texture2D.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0); Color[] pixels = texture2D.GetPixels(); for (int j = 0; j < height; j++) { for (int k = 0; k < width; k++) { array4[j * width + k] = pixels[(height - 1 - j) * width + k]; } } outCubemap.SetPixels(array4, array2[i]); } outCubemap.SmoothEdges(); RenderTexture.active = active; ownerCamera.fieldOfView = fieldOfView; ownerCamera.aspect = aspect; ownerCamera.transform.rotation = rotation; ownerCamera.targetTexture = active; UnityEngine.Object.DestroyImmediate(texture2D); UnityEngine.Object.DestroyImmediate(renderTexture); }
private void CubemapToBitmapLayout() { cam.RenderToCubemap(tex, 63); tex.SmoothEdges(50); Unity.Collections.NativeArray <Color32> rawData = OutTex.GetRawTextureData <Color32>(); int index = 0; for (int i = CubemapFaces.Length; i > 0; --i) { Color[] face = tex.GetPixels(CubemapFaces[i - 1]); for (int y = 0; y < tex.height; y++) { for (int x = 0; x < tex.width; x++) { // invert the input tex since origin is bottom left corner int faceIndex = ((tex.height - 1 - y) * tex.width + x); rawData[index++] = face[faceIndex]; } } } OutTex.Apply(); }
public static int SmoothEdges(IntPtr l) { int result; try { int num = LuaDLL.lua_gettop(l); if (num == 2) { Cubemap cubemap = (Cubemap)LuaObject.checkSelf(l); int smoothRegionWidthInPixels; LuaObject.checkType(l, 2, out smoothRegionWidthInPixels); cubemap.SmoothEdges(smoothRegionWidthInPixels); LuaObject.pushValue(l, true); result = 1; } else if (num == 1) { Cubemap cubemap2 = (Cubemap)LuaObject.checkSelf(l); cubemap2.SmoothEdges(); LuaObject.pushValue(l, true); result = 1; } else { LuaObject.pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function SmoothEdges to call"); result = 2; } } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
static int SmoothEdges(IntPtr L) { int count = LuaDLL.lua_gettop(L); if (count == 1) { Cubemap obj = LuaScriptMgr.GetNetObject <Cubemap>(L, 1); obj.SmoothEdges(); return(0); } else if (count == 2) { Cubemap obj = LuaScriptMgr.GetNetObject <Cubemap>(L, 1); int arg0 = (int)LuaScriptMgr.GetNumber(L, 2); obj.SmoothEdges(arg0); return(0); } else { LuaDLL.luaL_error(L, "invalid arguments to method: Cubemap.SmoothEdges"); } return(0); }
IEnumerator RenderCubeFaces(Cubemap cube, bool irradiance) { if (irradiance) { size = (int)DiffSize; mipmap = false; } else { size = (int)SpecSize; mipmap = true; } cube = new Cubemap((int)size, texFor, mipmap); yield return(StartCoroutine(Capture(cube, CubemapFace.PositiveZ, CubeCamera))); yield return(StartCoroutine(Capture(cube, CubemapFace.PositiveX, CubeCamera))); yield return(StartCoroutine(Capture(cube, CubemapFace.NegativeX, CubeCamera))); yield return(StartCoroutine(Capture(cube, CubemapFace.NegativeZ, CubeCamera))); yield return(StartCoroutine(Capture(cube, CubemapFace.PositiveY, CubeCamera))); yield return(StartCoroutine(Capture(cube, CubemapFace.NegativeY, CubeCamera))); cube.Apply(mipmap); if (irradiance) { Cubemap diffCube = cube; diffCube.name = cubeName; if (SmoothEdges) { diffCube.SmoothEdges(SmoothEdgePixel); } diffCube.wrapMode = TextureWrapMode.Clamp; string finalDiffPath = diffCube.name + "DIFF.cubemap"; AssetDatabase.CreateAsset(diffCube, finalDiffPath); SerializedObject serializedCubemap = new SerializedObject(diffCube); SetLinearSpace(ref serializedCubemap, true); DIFFCube = diffCube; // DiffPath = finalDiffPath; } else { Cubemap specCube = cube; specCube.name = cubeName; if (SmoothEdges) { specCube.SmoothEdges(SmoothEdgePixel); } specCube.wrapMode = TextureWrapMode.Clamp; string finalSpecPath = specCube.name + "SPEC.cubemap"; AssetDatabase.CreateAsset(specCube, finalSpecPath); SerializedObject serializedCubemap = new SerializedObject(specCube); SetLinearSpace(ref serializedCubemap, true); SPECCube = specCube; // SpecPath = finalSpecPath; } yield return(StartCoroutine(Finished())); }
// Render Cubemaps using the built in function (pro only) public void RenderToCubeMap() { // Prepare PreSetup(); //Do directory check if (!Directory.Exists(sceneName)) { //if it doesn't, create it Directory.CreateDirectory(sceneName); } var cubeCamera = new GameObject("CubemapCamera", typeof(Camera)) as GameObject; // cubeCamera.hideFlags = HideFlags.HideInHierarchy; var cubeCam = cubeCamera.GetComponent("Camera") as Camera; cubeCam.nearClipPlane = Near; cubeCam.farClipPlane = Far; cubeCam.aspect = 1.0f; cubeCam.cullingMask = CullingMask; cubeCam.clearFlags = ClearFlags; cubeCam.backgroundColor = ClearColor; cubeCamera.transform.position = transform.position; if (HDR == true) { cubeCam.hdr = true; texFor = TextureFormat.ARGB32; } else { cubeCam.hdr = false; texFor = TextureFormat.RGB24; } // Irradiance cubemap cubemap = new Cubemap((int)DiffSize, texFor, false); cubeCam.RenderToCubemap(cubemap); Cubemap diffCube = cubemap; diffCube.name = cubeName; if (SmoothEdges) { diffCube.SmoothEdges(SmoothEdgePixel); } diffCube.wrapMode = TextureWrapMode.Clamp; string finalDiffPath = diffCube.name + "DIFF.cubemap"; AssetDatabase.CreateAsset(diffCube, finalDiffPath); SerializedObject serializedDiffCubemap = new SerializedObject(diffCube); SetLinearSpace(ref serializedDiffCubemap, true); DIFFCube = diffCube; // Radiance cubemap cubemap = new Cubemap((int)SpecSize, texFor, true); cubeCam.RenderToCubemap(cubemap); Cubemap specCube = cubemap; specCube.name = cubeName; if (SmoothEdges) { specCube.SmoothEdges(SmoothEdgePixel); } specCube.wrapMode = TextureWrapMode.Clamp; string finalSpecPath = specCube.name + "SPEC.cubemap"; AssetDatabase.CreateAsset(specCube, finalSpecPath); SerializedObject serializedSpecCubemap = new SerializedObject(specCube); SetLinearSpace(ref serializedSpecCubemap, true); SPECCube = specCube; GameObject.DestroyImmediate(cubeCamera); //RetrieveCubemaps(); }
/// <summary> /// Capture frame sync impl. /// </summary> void CaptureCubemapFrameSync() { int width = CubemapSize; int height = CubemapSize; CubemapFace[] faces = new CubemapFace[] { CubemapFace.PositiveX, CubemapFace.NegativeX, CubemapFace.PositiveY, CubemapFace.NegativeY, CubemapFace.PositiveZ, CubemapFace.NegativeZ }; Vector3[] faceAngles = new Vector3[] { new Vector3(0.0f, 90.0f, 0.0f), new Vector3(0.0f, -90.0f, 0.0f), new Vector3(-90.0f, 0.0f, 0.0f), new Vector3(90.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 180.0f, 0.0f) }; // Reset capture camera rotation. videoCamera.transform.eulerAngles = new Vector3(0.0f, 0.0f, 0.0f); // Create cubemap face render texture. RenderTexture faceTexture = new RenderTexture(width, height, 24); faceTexture.antiAliasing = AntiAliasing; #if !(UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3) faceTexture.dimension = UnityEngine.Rendering.TextureDimension.Tex2D; #endif faceTexture.hideFlags = HideFlags.HideAndDontSave; // For intermediate saving Texture2D swapTexture = new Texture2D(width, height, TextureFormat.RGB24, false); swapTexture.hideFlags = HideFlags.HideAndDontSave; // Prepare for target render texture. videoCamera.targetTexture = faceTexture; // TODO, make this into shader for GPU fast processing. if (projectionType == PanoramaProjectionType.CUBEMAP) { for (int i = 0; i < faces.Length; i++) { videoCamera.transform.eulerAngles = faceAngles[i]; videoCamera.Render(); RenderTexture.active = faceTexture; swapTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); Color[] pixels = swapTexture.GetPixels(); switch (i) { case (int)CubemapFace.PositiveX: frameTexture.SetPixels(0, height, width, height, pixels); break; case (int)CubemapFace.NegativeX: frameTexture.SetPixels(width, height, width, height, pixels); break; case (int)CubemapFace.PositiveY: frameTexture.SetPixels(width * 2, height, width, height, pixels); break; case (int)CubemapFace.NegativeY: frameTexture.SetPixels(0, 0, width, height, pixels); break; case (int)CubemapFace.PositiveZ: frameTexture.SetPixels(width, 0, width, height, pixels); break; case (int)CubemapFace.NegativeZ: frameTexture.SetPixels(width * 2, 0, width, height, pixels); break; } } frameTexture.Apply(); } else if (projectionType == PanoramaProjectionType.EQUIRECTANGULAR) { Color[] mirroredPixels = new Color[swapTexture.height * swapTexture.width]; for (int i = 0; i < faces.Length; i++) { videoCamera.transform.eulerAngles = faceAngles[i]; videoCamera.Render(); RenderTexture.active = faceTexture; swapTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); // Mirror vertically to meet the standard of unity cubemap. Color[] OrignalPixels = swapTexture.GetPixels(); for (int y1 = 0; y1 < height; y1++) { for (int x1 = 0; x1 < width; x1++) { mirroredPixels[y1 * width + x1] = OrignalPixels[((height - 1 - y1) * width) + x1]; } } frameCubemap.SetPixels(mirroredPixels, faces[i]); } frameCubemap.SmoothEdges(); frameCubemap.Apply(); // Convert to equirectangular projection. Graphics.Blit(frameCubemap, frameRenderTexture, transformMaterial); // From frameRenderTexture to frameTexture. CopyFrameTexture(); } RenderTexture.active = null; videoCamera.targetTexture = null; // Clean temp texture. DestroyImmediate(swapTexture); DestroyImmediate(faceTexture); // Send for encoding. EnqueueFrameTexture(); }
private void OnGUI() { //input section EditorGUILayout.Space(); EditorGUILayout.PropertyField(sp_input_cubemap); //input texture info if (input_cubemap != null) { string info = input_cubemap.width.ToString() + "x" + input_cubemap.height.ToString() + " " + input_cubemap.format.ToString(); EditorGUILayout.LabelField(info); } EditorGUILayout.Space(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); EditorGUILayout.Space(); EditorGUILayout.PropertyField(sp_output_size); EditorGUILayout.PropertyField(sp_output_format); EditorGUILayout.PropertyField(sp_output_srgb); EditorGUILayout.PropertyField(sp_brdf); if (brdf == BRDF.Phong) { EditorGUILayout.PropertyField(sp_startAlpha); EditorGUILayout.PropertyField(sp_alphaMipDrop); } so.ApplyModifiedProperties(); //prefilter section GUI.enabled = input_cubemap != null; if (GUILayout.Button("Prefilter")) { num_mips = Mathf.Min(6, 1 + (int)Mathf.Log((float)((int)output_size), 2)); //max 6 mipmaps input_cubemap.filterMode = FilterMode.Trilinear; input_cubemap.wrapMode = TextureWrapMode.Clamp; //input_cubemap.SmoothEdges(); RenderTextureDescriptor rtd = new RenderTextureDescriptor(); rtd.autoGenerateMips = false; rtd.colorFormat = output_format; rtd.depthBufferBits = 0; rtd.dimension = TextureDimension.Cube; rtd.enableRandomWrite = false; rtd.height = (int)output_size; rtd.memoryless = RenderTextureMemoryless.None; rtd.msaaSamples = 1; rtd.shadowSamplingMode = ShadowSamplingMode.None; rtd.sRGB = output_srgb; rtd.useMipMap = true; rtd.volumeDepth = 1; rtd.width = (int)output_size; output_cubemap = new RenderTexture(rtd); output_cubemap.filterMode = FilterMode.Trilinear; output_cubemap.wrapMode = TextureWrapMode.Clamp; CommandBuffer cb = new CommandBuffer(); Material mat = null; if (brdf == BRDF.Phong) { mat = new Material(Shader.Find("PBR/EnvMapPrefilter_Phong")); } else if (brdf == BRDF.GGX) { mat = new Material(Shader.Find("PBR/EnvMapPrefilter_GGX")); } mat.SetTexture("input_envmap", input_cubemap); mat.SetFloat("_CubeSize", rtd.width); mat.SetFloat("numLod", num_mips); float alpha = startAlpha; if (brdf == BRDF.GGX) { alpha = 0.0f; } //cycle mips and faces for (int mip = 0; mip < num_mips; ++mip) { if (brdf == BRDF.GGX) { alpha = mip / (float)(num_mips - 1); } cb.SetGlobalFloat("_Lod", mip); cb.SetGlobalFloat("alpha", alpha); for (int face = 0; face < 6; ++face) { cb.SetRenderTarget(output_cubemap, mip, (CubemapFace)face); cb.SetGlobalFloat("face", face); cb.DrawProcedural(Matrix4x4.identity, mat, 0, MeshTopology.Triangles, 3); } if (brdf == BRDF.Phong) { alpha *= alphaMipDrop; } } Graphics.ExecuteCommandBuffer(cb); Object.DestroyImmediate(mat); } //this is for saving the precomputed second term of the splitted sum formula (from the UE4 pbr paper) if (brdf == BRDF.GGX) { if (GUILayout.Button("Save GGX BRDF")) { RenderTexture brdf_rt = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); brdf_rt.Create(); Material mat = new Material(Shader.Find("PBR/EnvMapPrefilter_GGX")); CommandBuffer cb = new CommandBuffer(); cb.SetRenderTarget(brdf_rt); cb.DrawProcedural(Matrix4x4.identity, mat, 1, MeshTopology.Triangles, 3); Graphics.ExecuteCommandBuffer(cb); Object.DestroyImmediate(mat); Texture2D brdf_tex = new Texture2D(512, 512, TextureFormat.RGBAFloat, false, true); brdf_tex.wrapMode = TextureWrapMode.Clamp; RenderTexture.active = brdf_rt; brdf_tex.ReadPixels(new Rect(0, 0, 512, 512), 0, 0); brdf_tex.Apply(); AssetDatabase.CreateAsset(brdf_tex, "Assets/ggx_brdf.asset"); } } //save section GUI.enabled = true; EditorGUILayout.Space(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); EditorGUILayout.Space(); so.ApplyModifiedProperties(); EditorGUILayout.Space(); prefiltered_name = EditorGUILayout.TextField("Prefiltered name", prefiltered_name); bool save_enabled = prefiltered_name != "" && output_cubemap != null; GUI.enabled = save_enabled; if (GUILayout.Button("Save")) { int current_size = (int)output_size; Cubemap asset_to_save = new Cubemap(current_size, ConvertFormat(output_format), true); asset_to_save.filterMode = FilterMode.Trilinear; asset_to_save.wrapMode = TextureWrapMode.Clamp; RenderTextureDescriptor desc = new RenderTextureDescriptor(); desc.autoGenerateMips = false; desc.colorFormat = output_format; desc.depthBufferBits = 0; desc.dimension = TextureDimension.Tex2D; desc.enableRandomWrite = false; desc.msaaSamples = 1; desc.sRGB = output_cubemap.sRGB; desc.useMipMap = true; desc.volumeDepth = 1; //cycle foreach mip level and foreach face for (int mip = 0; mip < num_mips; ++mip) { //need a temporary texture2d and render target Texture2D tmp_tex = new Texture2D(current_size, current_size, asset_to_save.format, false, output_cubemap.sRGB); tmp_tex.filterMode = FilterMode.Trilinear; tmp_tex.wrapMode = TextureWrapMode.Clamp; desc.width = desc.height = current_size; RenderTexture tmp_rt = new RenderTexture(desc); tmp_rt.filterMode = FilterMode.Trilinear; tmp_rt.wrapMode = TextureWrapMode.Clamp; tmp_rt.Create(); for (int face = 0; face < 6; ++face) { //first copy the selected face for the selected mip into the temporary render target Graphics.CopyTexture(output_cubemap, face, mip, tmp_rt, 0, 0); //then copy from the temporary render target to the temporary texture 2d RenderTexture.active = tmp_rt; tmp_tex.ReadPixels(new Rect(0, 0, current_size, current_size), 0, 0, false); //then from the temporary texture to the cubemap (all of this workaround is because cubemap class doesn't provide a ReadPixels method) Color[] colors = tmp_tex.GetPixels(); Color[] flipped = new Color[colors.Length]; //need to flip the y for (int y = 0; y < current_size; ++y) { for (int x = 0; x < current_size; ++x) { int flipped_y = current_size - 1 - y; int src_index = flipped_y * current_size + x; int dest_index = y * current_size + x; flipped[dest_index] = colors[src_index]; } } asset_to_save.SetPixels(flipped, (CubemapFace)face, mip); } current_size /= 2; } asset_to_save.Apply(false); asset_to_save.SmoothEdges(10); AssetDatabase.CreateAsset(asset_to_save, prefiltered_name); } GUI.enabled = output_cubemap != null; if (GUILayout.Button("Delete")) { output_cubemap.Release(); Object.DestroyImmediate(output_cubemap); output_cubemap = null; } //view section EditorGUILayout.Space(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); EditorGUILayout.Space(); GUI.enabled = output_cubemap != null; if (GUILayout.Button("View")) { view_mat = new Material(Shader.Find("PBR/EnvMapShader")); view_mat.SetTexture("_EnvMap", output_cubemap); view_mat.SetFloat("_LodLevel", view_mip); RenderSettings.skybox = view_mat; } EditorGUI.BeginChangeCheck(); view_mip = (int)EditorGUILayout.Slider("Mip level", view_mip, 0, num_mips); if (EditorGUI.EndChangeCheck()) { view_mat.SetFloat("_LodLevel", view_mip); } GUI.enabled = true; }
public static void RenderIntoCubemap(Camera ownerCamera, Cubemap outCubemap) { int width = (int)outCubemap.width; int height = (int)outCubemap.height; CubemapFace[] faces = new CubemapFace[] { CubemapFace.PositiveX, CubemapFace.NegativeX, CubemapFace.PositiveY, CubemapFace.NegativeY, CubemapFace.PositiveZ, CubemapFace.NegativeZ }; Vector3[] faceAngles = new Vector3[] { new Vector3(0.0f, 90.0f, 0.0f), new Vector3(0.0f, -90.0f, 0.0f), new Vector3(-90.0f, 0.0f, 0.0f), new Vector3(90.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 180.0f, 0.0f) }; // Backup states RenderTexture backupRenderTex = RenderTexture.active; float backupFieldOfView = ownerCamera.fieldOfView; float backupAspect = ownerCamera.aspect; Quaternion backupRot = ownerCamera.transform.rotation; //RenderTexture backupRT = ownerCamera.targetTexture; // Enable 8X MSAA RenderTexture faceTexture = new RenderTexture(width, height, 24); faceTexture.antiAliasing = 8; #if !(UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3) faceTexture.dimension = UnityEngine.Rendering.TextureDimension.Tex2D; #endif faceTexture.hideFlags = HideFlags.HideAndDontSave; // For intermediate saving Texture2D swapTex = new Texture2D(width, height, TextureFormat.RGB24, false); swapTex.hideFlags = HideFlags.HideAndDontSave; // Capture 6 Directions ownerCamera.targetTexture = faceTexture; ownerCamera.fieldOfView = 90; ownerCamera.aspect = 1.0f; Color[] mirroredPixels = new Color[swapTex.height * swapTex.width]; for (int i = 0; i < faces.Length; i++) { ownerCamera.transform.eulerAngles = faceAngles[i]; ownerCamera.Render(); RenderTexture.active = faceTexture; swapTex.ReadPixels(new Rect(0, 0, width, height), 0, 0); // Mirror vertically to meet the standard of unity cubemap Color[] OrignalPixels = swapTex.GetPixels(); for (int y1 = 0; y1 < height; y1++) { for (int x1 = 0; x1 < width; x1++) { mirroredPixels[y1 * width + x1] = OrignalPixels[((height - 1 - y1) * width) + x1]; } } ; outCubemap.SetPixels(mirroredPixels, faces[i]); } outCubemap.SmoothEdges(); // Restore states RenderTexture.active = backupRenderTex; ownerCamera.fieldOfView = backupFieldOfView; ownerCamera.aspect = backupAspect; ownerCamera.transform.rotation = backupRot; ownerCamera.targetTexture = backupRenderTex; DestroyImmediate(swapTex); DestroyImmediate(faceTexture); }
private static void ReplaceCubemap(CubemapReplacement replacement) { if (replacement.IsNight) { RevertNightCubemap(); } else { RevertDayCubemap(); } var cubemap = new Cubemap(replacement.Size, TextureFormat.ARGB32, true) { name = "CubemapReplacerCubemap", wrapMode = TextureWrapMode.Clamp }; var prefix = replacement.FilePrefix; if (replacement.SplitFormat) { var posx = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "posx.png")); SetCubemapFaceSolid(posx, CubemapFace.PositiveX, cubemap, 2, 0); Object.Destroy(posx); var posy = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "posy.png")); SetCubemapFaceSolid(posy, CubemapFace.PositiveY, cubemap, 2, 0); Object.Destroy(posy); var posz = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "posz.png")); SetCubemapFaceSolid(posz, CubemapFace.PositiveZ, cubemap, 2, 0); Object.Destroy(posz); var negx = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "negx.png")); SetCubemapFaceSolid(negx, CubemapFace.NegativeX, cubemap, 2, 0); Object.Destroy(negx); var negy = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "negy.png")); SetCubemapFaceSolid(negy, CubemapFace.NegativeY, cubemap, 2, 0); Object.Destroy(negy); var negz = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "negz.png")); SetCubemapFaceSolid(negz, CubemapFace.NegativeZ, cubemap, 2, 0); Object.Destroy(negz); } else { var texture = Util.LoadTextureFromFile(Path.Combine(replacement.Directory, prefix + "cubemap.png")); SetCubemapFaceSolid(texture, CubemapFace.PositiveX, cubemap, 1, 2); SetCubemapFaceSolid(texture, CubemapFace.PositiveY, cubemap, 0, 1); SetCubemapFaceSolid(texture, CubemapFace.PositiveZ, cubemap, 1, 1); SetCubemapFaceSolid(texture, CubemapFace.NegativeX, cubemap, 1, 0); SetCubemapFaceSolid(texture, CubemapFace.NegativeY, cubemap, 2, 1); SetCubemapFaceSolid(texture, CubemapFace.NegativeZ, cubemap, 1, 3); Object.Destroy(texture); } cubemap.anisoLevel = 9; cubemap.filterMode = FilterMode.Trilinear; cubemap.SmoothEdges(); cubemap.Apply(); if (replacement.IsNight) { Object.FindObjectOfType <DayNightProperties>().m_OuterSpaceCubemap = cubemap; customNightCubemap = cubemap; } else { Shader.SetGlobalTexture("_EnvironmentCubemap", cubemap); customDayCubemap = cubemap; } }
// This is the coroutine that creates the cubemap images IEnumerator CreateCubeMap(bool diffuse) { int size; if (diffuse == true) { size = CubeSizeSetup(true); } else { size = CubeSizeSetup(false); } Cubemap tempCube = new Cubemap(size, TextureFormat.ARGB32, true); yield return(StartCoroutine(Capture(tempCube, CubemapFace.PositiveZ, cubeCamera))); yield return(StartCoroutine(Capture(tempCube, CubemapFace.PositiveX, cubeCamera))); yield return(StartCoroutine(Capture(tempCube, CubemapFace.NegativeX, cubeCamera))); yield return(StartCoroutine(Capture(tempCube, CubemapFace.NegativeZ, cubeCamera))); yield return(StartCoroutine(Capture(tempCube, CubemapFace.PositiveY, cubeCamera))); yield return(StartCoroutine(Capture(tempCube, CubemapFace.NegativeY, cubeCamera))); // v0.035 this fix the ugly mipmap transition tempCube.filterMode = FilterMode.Trilinear; tempCube.wrapMode = TextureWrapMode.Clamp; if (SystemInfo.graphicsShaderLevel != 50) { tempCube.SmoothEdges(smoothEdge); } tempCube.Apply(); if (diffuse == true) { diffuseCube = tempCube; string diffusePath = GetOutPutPath(diffuseCube, true); AssetDatabase.CreateAsset(diffuseCube, diffusePath); SerializedObject serializedCubemap = new SerializedObject(diffuseCube); SetLinearSpace(ref serializedCubemap, false); } else { specularCube = tempCube; string specularPath = GetOutPutPath(specularCube, false); AssetDatabase.CreateAsset(specularCube, specularPath); SerializedObject serializedCubemap = new SerializedObject(specularCube); SetLinearSpace(ref serializedCubemap, false); } yield return(StartCoroutine(CaptureFinished())); }
IEnumerator ConvolveSpecularCubeMap() { int size = 0; int samples = 0; size = CubeSizeSetup(false); samples = qualitySetup(false); if (radianceModel == radianceEnum.BlinnPhong) { convolveSpecularSkybox = new Material(Shader.Find("Hidden/Antonov Suit/Radiance/Blinn")); } if (radianceModel == radianceEnum.GGX) { convolveSpecularSkybox = new Material(Shader.Find("Hidden/Antonov Suit/Radiance/GGX")); } convolveSpecularSkybox.SetInt("_specSamples", samples); convolveSpecularSkybox.SetInt("_specularSize", size); convolveSpecularSkybox.SetTexture("_SpecCubeIBL", specularCube); UnityEngine.RenderSettings.skybox = convolveSpecularSkybox; Cubemap tempCube = new Cubemap(size, TextureFormat.ARGB32, true); for (int mip = 0; (size >> mip) > 0; mip++) { // v0.049 float minExponent = 0.1f; float stepExp = 1 / (float)specularExponent * (float)mip + 0.01f; float exponent = Mathf.Max(stepExp, minExponent); convolveSpecularSkybox.SetFloat("_Shininess", exponent); int cubeSize = Mathf.Max(1, tempCube.width >> mip); Cubemap mipCube = new Cubemap(cubeSize, TextureFormat.ARGB32, false); if (hasPro == true) { cubeCamera.RenderToCubemap(mipCube); for (int f = 0; f < 6; ++f) { CubemapFace face = (CubemapFace)f; tempCube.SetPixels(mipCube.GetPixels(face), face, mip); } } else { yield return(StartCoroutine(CaptureImportanceSample(tempCube, CubemapFace.PositiveZ, cubeCamera, mip))); yield return(StartCoroutine(CaptureImportanceSample(tempCube, CubemapFace.PositiveX, cubeCamera, mip))); yield return(StartCoroutine(CaptureImportanceSample(tempCube, CubemapFace.NegativeX, cubeCamera, mip))); yield return(StartCoroutine(CaptureImportanceSample(tempCube, CubemapFace.NegativeZ, cubeCamera, mip))); yield return(StartCoroutine(CaptureImportanceSample(tempCube, CubemapFace.PositiveY, cubeCamera, mip))); yield return(StartCoroutine(CaptureImportanceSample(tempCube, CubemapFace.NegativeY, cubeCamera, mip))); } } // v0.035 this fix the ugly mipmap transition tempCube.filterMode = FilterMode.Trilinear; tempCube.wrapMode = TextureWrapMode.Clamp; if (SystemInfo.graphicsShaderLevel != 50) { tempCube.SmoothEdges(smoothEdge); } tempCube.Apply(false); specularCube = tempCube; string convolvedSpecularPath = GetOutPutPath(specularCube, false); AssetDatabase.CreateAsset(specularCube, convolvedSpecularPath); SerializedObject serializedCubemap = new SerializedObject(specularCube); SetLinearSpace(ref serializedCubemap, false); yield return(StartCoroutine(CaptureFinished())); }
public void TakeScreenshot() { int width = 1024; int height = 1024; CubemapFace[] faces = new CubemapFace[] { CubemapFace.PositiveX, CubemapFace.NegativeX, CubemapFace.PositiveY, CubemapFace.NegativeY, CubemapFace.PositiveZ, CubemapFace.NegativeZ }; Vector3[] faceAngles = new Vector3[] { new Vector3(0.0f, 90.0f, 0.0f), new Vector3(0.0f, -90.0f, 0.0f), new Vector3(-90.0f, 0.0f, 0.0f), new Vector3(90.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 180.0f, 0.0f) }; Camera.transform.eulerAngles = new Vector3(0.0f, 0.0f, 0.0f); // Create cubemap face render texture. RenderTexture faceTexture = new RenderTexture(width, height, 24); faceTexture.antiAliasing = 4; #if !(UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3) faceTexture.dimension = UnityEngine.Rendering.TextureDimension.Tex2D; #endif faceTexture.hideFlags = HideFlags.HideAndDontSave; // For intermediate saving Texture2D swapTexture = new Texture2D(width, height, TextureFormat.RGB24, false); swapTexture.hideFlags = HideFlags.HideAndDontSave; // Prepare for target render texture. Camera.targetTexture = faceTexture; Color[] mirroredPixels = new Color[swapTexture.height * swapTexture.width]; for (int i = 0; i < faces.Length; i++) { Camera.transform.eulerAngles = faceAngles[i]; Camera.Render(); RenderTexture.active = faceTexture; swapTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); // Mirror vertically to meet the standard of unity cubemap. Color[] OrignalPixels = swapTexture.GetPixels(); for (int y1 = 0; y1 < height; y1++) { for (int x1 = 0; x1 < width; x1++) { mirroredPixels[y1 * width + x1] = OrignalPixels[((height - 1 - y1) * width) + x1]; } } frameCubemap.SetPixels(mirroredPixels, faces[i]); } frameCubemap.SmoothEdges(); frameCubemap.Apply(); // Convert to equirectangular projection. Graphics.Blit(frameCubemap, frameRenderTexture, transformMaterial); // Bind texture. RenderTexture.active = frameRenderTexture; // TODO, remove expensive step of copying pixel data from GPU to CPU. frameTexture.ReadPixels(new Rect(0, 0, 4096, 2048), 0, 0, false); frameTexture.Apply(); // Save frameTexture to file. try { // Encode the texture and save it to disk byte[] bytes = frameTexture.EncodeToPNG(); string path = PathConfig.saveFolder + StringUtils.GetPngFileName(null); System.IO.File.WriteAllBytes(path, bytes); } catch (System.Exception e) { Debug.LogError("Failed to save equirectangular file since " + e.ToString()); return; } // Restore RenderTexture states. RenderTexture.active = null; RenderTexture.active = null; Camera.targetTexture = null; // Clean temp texture. DestroyImmediate(swapTexture); DestroyImmediate(faceTexture); }