unity3d 折射_unity折射 - CSDN
精华内容
参与话题
  • Unity3d 实时折射与反射

    万次阅读 2014-05-27 16:45:01
    Unity3d 实时折射与反射

    这里只贴出了实时折射与反射的脚本与shader,

    关于NGUI部分则请大家自行下载。

    这个版本主要缺点是折射部分平面的Layer必须是water层,如果有哪位高手能把这一块去掉,请记得把代码回复到这篇文章下,谢谢!

    Water.cs

    using UnityEngine;
    using System.Collections;
    using System;
    using System.Collections.Generic;
    /// <summary>
    /// 水面
    /// </summary>
    [AddComponentMenu("GameCore/Effect/Water/Water (Base)")]
    [ExecuteInEditMode]
    public class Water : MonoBehaviour
    {
        public enum FlageWaterRefType
        {
            Both = 0,
            Reflection = 1,
            Refraction = 2
        }
        public bool DisablePixelLights = false;
        public LayerMask Layers = -1;
        public int TexSize = 512;
        public FlageWaterRefType RefType = FlageWaterRefType.Both;   
        public float ReflectClipPlaneOffset = 0;
        public float RefractionAngle = 0;
    
        private static Camera _reflectionCamera;
        private static Camera _refractionCamera;
    
        private int _OldTexSize = 0;
        private RenderTexture _reflectionRenderTex;
        private RenderTexture _refractionRenderTex;
    
        private bool _insideRendering = false;
        private float _refType = (float)FlageWaterRefType.Both;
    
        void OnWillRenderObject()
        {
    
            if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled)
                return;
            Camera cam = Camera.current;
            if (!cam)
                return;
            Material[] materials = renderer.sharedMaterials;
            if (_insideRendering)
                return;
            _insideRendering = true;
            int oldPixelLightCount = QualitySettings.pixelLightCount;
            if (DisablePixelLights)
                QualitySettings.pixelLightCount = 0;
            if (RefType == FlageWaterRefType.Both || RefType == FlageWaterRefType.Reflection)
            {
                DrawReflectionRenderTexture(cam);
                foreach (Material mat in materials)
                {
                    if (mat.HasProperty("_ReflectionTex"))
                        mat.SetTexture("_ReflectionTex", _reflectionRenderTex);
                }
            }
    
            if (RefType == FlageWaterRefType.Both || RefType == FlageWaterRefType.Refraction)
            {
                this.gameObject.layer = 4;
                DrawRefractionRenderTexture(cam);
                foreach (Material mat in materials)
                {
                    if (mat.HasProperty("_RefractionTex"))
                        mat.SetTexture("_RefractionTex", _refractionRenderTex);
                }
            }
            _refType = (float)RefType;
            Matrix4x4 projmtx = CoreTool.UV_Tex2DProj2Tex2D(transform, cam);
            foreach (Material mat in materials)
            {
                mat.SetMatrix("_ProjMatrix", projmtx);
                mat.SetFloat("_RefType", _refType);
            }
            if (DisablePixelLights)
                QualitySettings.pixelLightCount = oldPixelLightCount;
            _insideRendering = false;
        }
    
        /// <summary>
        /// 绘制反射RenderTexture
        /// </summary>
        private void DrawReflectionRenderTexture(Camera cam)
        {
            Vector3 pos = transform.position;
            Vector3 normal = transform.up;
    
            CreateObjects(cam,ref _reflectionRenderTex, ref _reflectionCamera);
    
            CoreTool.CloneCameraModes(cam, _reflectionCamera);
    
            float d = -Vector3.Dot(normal, pos) - ReflectClipPlaneOffset;
            Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
    
    
            Matrix4x4 reflection = CoreTool.CalculateReflectionMatrix(Matrix4x4.zero, reflectionPlane);
    
            Vector3 oldpos = cam.transform.position;
            Vector3 newpos = reflection.MultiplyPoint(oldpos);
            _reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
            
            // Setup oblique projection matrix so that near plane is our reflection
            // plane. This way we clip everything below/above it for free.
            Vector4 clipPlane = CoreTool.CameraSpacePlane(_reflectionCamera, pos, normal, 1.0f, ReflectClipPlaneOffset);
    
            Matrix4x4 projection = cam.projectionMatrix;
    
            projection = CoreTool.CalculateObliqueMatrix(projection, clipPlane, -1);
    
            _reflectionCamera.projectionMatrix = projection;
    
            _reflectionCamera.cullingMask = ~(1 << 4) & Layers.value; // never render water layer
            _reflectionCamera.targetTexture = _reflectionRenderTex;
    
            GL.SetRevertBackfacing(true);
            _reflectionCamera.transform.position = newpos;
            Vector3 euler = cam.transform.eulerAngles;
            _reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z);
            _reflectionCamera.Render();
            _reflectionCamera.transform.position = oldpos;
            GL.SetRevertBackfacing(false);
        }
    
        /// <summary>
        /// 绘制折射RenderTexture
        /// </summary>
        private void DrawRefractionRenderTexture(Camera cam)
        {
            CreateObjects(cam, ref _refractionRenderTex, ref _refractionCamera);
            CoreTool.CloneCameraModes(cam, _refractionCamera);
    
            Vector3 pos = transform.position;
            Vector3 normal = transform.up;
    
            Matrix4x4 projection = cam.worldToCameraMatrix;
            projection *= Matrix4x4.Scale(new Vector3(1,Mathf.Clamp(1-RefractionAngle,0.001f,1),1));
            _refractionCamera.worldToCameraMatrix = projection;
    
            Vector4 clipPlane = CoreTool.CameraSpacePlane(_refractionCamera, pos, normal, 1.0f, 0);
            projection = cam.projectionMatrix;
            projection[2] = clipPlane.x + projection[3];//x
            projection[6] = clipPlane.y + projection[7];//y
            projection[10] = clipPlane.z + projection[11];//z
            projection[14] = clipPlane.w + projection[15];//w
    
            _refractionCamera.projectionMatrix = projection;
    
            _refractionCamera.cullingMask = ~(1 << 4) & Layers.value; // never render water layer
            _refractionCamera.targetTexture = _refractionRenderTex;       
            
            _refractionCamera.transform.position = cam.transform.position;
            _refractionCamera.transform.eulerAngles = cam.transform.eulerAngles;
            _refractionCamera.Render();        
        }
    
        void OnDisable()
        {
            if (_reflectionRenderTex)
            {
                DestroyImmediate(_reflectionRenderTex);
                _reflectionRenderTex = null;
            }        
            if (_reflectionCamera)
            {
                DestroyImmediate(_reflectionCamera.gameObject);
                _reflectionCamera = null;
            }
    
            if (_refractionRenderTex)
            {
                DestroyImmediate(_refractionRenderTex);
                _refractionRenderTex = null;
            }
            if (_refractionCamera)
            {
                DestroyImmediate(_refractionCamera.gameObject);
                _refractionCamera = null;
            }        
        }
    
        void CreateObjects(Camera srcCam, ref RenderTexture renderTex, ref Camera destCam)
        {
            // Reflection render texture
            if (!renderTex || _OldTexSize != TexSize)
            {
                if (renderTex)
                    DestroyImmediate(renderTex);
                renderTex = new RenderTexture(TexSize, TexSize, 0);
                renderTex.name = "__RefRenderTexture" + renderTex.GetInstanceID();
                renderTex.isPowerOfTwo = true;
                renderTex.hideFlags = HideFlags.DontSave;
                renderTex.antiAliasing = 4;
                renderTex.anisoLevel = 0;
                _OldTexSize = TexSize;
            }
    
            if (!destCam) // catch both not-in-dictionary and in-dictionary-but-deleted-GO
            {
                GameObject go = new GameObject("__RefCamera for " + srcCam.GetInstanceID(), typeof(Camera), typeof(Skybox));
                destCam = go.camera;
                destCam.enabled = false;
                destCam.transform.position = transform.position;
                destCam.transform.rotation = transform.rotation;
                destCam.gameObject.AddComponent("FlareLayer");
                go.hideFlags = HideFlags.HideAndDontSave;
            }
        }
    }
    

    WaterEditor.cs

    using UnityEngine;
    using System.Collections;
    using System;
    using UnityEditor;
    
    [CustomEditor(typeof(Water))]
    public class WaterEditor : Editor
    {
        
    
        GUIContent[] _renderTextureOptions = new GUIContent[8] {new GUIContent("16"), new GUIContent("32"), new GUIContent("64"), new GUIContent("128"), 
            new GUIContent("256"), new GUIContent("512"), new GUIContent("1024"), new GUIContent("2048") };
        int[] _renderTextureSize = new int[8] { 16, 32, 64, 128, 256, 512, 1024, 2048 };
        public override void OnInspectorGUI()
        {
            Water water = target as Water;
            EditorGUILayout.PropertyField(this.serializedObject.FindProperty("RefType"), new GUIContent("RefType"));
            EditorGUILayout.PropertyField(this.serializedObject.FindProperty("DisablePixelLights"), new GUIContent("DisablePixelLights"));
            EditorGUILayout.PropertyField(this.serializedObject.FindProperty("Layers"), new GUIContent("Layers"));
            EditorGUILayout.IntPopup(this.serializedObject.FindProperty("TexSize"), _renderTextureOptions, _renderTextureSize, new GUIContent("TexSize"));
    
    
            if (NGUIEditorTools.DrawHeader("Reflect Settings"))
            {
                NGUIEditorTools.BeginContents();
                {
                    EditorGUILayout.Slider(this.serializedObject.FindProperty("ReflectClipPlaneOffset"),0,0.1f,new GUIContent("ClipPlane Offset"));
                }
                NGUIEditorTools.EndContents();
            }
    
            if (NGUIEditorTools.DrawHeader("Refraction Settings"))
            {
                NGUIEditorTools.BeginContents();
                {
                    EditorGUILayout.Slider(this.serializedObject.FindProperty("RefractionAngle"),0,1, new GUIContent("Refraction Angle"));
                }
                NGUIEditorTools.EndContents();
            }
            this.serializedObject.ApplyModifiedProperties();
        }
    }
    

    CoreTool.cs

    using System.Collections;
    using System;
    using UnityEngine;
    
    /// <summary>
    /// 工具类
    /// </summary>
    public static class CoreTool
    {
        #region Config配置
        /// <summary>
        /// 验证当前文件是否为配置文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public static bool IsConfig(string filePath)
        {
            return true;
        }
        #endregion
    
        #region Camera
        /// <summary>
        /// 将源摄像机状态克隆到目标相机
        /// </summary>
        /// <param name="src">源相机</param>
        /// <param name="dest">目标相机</param>
        public static void CloneCameraModes(Camera src, Camera dest)
        {
            if (dest == null)
                return;
            // set camera to clear the same way as current camera
            dest.clearFlags = src.clearFlags;
            dest.backgroundColor = src.backgroundColor;
            if (src.clearFlags == CameraClearFlags.Skybox)
            {
                Skybox sky = src.GetComponent(typeof(Skybox)) as Skybox;
                Skybox mysky = dest.GetComponent(typeof(Skybox)) as Skybox;
                if (!sky || !sky.material)
                {
                    mysky.enabled = false;
                }
                else
                {
                    mysky.enabled = true;
                    mysky.material = sky.material;
                }
            }
            // update other values to match current camera.
            // even if we are supplying custom camera&projection matrices,
            // some of values are used elsewhere (e.g. skybox uses far plane)
            dest.depth = src.depth;
            dest.farClipPlane = src.farClipPlane;
            dest.nearClipPlane = src.nearClipPlane;
            dest.orthographic = src.orthographic;
            dest.fieldOfView = src.fieldOfView;
            dest.aspect = src.aspect;
            dest.orthographicSize = src.orthographicSize;
        }
    
        /// <summary>
        /// 计算反射矩阵
        /// </summary>
        /// <param name="reflectionMat">原始矩阵</param>
        /// <param name="plane">反射平面</param>
        /// <returns>反射矩阵</returns>
        public static Matrix4x4 CalculateReflectionMatrix(Matrix4x4 reflectionMat, Vector4 plane)
        {
            reflectionMat.m00 = (1F - 2F * plane[0] * plane[0]);
            reflectionMat.m01 = (-2F * plane[0] * plane[1]);
            reflectionMat.m02 = (-2F * plane[0] * plane[2]);
            reflectionMat.m03 = (-2F * plane[3] * plane[0]);
    
            reflectionMat.m10 = (-2F * plane[1] * plane[0]);
            reflectionMat.m11 = (1F - 2F * plane[1] * plane[1]);
            reflectionMat.m12 = (-2F * plane[1] * plane[2]);
            reflectionMat.m13 = (-2F * plane[3] * plane[1]);
    
            reflectionMat.m20 = (-2F * plane[2] * plane[0]);
            reflectionMat.m21 = (-2F * plane[2] * plane[1]);
            reflectionMat.m22 = (1F - 2F * plane[2] * plane[2]);
            reflectionMat.m23 = (-2F * plane[3] * plane[2]);
    
            reflectionMat.m30 = 0F;
            reflectionMat.m31 = 0F;
            reflectionMat.m32 = 0F;
            reflectionMat.m33 = 1F;
            return reflectionMat;
        }
    
        /// <summary>
        /// 计算指定平面在摄像机中的空间位置
        /// </summary>
        /// <param name="cam">摄像机</param>
        /// <param name="pos">平面上的点</param>
        /// <param name="normal">平面法线</param>
        /// <param name="sideSign">1:平面正面,-1:平面反面</param>
        /// <param name="clipPlaneOffset">平面法线位置偏移量</param>
        /// <returns></returns>
        public static Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign,float clipPlaneOffset)
        {        
            Vector3 offsetPos = pos + normal * clipPlaneOffset;
            Matrix4x4 m = cam.worldToCameraMatrix;
            Vector3 cpos = m.MultiplyPoint(offsetPos);
            Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign;
            return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
        }
    
        /// <summary>
        /// 由剪裁面计算投影倾斜矩阵
        /// </summary>
        /// <param name="projection">投影矩阵</param>
        /// <param name="clipPlane">剪裁面</param>
        /// <param name="sideSign">剪裁平面(-1:平面下面,1:平面上面)</param>
        public static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 projection, Vector4 clipPlane,float sideSign)
        {
            Vector4 q = projection.inverse * new Vector4(
                sgn(clipPlane.x),
                sgn(clipPlane.y),
                1.0f,
                1.0f
            );
            Vector4 c = clipPlane * (2.0F / (Vector4.Dot(clipPlane, q)));
            // third row = clip plane - fourth row
            projection[2] = c.x + Mathf.Sign(sideSign)*projection[3];
            projection[6] = c.y + Mathf.Sign(sideSign) * projection[7];
            projection[10] = c.z + Mathf.Sign(sideSign) * projection[11];
            projection[14] = c.w + Mathf.Sign(sideSign) * projection[15];
            return projection;
        }
    
        private static float sgn(float a)
        {
            if (a > 0.0f) return 1.0f;
            if (a < 0.0f) return -1.0f;
            return 0.0f;
        }
    
        /// <summary>
        /// 由水平、垂直距离修改倾斜矩阵
        /// </summary>
        /// <param name="projMatrix">倾斜矩阵</param>
        /// <param name="horizObl">水平方向</param>
        /// <param name="vertObl">垂直方向</param>
        /// <returns>修改后的倾斜矩阵</returns>
        public static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 projMatrix, float horizObl, float vertObl)
        {
            Matrix4x4 mat = projMatrix;
    	    mat[0, 2] = horizObl;
    	    mat[1, 2] = vertObl;
    	    return mat;
        }
        #endregion
    
        #region Shader Matrix4x4
        /// <summary>
        /// tex2DProj到tex2D的uv纹理转换矩阵
        /// 在shader中,
        /// vert=>o.posProj = mul(_ProjMatrix, v.vertex);
        /// frag=>tex2D(_RefractionTex,float2(i.posProj) / i.posProj.w)
        /// </summary>
        /// <param name="transform">要显示纹理的对象</param>
        /// <param name="cam">当前观察的摄像机</param>
        /// <returns>返回转换矩阵</returns>
        public static Matrix4x4 UV_Tex2DProj2Tex2D(Transform transform,Camera cam)
        {
            Matrix4x4 scaleOffset = Matrix4x4.TRS(
                new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));
            Vector3 scale = transform.lossyScale;
            Matrix4x4 _ProjMatrix = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z));
            _ProjMatrix = scaleOffset * cam.projectionMatrix * cam.worldToCameraMatrix * _ProjMatrix;
            return _ProjMatrix;
        }
        #endregion
    }
    

    Shader

    Shader "GameCore/Mobile/Water/Diffuse" 
    {
        Properties {		
            _ReflectionTex ("Reflection", 2D) = "white" {}
    		_RefractionTex ("Refraction", 2D) = "white" {}	
    		_RefColor("Color",Color) = (1,1,1,1)
    	}
    	SubShader {
            Tags {
                "RenderType"="Opaque"}
    		LOD 100
    		Pass {
                CGPROGRAM
    			#pragma vertex vert
    			#pragma fragment frag
    			#include "UnityCG.cginc"
    
    			uniform float4x4 _ProjMatrix;
    			uniform float _RefType;
                sampler2D _ReflectionTex;
    			sampler2D _RefractionTex;
                float4 _RefColor;
                struct outvertex {
                    float4 pos : SV_POSITION;
                    float4 uv0 : TEXCOORD0;
    				float4 refparam : COLOR0;//r:fresnel,g:none,b:none,a:none
                };
                
    			outvertex vert(appdata_tan v) {
                    outvertex o;
                    o.pos = mul (UNITY_MATRIX_MVP,v.vertex);
                    float4 posProj = mul(_ProjMatrix, v.vertex);
    				o.uv0 = posProj;				
    				float3 r =normalize(ObjSpaceViewDir(v.vertex));
    				float d = saturate(dot(r,normalize(v.normal)));//r+(1-r)*pow(d,5)				
    				o.refparam =float4(d,0,0,0);
    				
    				return o;
                }
    										
    			float4 frag(outvertex i) : COLOR {                
    				half4 flecol = tex2D(_ReflectionTex,float2(i.uv0) / i.uv0.w);							
    				half4 fracol = tex2D(_RefractionTex,float2(i.uv0) / i.uv0.w);				
    				half4 outcolor = half4(1,1,1,1);				
    				if(_RefType == 0)
    				{
    					outcolor = lerp(flecol,fracol,i.refparam.r);
    				}
    				else if(_RefType == 1)
    				{
    					outcolor = flecol;
    				}
    				else if(_RefType == 2)
    				{
    					outcolor = fracol;
    				}	
                    return outcolor*_RefColor;
                }
    			ENDCG
    		}
    	}
    }



    展开全文
  • Unity3D--光的反射与折射实现  最近做老师的科研项目,主要方向是虚拟现实,重点是研究光学物理实验。在这里写一些自己开发过程中想法和实现细节,方便自己回顾和分享给需要的小伙伴! ☆☆☆☆☆☆☆☆☆☆☆  ...

    Unity3D--光的反射与折射实现
      最近做老师的科研项目,主要方向是虚拟现实,重点是研究光学物理实验。在这里写一些自己开发过程中想法和实现细节,方便自己回顾和分享给需要的小伙伴! ☆☆☆☆☆☆☆☆☆☆☆
      说起光,首先要在Unity3D场景中将光线显示出来且满足光学实验规律。那么,先介绍目前我用过的两种光线显示方法:
      一、Unity3D中的LineRender画线法,该方法网上介绍都比较详细,我就不说了。主要介绍我目前实验中用到Vectrosity
      二、Vectrosity 5.4.2画线插件,该插件可以很方便地在2D和3D物体上绘制线段、射线以及折线等等。(点击下载:目前在审核中,需要可以私发插件包和官方文档。)
      接下来,回到我们的重点内容:光的反射和折射实现。
      光的反射,不用多说,Unity3D中包含该方法,即:reflect(float3 I,float3 N);I为入射光线向量,N为法线向量。
      例如:fanShe = Vector3.Reflect(hit.point - v0, hit.normal); //返回fanShe为反射光线。
      运用Vectrosity 插件绘制反射光线,即:

    using UnityEngine;
    using Vectrosity;
    public class Lightings : MonoBehaviour
        {
            private VectorLine myLine;//绘制反射光线
            
            void Start()
            {
            }
            
            void Update()
            {
                v0 = GameObject.Find("origin").transform.position;
                    //绘制反射光线...
                    fanShe= Vector3.Reflect(hit.point - v0, hit.normal);
                    myLine = VectorLine.SetRay3D(Color.blue, 0.1f, hit.point, fanShe);
                    myLine.lineWidth = 4.0f; 
            }
    }

    光的折射,不幸的是在Unity3D中并没有写该方法,需要我们自己构造,没搞错吧??这种API方法难道不是应该Unity3D写好的吗?有反射,怎么会没有折射,这也太偏心了吧。。。。。

          没有办法的呀,自己默默找资料,写呗。废话不多说,直接上代码。GoGo~~~~~

     //该函数返回结果为:折射光线的方向,其中:I为入射光线,N为法线,h为折射率
            public Vector3 Refract(Vector3 I, Vector3 N, float h)
            {
                I = I.normalized;//单位化
                N = N.normalized;
    
                float A = Vector3.Dot(I, N);
                float B = 1.0f - h * h * (1.0f - A * A);
                Vector3 T = h * I - (h * A + Mathf.Sqrt(B)) * N;
                if (B > 0)
                    return T;
                else
                    return Vector3.zero;
            }

    下面还是运用实例,讲解该方法如何运用,上代码——>>

    public class Lightings : MonoBehaviour
        {
            public float mN1 = 1.0f;  //空气折射率1
            public float mN2 = 1.33f;  //水折射率1.33
            private VectorLine myLine1;//绘制反射光线
            
            void Start()
            {
            }
            
            void Update()
            {
                    //绘制折射光线...光线从空气射向水中,绘制水中折射光线。
                    //(endHit.point - startHit.point)为入射光线向量
                    zheShe = Refract(endHit.point - startHit.point, endHit.normal, mN1/mN2);
                    myLine1 = VectorLine.SetRay3D(Color.red, 0.1f, hit.point, zheShe);
                    myLine1.lineWidth = 4.0f; 
            }
    }

    贴一张我的实验效果图(3D场景下):起始为红光,当然发生反射、折射(以及全反射)现象。

    展开全文
  • unity光线折射向量refract计算demo,配合博客进行学习
  • 这里只是张贴在实时折射和脚本反思shader, 大约NGUI第一部分请下载。 这个版本的主要缺点是折射平面部Layer必须是water层。假设有专家谁可以摆脱这一个。请记得把代码回该条,谢谢! Water.cs using ...

    这里只是张贴在实时折射和脚本反思shader,

    大约NGUI第一部分请下载。

    这个版本的主要缺点是折射平面部Layer必须是water层。假设有专家谁可以摆脱这一个。请记得把代码回该条,谢谢!

    Water.cs

    using UnityEngine;
    using System.Collections;
    using System;
    using System.Collections.Generic;
    /// <summary>
    /// 水面
    /// </summary>
    [AddComponentMenu("GameCore/Effect/Water/Water (Base)")]
    [ExecuteInEditMode]
    public class Water : MonoBehaviour
    {
        public enum FlageWaterRefType
        {
            Both = 0,
            Reflection = 1,
            Refraction = 2
        }
        public bool DisablePixelLights = false;
        public LayerMask Layers = -1;
        public int TexSize = 512;
        public FlageWaterRefType RefType = FlageWaterRefType.Both;   
        public float ReflectClipPlaneOffset = 0;
        public float RefractionAngle = 0;
    
        private static Camera _reflectionCamera;
        private static Camera _refractionCamera;
    
        private int _OldTexSize = 0;
        private RenderTexture _reflectionRenderTex;
        private RenderTexture _refractionRenderTex;
    
        private bool _insideRendering = false;
        private float _refType = (float)FlageWaterRefType.Both;
    
        void OnWillRenderObject()
        {
    
            if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled)
                return;
            Camera cam = Camera.current;
            if (!cam)
                return;
            Material[] materials = renderer.sharedMaterials;
            if (_insideRendering)
                return;
            _insideRendering = true;
            int oldPixelLightCount = QualitySettings.pixelLightCount;
            if (DisablePixelLights)
                QualitySettings.pixelLightCount = 0;
            if (RefType == FlageWaterRefType.Both || RefType == FlageWaterRefType.Reflection)
            {
                DrawReflectionRenderTexture(cam);
                foreach (Material mat in materials)
                {
                    if (mat.HasProperty("_ReflectionTex"))
                        mat.SetTexture("_ReflectionTex", _reflectionRenderTex);
                }
            }
    
            if (RefType == FlageWaterRefType.Both || RefType == FlageWaterRefType.Refraction)
            {
                this.gameObject.layer = 4;
                DrawRefractionRenderTexture(cam);
                foreach (Material mat in materials)
                {
                    if (mat.HasProperty("_RefractionTex"))
                        mat.SetTexture("_RefractionTex", _refractionRenderTex);
                }
            }
            _refType = (float)RefType;
            Matrix4x4 projmtx = CoreTool.UV_Tex2DProj2Tex2D(transform, cam);
            foreach (Material mat in materials)
            {
                mat.SetMatrix("_ProjMatrix", projmtx);
                mat.SetFloat("_RefType", _refType);
            }
            if (DisablePixelLights)
                QualitySettings.pixelLightCount = oldPixelLightCount;
            _insideRendering = false;
        }
    
        /// <summary>
        /// 绘制反射RenderTexture
        /// </summary>
        private void DrawReflectionRenderTexture(Camera cam)
        {
            Vector3 pos = transform.position;
            Vector3 normal = transform.up;
    
            CreateObjects(cam,ref _reflectionRenderTex, ref _reflectionCamera);
    
            CoreTool.CloneCameraModes(cam, _reflectionCamera);
    
            float d = -Vector3.Dot(normal, pos) - ReflectClipPlaneOffset;
            Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
    
    
            Matrix4x4 reflection = CoreTool.CalculateReflectionMatrix(Matrix4x4.zero, reflectionPlane);
    
            Vector3 oldpos = cam.transform.position;
            Vector3 newpos = reflection.MultiplyPoint(oldpos);
            _reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
            
            // Setup oblique projection matrix so that near plane is our reflection
            // plane. This way we clip everything below/above it for free.
            Vector4 clipPlane = CoreTool.CameraSpacePlane(_reflectionCamera, pos, normal, 1.0f, ReflectClipPlaneOffset);
    
            Matrix4x4 projection = cam.projectionMatrix;
    
            projection = CoreTool.CalculateObliqueMatrix(projection, clipPlane, -1);
    
            _reflectionCamera.projectionMatrix = projection;
    
            _reflectionCamera.cullingMask = ~(1 << 4) & Layers.value; // never render water layer
            _reflectionCamera.targetTexture = _reflectionRenderTex;
    
            GL.SetRevertBackfacing(true);
            _reflectionCamera.transform.position = newpos;
            Vector3 euler = cam.transform.eulerAngles;
            _reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z);
            _reflectionCamera.Render();
            _reflectionCamera.transform.position = oldpos;
            GL.SetRevertBackfacing(false);
        }
    
        /// <summary>
        /// 绘制折射RenderTexture
        /// </summary>
        private void DrawRefractionRenderTexture(Camera cam)
        {
            CreateObjects(cam, ref _refractionRenderTex, ref _refractionCamera);
            CoreTool.CloneCameraModes(cam, _refractionCamera);
    
            Vector3 pos = transform.position;
            Vector3 normal = transform.up;
    
            Matrix4x4 projection = cam.worldToCameraMatrix;
            projection *= Matrix4x4.Scale(new Vector3(1,Mathf.Clamp(1-RefractionAngle,0.001f,1),1));
            _refractionCamera.worldToCameraMatrix = projection;
    
            Vector4 clipPlane = CoreTool.CameraSpacePlane(_refractionCamera, pos, normal, 1.0f, 0);
            projection = cam.projectionMatrix;
            projection[2] = clipPlane.x + projection[3];//x
            projection[6] = clipPlane.y + projection[7];//y
            projection[10] = clipPlane.z + projection[11];//z
            projection[14] = clipPlane.w + projection[15];//w
    
            _refractionCamera.projectionMatrix = projection;
    
            _refractionCamera.cullingMask = ~(1 << 4) & Layers.value; // never render water layer
            _refractionCamera.targetTexture = _refractionRenderTex;       
            
            _refractionCamera.transform.position = cam.transform.position;
            _refractionCamera.transform.eulerAngles = cam.transform.eulerAngles;
            _refractionCamera.Render();        
        }
    
        void OnDisable()
        {
            if (_reflectionRenderTex)
            {
                DestroyImmediate(_reflectionRenderTex);
                _reflectionRenderTex = null;
            }        
            if (_reflectionCamera)
            {
                DestroyImmediate(_reflectionCamera.gameObject);
                _reflectionCamera = null;
            }
    
            if (_refractionRenderTex)
            {
                DestroyImmediate(_refractionRenderTex);
                _refractionRenderTex = null;
            }
            if (_refractionCamera)
            {
                DestroyImmediate(_refractionCamera.gameObject);
                _refractionCamera = null;
            }        
        }
    
        void CreateObjects(Camera srcCam, ref RenderTexture renderTex, ref Camera destCam)
        {
            // Reflection render texture
            if (!renderTex || _OldTexSize != TexSize)
            {
                if (renderTex)
                    DestroyImmediate(renderTex);
                renderTex = new RenderTexture(TexSize, TexSize, 0);
                renderTex.name = "__RefRenderTexture" + renderTex.GetInstanceID();
                renderTex.isPowerOfTwo = true;
                renderTex.hideFlags = HideFlags.DontSave;
                renderTex.antiAliasing = 4;
                renderTex.anisoLevel = 0;
                _OldTexSize = TexSize;
            }
    
            if (!destCam) // catch both not-in-dictionary and in-dictionary-but-deleted-GO
            {
                GameObject go = new GameObject("__RefCamera for " + srcCam.GetInstanceID(), typeof(Camera), typeof(Skybox));
                destCam = go.camera;
                destCam.enabled = false;
                destCam.transform.position = transform.position;
                destCam.transform.rotation = transform.rotation;
                destCam.gameObject.AddComponent("FlareLayer");
                go.hideFlags = HideFlags.HideAndDontSave;
            }
        }
    }
    

    WaterEditor.cs

    using UnityEngine;
    using System.Collections;
    using System;
    using UnityEditor;
    
    [CustomEditor(typeof(Water))]
    public class WaterEditor : Editor
    {
        
    
        GUIContent[] _renderTextureOptions = new GUIContent[8] {new GUIContent("16"), new GUIContent("32"), new GUIContent("64"), new GUIContent("128"), 
            new GUIContent("256"), new GUIContent("512"), new GUIContent("1024"), new GUIContent("2048") };
        int[] _renderTextureSize = new int[8] { 16, 32, 64, 128, 256, 512, 1024, 2048 };
        public override void OnInspectorGUI()
        {
            Water water = target as Water;
            EditorGUILayout.PropertyField(this.serializedObject.FindProperty("RefType"), new GUIContent("RefType"));
            EditorGUILayout.PropertyField(this.serializedObject.FindProperty("DisablePixelLights"), new GUIContent("DisablePixelLights"));
            EditorGUILayout.PropertyField(this.serializedObject.FindProperty("Layers"), new GUIContent("Layers"));
            EditorGUILayout.IntPopup(this.serializedObject.FindProperty("TexSize"), _renderTextureOptions, _renderTextureSize, new GUIContent("TexSize"));
    
    
            if (NGUIEditorTools.DrawHeader("Reflect Settings"))
            {
                NGUIEditorTools.BeginContents();
                {
                    EditorGUILayout.Slider(this.serializedObject.FindProperty("ReflectClipPlaneOffset"),0,0.1f,new GUIContent("ClipPlane Offset"));
                }
                NGUIEditorTools.EndContents();
            }
    
            if (NGUIEditorTools.DrawHeader("Refraction Settings"))
            {
                NGUIEditorTools.BeginContents();
                {
                    EditorGUILayout.Slider(this.serializedObject.FindProperty("RefractionAngle"),0,1, new GUIContent("Refraction Angle"));
                }
                NGUIEditorTools.EndContents();
            }
            this.serializedObject.ApplyModifiedProperties();
        }
    }
    

    CoreTool.cs

    using System.Collections;
    using System;
    using UnityEngine;
    
    /// <summary>
    /// 工具类
    /// </summary>
    public static class CoreTool
    {
        #region Config配置
        /// <summary>
        /// 验证当前文件是否为配置文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public static bool IsConfig(string filePath)
        {
            return true;
        }
        #endregion
    
        #region Camera
        /// <summary>
        /// 将源摄像机状态克隆到目标相机
        /// </summary>
        /// <param name="src">源相机</param>
        /// <param name="dest">目标相机</param>
        public static void CloneCameraModes(Camera src, Camera dest)
        {
            if (dest == null)
                return;
            // set camera to clear the same way as current camera
            dest.clearFlags = src.clearFlags;
            dest.backgroundColor = src.backgroundColor;
            if (src.clearFlags == CameraClearFlags.Skybox)
            {
                Skybox sky = src.GetComponent(typeof(Skybox)) as Skybox;
                Skybox mysky = dest.GetComponent(typeof(Skybox)) as Skybox;
                if (!sky || !sky.material)
                {
                    mysky.enabled = false;
                }
                else
                {
                    mysky.enabled = true;
                    mysky.material = sky.material;
                }
            }
            // update other values to match current camera.
            // even if we are supplying custom camera&projection matrices,
            // some of values are used elsewhere (e.g. skybox uses far plane)
            dest.depth = src.depth;
            dest.farClipPlane = src.farClipPlane;
            dest.nearClipPlane = src.nearClipPlane;
            dest.orthographic = src.orthographic;
            dest.fieldOfView = src.fieldOfView;
            dest.aspect = src.aspect;
            dest.orthographicSize = src.orthographicSize;
        }
    
        /// <summary>
        /// 计算反射矩阵
        /// </summary>
        /// <param name="reflectionMat">原始矩阵</param>
        /// <param name="plane">反射平面</param>
        /// <returns>反射矩阵</returns>
        public static Matrix4x4 CalculateReflectionMatrix(Matrix4x4 reflectionMat, Vector4 plane)
        {
            reflectionMat.m00 = (1F - 2F * plane[0] * plane[0]);
            reflectionMat.m01 = (-2F * plane[0] * plane[1]);
            reflectionMat.m02 = (-2F * plane[0] * plane[2]);
            reflectionMat.m03 = (-2F * plane[3] * plane[0]);
    
            reflectionMat.m10 = (-2F * plane[1] * plane[0]);
            reflectionMat.m11 = (1F - 2F * plane[1] * plane[1]);
            reflectionMat.m12 = (-2F * plane[1] * plane[2]);
            reflectionMat.m13 = (-2F * plane[3] * plane[1]);
    
            reflectionMat.m20 = (-2F * plane[2] * plane[0]);
            reflectionMat.m21 = (-2F * plane[2] * plane[1]);
            reflectionMat.m22 = (1F - 2F * plane[2] * plane[2]);
            reflectionMat.m23 = (-2F * plane[3] * plane[2]);
    
            reflectionMat.m30 = 0F;
            reflectionMat.m31 = 0F;
            reflectionMat.m32 = 0F;
            reflectionMat.m33 = 1F;
            return reflectionMat;
        }
    
        /// <summary>
        /// 计算指定平面在摄像机中的空间位置
        /// </summary>
        /// <param name="cam">摄像机</param>
        /// <param name="pos">平面上的点</param>
        /// <param name="normal">平面法线</param>
        /// <param name="sideSign">1:平面正面。-1:平面反面</param>
        /// <param name="clipPlaneOffset">平面法线位置偏移量</param>
        /// <returns></returns>
        public static Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign,float clipPlaneOffset)
        {        
            Vector3 offsetPos = pos + normal * clipPlaneOffset;
            Matrix4x4 m = cam.worldToCameraMatrix;
            Vector3 cpos = m.MultiplyPoint(offsetPos);
            Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign;
            return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
        }
    
        /// <summary>
        /// 由剪裁面计算投影倾斜矩阵
        /// </summary>
        /// <param name="projection">投影矩阵</param>
        /// <param name="clipPlane">剪裁面</param>
        /// <param name="sideSign">剪裁平面(-1:平面以下,1:平面上面)</param>
        public static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 projection, Vector4 clipPlane,float sideSign)
        {
            Vector4 q = projection.inverse * new Vector4(
                sgn(clipPlane.x),
                sgn(clipPlane.y),
                1.0f,
                1.0f
            );
            Vector4 c = clipPlane * (2.0F / (Vector4.Dot(clipPlane, q)));
            // third row = clip plane - fourth row
            projection[2] = c.x + Mathf.Sign(sideSign)*projection[3];
            projection[6] = c.y + Mathf.Sign(sideSign) * projection[7];
            projection[10] = c.z + Mathf.Sign(sideSign) * projection[11];
            projection[14] = c.w + Mathf.Sign(sideSign) * projection[15];
            return projection;
        }
    
        private static float sgn(float a)
        {
            if (a > 0.0f) return 1.0f;
            if (a < 0.0f) return -1.0f;
            return 0.0f;
        }
    
        /// <summary>
        /// 由水平、垂直距离改动倾斜矩阵
        /// </summary>
        /// <param name="projMatrix">倾斜矩阵</param>
        /// <param name="horizObl">水平方向</param>
        /// <param name="vertObl">垂直方向</param>
        /// <returns>改动后的倾斜矩阵</returns>
        public static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 projMatrix, float horizObl, float vertObl)
        {
            Matrix4x4 mat = projMatrix;
    	    mat[0, 2] = horizObl;
    	    mat[1, 2] = vertObl;
    	    return mat;
        }
        #endregion
    
        #region Shader Matrix4x4
        /// <summary>
        /// tex2DProj到tex2D的uv纹理转换矩阵
        /// 在shader中,
        /// vert=>o.posProj = mul(_ProjMatrix, v.vertex);
        /// frag=>tex2D(_RefractionTex,float2(i.posProj) / i.posProj.w)
        /// </summary>
        /// <param name="transform">要显示纹理的对象</param>
        /// <param name="cam">当前观察的摄像机</param>
        /// <returns>返回转换矩阵</returns>
        public static Matrix4x4 UV_Tex2DProj2Tex2D(Transform transform,Camera cam)
        {
            Matrix4x4 scaleOffset = Matrix4x4.TRS(
                new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));
            Vector3 scale = transform.lossyScale;
            Matrix4x4 _ProjMatrix = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z));
            _ProjMatrix = scaleOffset * cam.projectionMatrix * cam.worldToCameraMatrix * _ProjMatrix;
            return _ProjMatrix;
        }
        #endregion
    }
    

    Shader

    Shader "GameCore/Mobile/Water/Diffuse" 
    {
        Properties {		
            _ReflectionTex ("Reflection", 2D) = "white" {}
    		_RefractionTex ("Refraction", 2D) = "white" {}	
    		_RefColor("Color",Color) = (1,1,1,1)
    	}
    	SubShader {
            Tags {
                "RenderType"="Opaque"}
    		LOD 100
    		Pass {
                CGPROGRAM
    			#pragma vertex vert
    			#pragma fragment frag
    			#include "UnityCG.cginc"
    
    			uniform float4x4 _ProjMatrix;
    			uniform float _RefType;
                sampler2D _ReflectionTex;
    			sampler2D _RefractionTex;
                float4 _RefColor;
                struct outvertex {
                    float4 pos : SV_POSITION;
                    float4 uv0 : TEXCOORD0;
    				float4 refparam : COLOR0;//r:fresnel,g:none,b:none,a:none
                };
                
    			outvertex vert(appdata_tan v) {
                    outvertex o;
                    o.pos = mul (UNITY_MATRIX_MVP,v.vertex);
                    float4 posProj = mul(_ProjMatrix, v.vertex);
    				o.uv0 = posProj;				
    				float3 r =normalize(ObjSpaceViewDir(v.vertex));
    				float d = saturate(dot(r,normalize(v.normal)));//r+(1-r)*pow(d,5)				
    				o.refparam =float4(d,0,0,0);
    				
    				return o;
                }
    										
    			float4 frag(outvertex i) : COLOR {                
    				half4 flecol = tex2D(_ReflectionTex,float2(i.uv0) / i.uv0.w);							
    				half4 fracol = tex2D(_RefractionTex,float2(i.uv0) / i.uv0.w);				
    				half4 outcolor = half4(1,1,1,1);				
    				if(_RefType == 0)
    				{
    					outcolor = lerp(flecol,fracol,i.refparam.r);
    				}
    				else if(_RefType == 1)
    				{
    					outcolor = flecol;
    				}
    				else if(_RefType == 2)
    				{
    					outcolor = fracol;
    				}	
                    return outcolor*_RefColor;
                }
    			ENDCG
    		}
    	}
    }



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

    展开全文
  • Unity3D Shader(17)——水的折射

    千次阅读 2017-08-22 21:41:11
    这里引用的是蛮牛的Unity3D Shader的进阶教程里的代码。咨询:qq254033230这里依然用的是vertex 和fragment shader来解决水的反射的问题。首先,准备两个平面,一个平面作为底图,一个平面模拟水的波动。这里要用到...

    这里引用的是蛮牛的Unity3D Shader的进阶教程里的代码。咨询:qq254033230

    这里依然用的是vertex 和fragment shader来解决水的反射的问题。

    首先,准备两个平面,一个平面作为底图,一个平面模拟水的波动。这里要用到抓取底图的通道 GrabPass{}。然后把抓取的通道图放到水面的那张图上。另外一个难点就是要模拟水的波动,水的波动的原理如下图:
    这里写图片描述

    其中顶点函数代码和片段函数代码如下:
    v2f vert(appdata v){
             float w=2*3.1415926/_L;
             float f=_S*w;
    
             v.vertex.y+=_A*sin(v.vertex.xz*w+_Time.x*f);
    
             v2f o;
             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
             o.uv=TRANSFORM_TEX(v.uv,_MainTex);
             o.proj=ComputeGrabScreenPos(o.pos);
             return o;
            }
    
            float4 frag(v2f IN):SV_Target{
            IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2);
            float4 col=tex2Dproj(_GrabTexture,IN.proj)*0.5;
            return col;
            }

    这里写图片描述

    如果想最后的贴图是随着法线变化,那么就要用到偏导数,计算每个顶点的动态法线。

    v2f vert(appdata v){
             float w=2*3.1415926/_L;
             float f=_S*w;
    
             v.vertex.y+=_A*sin(-length(v.vertex.xz)*w+_Time.x*f);
             float dx=_A*v.vertex.x*w*cos(-length(v.vertex.xz)*w+_Time.x*f);
             float dz=_A*v.vertex.z*w*cos(-length(v.vertex.xz)*w+_Time.x*f);
    
             float3 B=normalize(float3(1,dx,0));
             float3 T=normalize(float3(0,dz,1));
    
             v2f o;
             o.N=cross(B,T);
             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
             o.uv=TRANSFORM_TEX(v.uv,_MainTex);
             o.proj=ComputeGrabScreenPos(o.pos);
             return o;
            }
    
            float4 frag(v2f IN):SV_Target{
            float d=dot(IN.N,float3(0,1,0));
            IN.proj.xy+=d*0.1;
            //IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2);
            float4 col=tex2Dproj(_GrabTexture,IN.proj)*0.5;
            return col;
            }

    以上还不算完美,可以加上漫反射,让水的颜色随着波纹变化。

    v2f vert(appdata v){
             float w=2*3.1415926/_L;
             float f=_S*w;
    
             v.vertex.y+=_A*sin(-length(v.vertex.xz)*w+_Time.x*f);
             float dx=_A*v.vertex.x*w*cos(-length(v.vertex.xz)*w+_Time.x*f);
             float dz=_A*v.vertex.z*w*cos(-length(v.vertex.xz)*w+_Time.x*f);
    
             float3 B=normalize(float3(1,dx,0));
             float3 T=normalize(float3(0,dz,1));
    
             v2f o;
             o.N=cross(B,T);
             o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
             o.uv=TRANSFORM_TEX(v.uv,_MainTex);
             o.proj=ComputeGrabScreenPos(o.pos);
             return o;
            }
    
            float4 frag(v2f IN):SV_Target{
            float3 ncol=UnpackNormal(tex2D(_MainTex,IN.uv+_Time.x))*0.3;
            IN.N=IN.N+ncol;
    
            float d=dot(IN.N,float3(0,1,0));
            float diff=max(0,dot(IN.N,float3(1,0,0)));  //漫反射
            IN.proj.xy+=d*0.1;
            //IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2);
            float4 col=tex2Dproj(_GrabTexture,IN.proj)*(0.3+diff);
            return col;
            }

    最终的效果:
    这里写图片描述

    展开全文
  • Unity3D shader——水的折射与反射

    千次阅读 2017-11-27 11:58:21
    水的折射与反射原理其实差不多,只是一个用ComputeGrabScreenPos(o.pos)来取得贴图,一个用ComputeScreenPos(o.pos)来取得贴图。另外还需要两个脚本,一个是工具类的脚本,一个是得到反射贴图的脚本。  这里直接放...
  • Unity3d 免费么?

    千次阅读 2015-11-24 00:14:38
    Unity3d 授权版一年的费用是1500或者75或者75每月 怎么想都是贵啊免费版都包括什么呢? 打开游戏首先强制显示“Powered by Unity”的画面 所有平台(有限制) 免费版不支持折射、实时反射、动态阴影,只支持静态反射...
  • UN283 unity3d游戏插件 材质shader 实时折射 镜面反射 Mirror_Shaders
  • Unity3d场景快速烘焙【2019】

    万次阅读 多人点赞 2019-12-26 19:09:28
    很多刚刚接触Unity3d的童鞋花了大量的时间自学,可总是把握不好Unity3d的烘焙,刚从一个坑里爬出来,又陷入另一个新的坑,每次烘焙一个场景少则几个小时,多则几十个小时,机器总是处于假死机状态,半天看不到结果,...
  • 使用Unity3d做了一个室内设计的应用,但是专业人士说效果不行,这个我看了其他人的一些Unity3d室内 设计的应用,效果很赞。发现我这个的效果确实很有差距。在这个场景里面我用了Unity3d自带的Shader: 1.大部分都...
  • Uunity 3d模型中实现射线折射 直接代码 using UnityEngine; public class ReflectLine : MonoBehaviour { void Update() { Ray ray = new Ray(transform.position, transform.forward); RaycastHit hit; if ...
  • Unity3D性能优化总结

    2015-05-19 13:50:10
    原文 http://blog.csdn.net/dj0379/article/details/27314163 ... ...Unity3D合并材质球 unity 3d中每倒入一次模型就多一个材质球,可我的这些模型都是共用一张贴图的就想共用一个材质球,所以每次都要
  • Unity3D游戏开发之虚拟现实项目开发流程  欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学院,致力于打造...
  • unity shader 玻璃效果 折射效果

    千次阅读 2019-01-11 11:15:07
    Shader "Unlit/render_reflect" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags {"Queue" = "... GrabPass{&quo
  • unity3d 2019烘焙教程 持续更新中

    万次阅读 多人点赞 2019-08-20 11:06:12
    很多刚刚接触Unity3d的童鞋花了大量的时间自学,可总是把握不好Unity3d的烘焙,刚从一个坑里爬出来,又陷入另一个新的坑,每次烘焙一个场景少则几个小时,多则几十个小时,机器总是处于假死机状态,半天看不到结果,...
  • unity折射光线算法

    2019-04-22 20:54:00
    人工智能的三大基石—算法、数据和计算能力,算法作为其中之一,是非常重要的,那么人工智能都会涉及哪些算法呢?不同算法适用于哪些场景呢? 一、按照模型训练方式不同可以分为监督学习(Supervised Learning),...
  • unity3d 水体water effect的制作, 本次主要对水体的波动进行研究,sin,cos,Gerstner波等。
  • Unity3D引擎之Shader Forge应用

    千次阅读 2017-04-04 17:52:42
    已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。CSDN视频网址:http://edu.csdn.net/lecturer/144 本篇博客给读者介绍一个材质渲染的组件-Shader Forge,...
  • Unity3D 优化总篇

    千次阅读 2015-05-08 09:35:32
    转载【整理】unity3d优化总结篇 -- yxriyin 对项目优化有很多点,如:mesh合并 ,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等, 优化:  1. 更新不透明贴图的压缩格式为ETC 4bit,...
1 2 3 4 5 ... 20
收藏数 825
精华内容 330
关键字:

unity3d 折射