private void setFaceAverage(ref Cubemap filteredCubeMap, int a, int b, int c, int d, int e, int f) { Color average = (filteredCubeMap.GetPixel((CubemapFace)a, b, c) + filteredCubeMap.GetPixel((CubemapFace)d, e, f)) / 2.0f; filteredCubeMap.SetPixel((CubemapFace)a, b, c, average); filteredCubeMap.SetPixel((CubemapFace)d, e, f, average); }
private void setCornerAverage(ref Cubemap filteredCubeMap, int a, int b, int c, int d, int e, int f, int g, int h, int i) { Color average = (filteredCubeMap.GetPixel((CubemapFace)a, b, c) + filteredCubeMap.GetPixel((CubemapFace)d, e, f) + filteredCubeMap.GetPixel((CubemapFace)g, h, i)) / 3.0f; filteredCubeMap.SetPixel((CubemapFace)a, b, c, average); filteredCubeMap.SetPixel((CubemapFace)d, e, f, average); filteredCubeMap.SetPixel((CubemapFace)g, h, i, average); }
private Cubemap InterpolateTexture(Cubemap tex0, Cubemap tex1, Cubemap tex2, Vector3 weight) { Cubemap result = new Cubemap(256, TextureFormat.Alpha8, true); foreach (CubemapFace face in System.Enum.GetValues(typeof(CubemapFace))) { if (face == CubemapFace.Unknown) { continue; } for (int y = 0; y < 256; ++y) { for (int x = 0; x < 256; ++x) { Color c0 = tex0.GetPixel(face, x, y); Color c1 = tex1.GetPixel(face, x, y); Color c2 = tex2.GetPixel(face, x, y); Color color = weight.x * c0 + weight.y * c1 + weight.z * c2; result.SetPixel(face, x, y, color); } } } result.Apply(); return(result); }
public static int SetPixel(IntPtr l) { int result; try { Cubemap cubemap = (Cubemap)LuaObject.checkSelf(l); CubemapFace face; LuaObject.checkEnum <CubemapFace>(l, 2, out face); int x; LuaObject.checkType(l, 3, out x); int y; LuaObject.checkType(l, 4, out y); Color color; LuaObject.checkType(l, 5, out color); cubemap.SetPixel(face, x, y, color); LuaObject.pushValue(l, true); result = 1; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
void TestGenerateSpecCubemap() { float dv = 1.0f / m_Cubemap.height; float du = 1.0f / m_Cubemap.width; float uoffs = 0.5f / m_Cubemap.width; float voffs = 0.5f / m_Cubemap.height; m_DbgLightDir0.Normalize(); m_DbgLightDir1.Normalize(); foreach (CubemapFace face in CubemapFace.GetValues(typeof(CubemapFace))) { for (int y = 0; y < m_Cubemap.height; y++) { float v = y * dv + voffs; for (int x = 0; x < m_Cubemap.width; x++) { float u = x * du + uoffs; Vector3 dir = UVToDir(u, v, face); dir.Normalize(); m_Cubemap.SetPixel(face, x, y, EvalSpecLighting(dir)); } } } m_Cubemap.Apply(); }
IEnumerator Capture(Cubemap cubemap, CubemapFace face, Camera cam) { var width = Screen.width; var height = Screen.height; Texture2D tex = new Texture2D(height, height, texFor, mipmap); int cubeSize = cubemap.height; cam.transform.localRotation = RotationOf(face); yield return(new WaitForEndOfFrame()); tex.ReadPixels(new Rect((width - height) / 2, 0, height, height), 0, 0); tex.Apply(); tex = Scale(tex, cubeSize, cubeSize); Color cubeCol; for (int y = 0; y < cubeSize; y++) { for (int x = 0; x < cubeSize; x++) { cubeCol = tex.GetPixel(cubeSize + x, (cubeSize - 1) - y); if (Linear) { cubeCol = cubeCol.linear; } cubemap.SetPixel(face, x, y, cubeCol); } } cubemap.Apply(); DestroyImmediate(tex); }
public void CopyToFace() { if (cubemapResolution != sourceTextureResolution.x || cubemapResolution != sourceTextureResolution.y) { throw new Exception("Panoramic texture to cubemap texture generator error: cubemap resolution is different from source texture width or height."); } for (int x = 0; x < cubemapResolution; x++) { for (int y = 0; y < cubemapResolution; y++) { targetCubemap.SetPixel(targetFace, x, y, sourceTexture.GetPixel(x, y)); } } targetCubemap.Apply(); }
static int SetPixel(IntPtr L) { LuaScriptMgr.CheckArgsCount(L, 5); Cubemap obj = LuaScriptMgr.GetNetObject <Cubemap>(L, 1); CubemapFace arg0 = LuaScriptMgr.GetNetObject <CubemapFace>(L, 2); int arg1 = (int)LuaScriptMgr.GetNumber(L, 3); int arg2 = (int)LuaScriptMgr.GetNumber(L, 4); Color arg3 = LuaScriptMgr.GetNetObject <Color>(L, 5); obj.SetPixel(arg0, arg1, arg2, arg3); return(0); }
private static void SetCubemapFaceSolid(Texture2D texture, CubemapFace face, Cubemap cubemap, int positionY, int positionX) { for (var x = 0; x < cubemap.width; x++) { for (var y = 0; y < cubemap.height; y++) { var sourceX = positionX * cubemap.width + x; var sourceY = (2 - positionY) * cubemap.height + (cubemap.height - y - 1); var color = texture.GetPixel(sourceX, sourceY); cubemap.SetPixel(face, x, y, color); } } }
//Reads the pixels in from the side, and assigns it to the proper face of the cubemap private void AssignCubemapFace(Texture2D side, CubemapFace cubemapFace) { for (int i = 0; i < _size; i++) { for (int j = 0; j < _size; j++) { Color pixel = side.GetPixel(i, j); _tempCubeMap.SetPixel(cubemapFace, i, j, pixel); } } _tempCubeMap.Apply(); }
// Use this for initialization void Start() { cam = GameObject.Find("Camera"); //gameObject.transform.eulerAngles = new Vector3(0,0,0); Mesh mesh = gameObject.GetComponent <MeshFilter>().mesh; child0 = new GameObject("child0"); child0.AddComponent <MeshFilter>(); child0.AddComponent <MeshRenderer>(); child0.transform.position = gameObject.transform.position; child0.transform.parent = gameObject.transform; child0.GetComponent <MeshFilter>().mesh = mesh; child0.GetComponent <MeshRenderer>().material = gameObject.GetComponent <MeshRenderer>().material; //child0.transform.localScale = new Vector3(1,1,1); child0.transform.eulerAngles = new Vector3(0, 90, 0); child1 = new GameObject("child1"); child1.AddComponent <MeshFilter>(); child1.AddComponent <MeshRenderer>(); child1.transform.position = gameObject.transform.position; child1.transform.parent = gameObject.transform; child1.GetComponent <MeshFilter>().mesh = mesh; child1.GetComponent <MeshRenderer>().material = gameObject.GetComponent <MeshRenderer>().material; //child0.transform.localScale = new Vector3(1,1,1); child1.transform.eulerAngles = new Vector3(0, 180, 0); child2 = new GameObject("child2"); child2.AddComponent <MeshFilter>(); child2.AddComponent <MeshRenderer>(); child2.transform.position = gameObject.transform.position; child2.transform.parent = gameObject.transform; child2.GetComponent <MeshFilter>().mesh = mesh; child2.GetComponent <MeshRenderer>().material = gameObject.GetComponent <MeshRenderer>().material; //child0.transform.localScale = new Vector3(1,1,1); child2.transform.eulerAngles = new Vector3(0, 270, 0); gameObject.transform.up = cam.transform.position - gameObject.transform.position; int width = 256; heightMap = new Cubemap(width, TextureFormat.ARGB32, false); for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { heightMap.SetPixel(CubemapFace.NegativeX, i, j, new Color(1, 0, 0, 1)); heightMap.SetPixel(CubemapFace.NegativeY, i, j, new Color(1, 1, 0, 1)); heightMap.SetPixel(CubemapFace.NegativeZ, i, j, new Color(1, 0, 1, 1)); heightMap.SetPixel(CubemapFace.PositiveX, i, j, new Color(1, 1, 0.5f, 1)); heightMap.SetPixel(CubemapFace.PositiveY, i, j, new Color(1, 1, 0.75f, 1)); heightMap.SetPixel(CubemapFace.PositiveZ, i, j, new Color(1, 1, 1, 1)); } } heightMap.Apply(); }
void createPlaceHolderCube() { if (PlaceHolderCube == null) { PlaceHolderCube = new Cubemap(16, TextureFormat.ARGB32, true); for (int face = 0; face < 6; face++) { for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { PlaceHolderCube.SetPixel((CubemapFace)face, x, y, Color.black); } } } PlaceHolderCube.Apply(true); } }
IEnumerator Snapshot(Cubemap cubemap, CubemapFace face, Camera cam) { int width = Screen.width; int height = Screen.height; Texture2D tex = new Texture2D(height, height, textureFormat, mipmap); cam.transform.localRotation = Rotation(face); yield return(new WaitForEndOfFrame()); tex.ReadPixels(new Rect((width - height) / 2, 0, height, height), 0, 0); tex.Apply(); tex = Scale(tex, this.size, this.size); Color[] colors = tex.GetPixels(); for (int i = 0; i < colors.Length; i++) { cubemap.SetPixel(face, this.size - (i % this.size) - 1, (int)Mathf.Floor(i / this.size), colors[colors.Length - i - 1]); } }
protected override void Init(PipelineResources resources) { proper = RenderPipeline.GetEvent <PropertySetEvent>(); if (useEmissionGeometry) { geometry.Init(); } if (useNoiseEvents) { noiseEvents.Init(resources); } lightingData = RenderPipeline.GetEvent <LightingEvent>(); reflectData = RenderPipeline.GetEvent <ReflectionEvent>(); lightingMat = new Material(resources.shaders.volumetricShader); cameraNormalBuffer = new ComputeBuffer(3, sizeof(float3)); blackCB = new Cubemap(1, TextureFormat.ARGB32, false); blackCB.SetPixel(CubemapFace.NegativeX, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.NegativeY, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.NegativeZ, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.PositiveX, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.PositiveX, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.PositiveX, 0, 0, Color.black); volumeDesc = new RenderTextureDescriptor { autoGenerateMips = false, bindMS = false, colorFormat = RenderTextureFormat.ARGBHalf, depthBufferBits = 0, dimension = TextureDimension.Tex3D, enableRandomWrite = true, height = downSampledSize.y, width = downSampledSize.x, memoryless = RenderTextureMemoryless.None, msaaSamples = 1, shadowSamplingMode = ShadowSamplingMode.None, sRGB = false, useMipMap = false, volumeDepth = downSampledSize.z, vrUsage = VRTextureUsage.None }; volumeTex = new RenderTexture(volumeDesc); volumeTex.filterMode = FilterMode.Bilinear; volumeTex.wrapMode = TextureWrapMode.Clamp; volumeTex.Create(); }
protected virtual void CheckSkyboxTexture() { if (effectSkybox == null) { Cubemap tempTexture = new Cubemap(1, TextureFormat.ARGB32, false); tempTexture.SetPixel(CubemapFace.NegativeX, 0, 0, Color.white); tempTexture.SetPixel(CubemapFace.NegativeY, 0, 0, Color.white); tempTexture.SetPixel(CubemapFace.NegativeZ, 0, 0, Color.white); tempTexture.SetPixel(CubemapFace.PositiveX, 0, 0, Color.white); tempTexture.SetPixel(CubemapFace.PositiveY, 0, 0, Color.white); tempTexture.SetPixel(CubemapFace.PositiveZ, 0, 0, Color.white); effectSkybox = tempTexture; } else if (effectColor.r < 0.15f && effectColor.g < 0.15 && effectColor.b < 0.15) { VRTK_Logger.Warn("`VRTK_TunnelOverlay` has an `Effect Skybox` texture but the `Effect Color` is too dark which will tint the texture so it is not visible."); } }
// Use this for initialization void Start() { int width = 256; heightMap = new Cubemap(width, TextureFormat.ARGB32, false); for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { heightMap.SetPixel(CubemapFace.NegativeX, i, j, new Color(1, 0, 0, 1)); heightMap.SetPixel(CubemapFace.NegativeY, i, j, new Color(1, 1, 0, 1)); heightMap.SetPixel(CubemapFace.NegativeZ, i, j, new Color(1, 0, 1, 1)); heightMap.SetPixel(CubemapFace.PositiveX, i, j, new Color(1, 1, 0.5f, 1)); heightMap.SetPixel(CubemapFace.PositiveY, i, j, new Color(1, 1, 0.75f, 1)); heightMap.SetPixel(CubemapFace.PositiveZ, i, j, new Color(1, 1, 1, 1)); } } heightMap.Apply(); gameObject.GetComponent <MeshRenderer>().material.SetTexture("_CubeMap", heightMap); }
protected override void Init(PipelineResources resources) { proper = RenderPipeline.GetEvent <PropertySetEvent>(); if (useEmissionGeometry) { geometry.Init(); } if (useNoiseEvents) { noiseEvents.Init(resources); } lightingData = RenderPipeline.GetEvent <LightingEvent>(); reflectData = RenderPipeline.GetEvent <ReflectionEvent>(); lightingMat = new Material(resources.shaders.volumetricShader); cameraNormalBuffer = new ComputeBuffer(3, sizeof(float3)); blackCB = new Cubemap(1, TextureFormat.ARGB32, false); blackCB.SetPixel(CubemapFace.NegativeX, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.NegativeY, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.NegativeZ, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.PositiveX, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.PositiveX, 0, 0, Color.black); blackCB.SetPixel(CubemapFace.PositiveX, 0, 0, Color.black); }
//-------------------------------------------------------------------------------------- // Irridiance Convolution based on SH void ConvolveIrradianceEnvironmentMap(Cubemap irrCubeMap) { int a_Size = irrCubeMap.width; Vector4[] m_NormCubeMapArray = new Vector4[a_Size*a_Size*6]; BuildNormalizerSolidAngleArray(a_Size, ref m_NormCubeMapArray); //This is a custom implementation of D3DXSHProjectCubeMap to avoid to deal with LPDIRECT3DSURFACE9 pointer //Use Sh order 2 for a total of 9 coefficient as describe in http://www.cs.berkeley.edu/~ravir/papers/envmap/ //accumulators are 64-bit floats in order to have the precision needed //over a summation of a large number of pixels double[] SHr = new double[25]; // NUM_SH_COEFFICIENT double[] SHg = new double[25]; double[] SHb = new double[25]; double[] SHdir = new double[25]; double weightAccum = 0.0; double weight = 0.0; int startFacePtr = 0; for (int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++) { // read pixels of m_NormCubeMap //var m_NormCubeMap_pixels = new Color[m_NormCubeMap.width*m_NormCubeMap.height]; //m_NormCubeMap_pixels = m_NormCubeMap.GetPixels((CubemapFace)iFaceIdx); // Pointer to the start of the given face in m_NormCubeMapArray startFacePtr = a_Size*a_Size*iFaceIdx; // read all pixels of irrCubeMap var cubeMap_pixels = new Color[irrCubeMap.width * irrCubeMap.height]; cubeMap_pixels = irrCubeMap.GetPixels((CubemapFace)iFaceIdx); for (int y = 0; y < a_Size; y++) { for (int x = 0; x < a_Size; x++) { // read normalCube single pixel Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + y*a_Size + x]; // read originalCube single pixel Color cubeMap_pixel = cubeMap_pixels[y*a_Size + x]; // solid angle stored in 4th channel of normalizer/solid angle cube map weight = m_NormCubeMap_pixel[3]; //weight = TexelCoordSolidAngle(iFaceIdx, (float)x, (float)y, a_Size); // pointer to direction and solid angle in cube map associated with texel Vector3 texelVect; texelVect.x = m_NormCubeMap_pixel[0]; texelVect.y = m_NormCubeMap_pixel[1]; texelVect.z = m_NormCubeMap_pixel[2]; //texelVect = TexelToVect(iFaceIdx, (float)x, (float)y, a_Size); EvalSHBasis(texelVect, ref SHdir); // read original colors and convert to float64 double R = cubeMap_pixel[0]; double G = cubeMap_pixel[1]; double B = cubeMap_pixel[2]; for (int i = 0; i < 25; i++) { SHr[i] += R * SHdir[i] * weight; SHg[i] += G * SHdir[i] * weight; SHb[i] += B * SHdir[i] * weight; } weightAccum += weight; } } } // Normalization - The sum of solid angle should be equal to the solid angle of the sphere (4 PI), so // Normalize in order our weightAccum exactly match 4 PI. for (int i = 0; i < 25; ++i) { SHr[i] *= 4.0 * CP_PI / weightAccum; SHg[i] *= 4.0 * CP_PI / weightAccum; SHb[i] *= 4.0 * CP_PI / weightAccum; } // Second step - Generate cubemap from SH coefficient // Normalized vectors per cubeface and per-texel solid angle // Why do we do it a 2nd time???? BuildNormalizerSolidAngleArray(a_Size, ref m_NormCubeMapArray); for (int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++) { // Pointer to the start of the given face in m_NormCubeMapArray startFacePtr = a_Size*a_Size*iFaceIdx; for (int y = 0; y < a_Size; y++) { for (int x = 0; x < a_Size; x++) { // read normalCube pixel Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + y*a_Size + x]; // read normalvector and pass it to EvalSHBasis to get SHdir Vector3 texelVect; texelVect.x = m_NormCubeMap_pixel[0]; texelVect.y = m_NormCubeMap_pixel[1]; texelVect.z = m_NormCubeMap_pixel[2]; //texelVect = TexelToVect(iFaceIdx, (float)x, (float)y, a_Size); EvalSHBasis( texelVect, ref SHdir); // set color values double R = 0.0; double G = 0.0; double B = 0.0; for (int i = 0; i < 25; ++i) { R += (SHr[i] * SHdir[i] * SHBandFactor[i]); G += (SHg[i] * SHdir[i] * SHBandFactor[i]); B += (SHb[i] * SHdir[i] * SHBandFactor[i]); } // Lux needs alpha! irrCubeMap.SetPixel((CubemapFace)iFaceIdx, x, y, new Color((float)R,(float)G,(float)B, 1.0f )); } } } irrCubeMap.Apply(); }
// Use this for initialization void Awake() { //skyboxMaterial. /*Texture2D skyboxMainTexture = new Texture2D(128, 128, TextureFormat.RGB24, true); * skyboxMainTexture.filterMode = FilterMode.Bilinear; * for(int x = 0; x < 128; x++) { * for(int y = 0; y < 128; y++) { * skyboxMainTexture.SetPixel(x, y, Color.blue); * } * }*/ Cubemap cubemap = new Cubemap(128, TextureFormat.RGB24, false); // PosY: for (int x = 0; x < 128; x++) { for (int y = 0; y < 128; y++) { //float r = Mathf.Lerp(0f, 1f, (float)x / (float)127); //float g = Mathf.Lerp(0f, 1f, (float)y / (float)127); Color col = GetGradientColor(2f * ((float)x / (float)127 - 0.5f), 1f, 2f * ((float)y / (float)127 - 0.5f)); col = Color.black; cubemap.SetPixel(CubemapFace.PositiveY, x, y, col); } } // PosX: for (int x = 0; x < 128; x++) { for (int y = 0; y < 128; y++) { //float r = Mathf.Lerp(0f, 1f, (float)x / (float)127); //float g = Mathf.Lerp(0f, 1f, (float)y / (float)127); Color col = GetGradientColor(1f, 2f * ((float)(127 - y) / (float)127 - 0.5f), 2f * ((float)(127 - x) / (float)127 - 0.5f)); col = Color.black; cubemap.SetPixel(CubemapFace.PositiveX, x, y, col); } } // PosZ: for (int x = 0; x < 128; x++) { for (int y = 0; y < 128; y++) { //float r = Mathf.Lerp(0f, 1f, (float)x / (float)127); //float g = Mathf.Lerp(0f, 1f, (float)y / (float)127); Color col = GetGradientColor(2f * ((float)x / (float)127 - 0.5f), 2f * ((float)(127 - y) / (float)127 - 0.5f), 1f); col = Color.black; cubemap.SetPixel(CubemapFace.PositiveZ, x, y, col); } } // NegX: for (int x = 0; x < 128; x++) { for (int y = 0; y < 128; y++) { //float r = Mathf.Lerp(0f, 1f, (float)x / (float)127); //float g = Mathf.Lerp(0f, 1f, (float)y / (float)127); Color col = GetGradientColor(-1f, 2f * ((float)(127 - y) / (float)127 - 0.5f), 2f * ((float)x / (float)127 - 0.5f)); col = Color.black; cubemap.SetPixel(CubemapFace.NegativeX, x, y, col); } } // NegZ: for (int x = 0; x < 128; x++) { for (int y = 0; y < 128; y++) { //float r = Mathf.Lerp(0f, 1f, (float)x / (float)127); //float g = Mathf.Lerp(0f, 1f, (float)y / (float)127); Color col = GetGradientColor(2f * ((float)(127 - x) / (float)127 - 0.5f), 2f * ((float)(127 - y) / (float)127 - 0.5f), -1f); col = Color.black; cubemap.SetPixel(CubemapFace.NegativeZ, x, y, col); } } // NegY: for (int x = 0; x < 128; x++) { for (int y = 0; y < 128; y++) { //float r = Mathf.Lerp(0f, 1f, (float)x / (float)127); //float g = Mathf.Lerp(0f, 1f, (float)y / (float)127); Color col = GetGradientColor(2f * ((float)x / (float)127 - 0.5f), -1f, 2f * ((float)(127 - y) / (float)127 - 0.5f)); col = Color.black; cubemap.SetPixel(CubemapFace.NegativeY, x, y, col); } } cubemap.Apply(); //skyboxMaterial.mainTexture = skyboxMainTexture; skyboxMaterial.SetTexture(Shader.PropertyToID("_Tex"), cubemap); DynamicGI.UpdateEnvironment(); }
// This function computes a diffuse environment map in // "filteredCubemap" of the same dimensions as "originalCubemap" // by integrating -- for each texel of "filteredCubemap" -- // the diffuse illumination from all texels of "originalCubemap" // for the surface normal vector corresponding to the direction // of each texel of "filteredCubemap". private Cubemap computeFilteredCubeMap() { Cubemap filteredCubeMap = new Cubemap(originalCubeMap.width, originalCubeMap.format, true); int filteredSize = filteredCubeMap.width; int originalSize = originalCubeMap.width; // Compute all texels of the diffuse environment cube map // by itterating over all of them for (int filteredFace = 0; filteredFace < 6; filteredFace++) // the six sides of the cube { for (int filteredI = 0; filteredI < filteredSize; filteredI++) { for (int filteredJ = 0; filteredJ < filteredSize; filteredJ++) { Vector3 filteredDirection = getDirection(filteredFace, filteredI, filteredJ, filteredSize).normalized; float totalWeight = 0.0f; Vector3 originalDirection; Vector3 originalFaceDirection; float weight; Color filteredColor = new Color(0.0f, 0.0f, 0.0f); // sum (i.e. integrate) the diffuse illumination // by all texels in the original environment map for (int originalFace = 0; originalFace < 6; originalFace++) { originalFaceDirection = getDirection( originalFace, 1, 1, 3).normalized; //the normal vector of the face for (int originalI = 0; originalI < originalSize; originalI++) { for (int originalJ = 0; originalJ < originalSize; originalJ++) { originalDirection = getDirection( originalFace, originalI, originalJ, originalSize); // direction to the texel // (i.e. light source) weight = 1.0f / originalDirection.sqrMagnitude; // take smaller size of more // distant texels into account originalDirection = originalDirection.normalized; weight = weight * Vector3.Dot( originalFaceDirection, originalDirection); // take tilt of texel compared // to face into account weight = weight * Mathf.Max(0.0f, Vector3.Dot(filteredDirection, originalDirection)); // directional filter // for diffuse illumination totalWeight = totalWeight + weight; // instead of analytically // normalization, we just normalize // to the potential max illumination filteredColor = filteredColor + weight * originalCubeMap.GetPixel( (CubemapFace)originalFace, originalI, originalJ); // add the // illumination by this texel } } } filteredCubeMap.SetPixel( (CubemapFace)filteredFace, filteredI, filteredJ, filteredColor / totalWeight); // store the diffuse illumination of this texel } } } // Avoid seams between cube faces: average edge texels // to the same color on each side of the seam int maxI = filteredCubeMap.width - 1; for (int i = 0; i < maxI; i++) { setFaceAverage(ref filteredCubeMap, 0, i, 0, 2, maxI, maxI - i); setFaceAverage(ref filteredCubeMap, 0, 0, i, 4, maxI, i); setFaceAverage(ref filteredCubeMap, 0, i, maxI, 3, maxI, i); setFaceAverage(ref filteredCubeMap, 0, maxI, i, 5, 0, i); setFaceAverage(ref filteredCubeMap, 1, i, 0, 2, 0, i); setFaceAverage(ref filteredCubeMap, 1, 0, i, 5, maxI, i); setFaceAverage(ref filteredCubeMap, 1, i, maxI, 3, 0, maxI - i); setFaceAverage(ref filteredCubeMap, 1, maxI, i, 4, 0, i); setFaceAverage(ref filteredCubeMap, 2, i, 0, 5, maxI - i, 0); setFaceAverage(ref filteredCubeMap, 2, i, maxI, 4, i, 0); setFaceAverage(ref filteredCubeMap, 3, i, 0, 4, i, maxI); setFaceAverage(ref filteredCubeMap, 3, i, maxI, 5, maxI - i, maxI); } // Avoid seams between cube faces: // average corner texels to the same color // on all three faces meeting in one corner setCornerAverage(ref filteredCubeMap, 0, 0, 0, 2, maxI, maxI, 4, maxI, 0); setCornerAverage(ref filteredCubeMap, 0, maxI, 0, 2, maxI, 0, 5, 0, 0); setCornerAverage(ref filteredCubeMap, 0, 0, maxI, 3, maxI, 0, 4, maxI, maxI); setCornerAverage(ref filteredCubeMap, 0, maxI, maxI, 3, maxI, maxI, 5, 0, maxI); setCornerAverage(ref filteredCubeMap, 1, 0, 0, 2, 0, 0, 5, maxI, 0); setCornerAverage(ref filteredCubeMap, 1, maxI, 0, 2, 0, maxI, 4, 0, 0); setCornerAverage(ref filteredCubeMap, 1, 0, maxI, 3, 0, maxI, 5, maxI, maxI); setCornerAverage(ref filteredCubeMap, 1, maxI, maxI, 3, 0, 0, 4, 0, maxI); filteredCubeMap.Apply(); //apply all SetPixel(..) commands return(filteredCubeMap); }