Unity中写GLSL(十八)—— 创建Diffuse环境贴图和Specular环境贴图

编程入门 行业动态 更新时间:2024-10-21 11:35:38

Unity中写GLSL(十八)—— 创建Diffuse<a href=https://www.elefans.com/category/jswz/34/1771403.html style=环境贴图和Specular环境贴图"/>

Unity中写GLSL(十八)—— 创建Diffuse环境贴图和Specular环境贴图

参考了WIKI:
具体的可以到这个wiki上面去看,我这里只给结果。(写太多东西太麻烦。。。)
这是生成的Diffuse环境贴图:

这是生成的Specular环境贴图:

下面是代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;public enum EnvMapType
{Diffuse,Specular,
}public class BuildEnvMap
{public static Cubemap originalCubeMap;public static Cubemap filteredCubeMap;public static string diffuseEnvMapPath = "Assets/Shader/PBR/Editor/DiffuseEnvMap.cubemap";public static string specularEnvMapPath = "Assets/Shader/PBR/Editor/SpecularEnvMap.cubemap";public static EnvMapType mapType;[MenuItem("CubeMap/BuildDiffuseEnvMap")]public static void BuildDiffuseEnvironmentMap(){mapType = EnvMapType.Diffuse;originalCubeMap = Selection.activeObject as Cubemap;if (originalCubeMap == null){Debug.LogError ("没选中CubeMap吗???");}else{ComputeFilteredCubeMap ();if (filteredCubeMap != null){AssetDatabase.CreateAsset (filteredCubeMap, diffuseEnvMapPath);Debug.Log("创建DiffuseEnvMap成功!!!");}else{Debug.LogError ("filteredCubeMap创建失败了?");}}}[MenuItem("CubeMap/BuildSpecularEnvMap")]public static void BuildSpecularEnvironmentMap(){mapType = EnvMapType.Specular;originalCubeMap = Selection.activeObject as Cubemap;if (originalCubeMap == null){Debug.LogError ("没选中CubeMap吗???");}else{ComputeFilteredCubeMap ();if (filteredCubeMap != null){AssetDatabase.CreateAsset (filteredCubeMap, specularEnvMapPath);Debug.Log("创建SpecularEnvMap成功!!!");}else{Debug.LogError ("filteredCubeMap创建失败了?");}}}public static Cubemap ComputeFilteredCubeMap(){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 themfor (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 mapfor (int originalFace = 0; originalFace < 6; originalFace++){originalFaceDirection = GetDirection(originalFace, 1, 1, 3).normalized; //the normal vector of the facefor (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 accountoriginalDirection = originalDirection.normalized;weight = weight * Vector3.Dot(originalFaceDirection, originalDirection); // take tilt of texel compared // to face into accountswitch (mapType){case EnvMapType.Diffuse:weight = weight * Mathf.Max(0.0f, Vector3.Dot(filteredDirection, originalDirection)); break;case EnvMapType.Specular:weight = weight * Mathf.Pow(Mathf.Max(0.0f, Vector3.Dot(filteredDirection, originalDirection)), 50.0f);break;default:break;}totalWeight = totalWeight + weight; filteredColor = filteredColor + weight * originalCubeMap.GetPixel((CubemapFace)originalFace, originalI, originalJ);}}}filteredCubeMap.SetPixel((CubemapFace)filteredFace, filteredI, filteredJ, filteredColor / totalWeight); }}}// Avoid seams between cube faces: average edge texels // to the same color on each side of the seamint 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 cornerSetCornerAverage(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(..) commandsreturn filteredCubeMap;}public static 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);}public static 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);}public static Vector3 GetDirection(int face, int i, int j, int size){switch (face){case 0:return new Vector3(0.5f, -((j + 0.5f) / size - 0.5f), -((i + 0.5f) / size - 0.5f));case 1:return new Vector3(-0.5f, -((j + 0.5f) / size - 0.5f), ((i + 0.5f) / size - 0.5f));case 2:return new Vector3(((i + 0.5f) / size - 0.5f), 0.5f, ((j + 0.5f) / size - 0.5f));case 3:return new Vector3(((i + 0.5f) / size - 0.5f), -0.5f, -((j + 0.5f) / size - 0.5f));case 4:return new Vector3(((i + 0.5f) / size - 0.5f),  -((j + 0.5f) / size - 0.5f), 0.5f);case 5:return new Vector3(-((i + 0.5f) / size - 0.5f), -((j + 0.5f) / size - 0.5f), -0.5f);default:return Vector3.zero;}}
}

更多推荐

Unity中写GLSL(十八)—— 创建Diffuse环境贴图和Specular环境贴图

本文发布于:2024-03-09 05:51:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1724051.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:环境   贴图   GLSL   Unity   Specular

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!