unity 镜面反射_unity镜面反射 - CSDN
精华内容
参与话题
  • Unity实现镜面反射

    2020-07-28 23:32:13
    unity实现镜面反射,将脚本放在需要镜面的面板上,将shader作为他的材质,就能实时形成镜子
  • unity镜面反射效果

    2020-07-28 23:33:36
    unity镜面反射效果
  • Unity3D--镜面反射

    千次阅读 2013-03-20 22:36:00
    首先,新建一个Shader: Shader "FX/Mirror Reflection"{ Properties { _MainTex (“Base (RGB)”, 2D) = “white” {} _ReflectionTex (“Reflection”, 2D) = “white” { TexGen ObjectLinear } ...

    首先,新建一个Shader:

    Shader "FX/Mirror Reflection"{
    Properties {
    _MainTex (“Base (RGB)”, 2D) = “white” {}
    _ReflectionTex (“Reflection”, 2D) = “white” { TexGen ObjectLinear }
    }
    // two texture cards: full thing
    Subshader {
    Pass {
    SetTexture[_MainTex] { combine texture }
    SetTexture[_ReflectionTex] { matrix [_ProjMatrix] combine texture * previous }
    }
    }
    // fallback: just main texture
    Subshader {
    Pass {
    SetTexture [_MainTex] { combine texture }
    }
    }
    }
    


     

    第二,新建一个脚本MirrorReflection.cs:

    注意:被赋予脚本的物体不能缩放也就是物体的Rransform.scale的值均为1。

    using UnityEngine;
    using System.Collections;
    
    // This is in fact just the Water script from Pro Standard Assets,
    // just with refraction stuff removed.
    
    [ExecuteInEditMode] // Make mirror live-update even when not in play mode
    public class MirrorReflection : MonoBehaviour
    {
    public bool m_DisablePixelLights = true;
    public int m_TextureSize = 256;
    public float m_ClipPlaneOffset = 0.07f;
    
    public LayerMask m_ReflectLayers = -1;
    
    private Hashtable m_ReflectionCameras = new Hashtable(); // Camera -> Camera table
    
    private RenderTexture m_ReflectionTexture = null;
    private int m_OldReflectionTextureSize = 0;
    
    private static bool s_InsideRendering = false;
    
    // This is called when it’s known that the object will be rendered by some
    // camera. We render reflections and do other updates here.
    // Because the script executes in edit mode, reflections for the scene view
    // camera will just work!
    public void OnWillRenderObject()
    {
    if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled)
    return;
    
    Camera cam = Camera.current;
    if (!cam)
    return;
    
    // Safeguard from recursive reflections.
    if (s_InsideRendering)
    return;
    s_InsideRendering = true;
    
    Camera reflectionCamera;
    CreateMirrorObjects(cam, out reflectionCamera);
    
    // find out the reflection plane: position and normal in world space
    Vector3 pos = transform.position;
    Vector3 normal = transform.up;
    
    // Optionally disable pixel lights for reflection
    int oldPixelLightCount = QualitySettings.pixelLightCount;
    if (m_DisablePixelLights)
    QualitySettings.pixelLightCount = 0;
    
    UpdateCameraModes(cam, reflectionCamera);
    
    // Render reflection
    // Reflect camera around reflection plane
    float d = -Vector3.Dot(normal, pos) – m_ClipPlaneOffset;
    Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
    
    Matrix4x4 reflection = Matrix4x4.zero;
    CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f);
    Matrix4x4 projection = cam.projectionMatrix;
    CalculateObliqueMatrix(ref projection, clipPlane);
    reflectionCamera.projectionMatrix = projection;
    
    reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer
    reflectionCamera.targetTexture = m_ReflectionTexture;
    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);
    Material[] materials = renderer.sharedMaterials;
    foreach (Material mat in materials)
    {
    if (mat.HasProperty("_ReflectionTex"))
    mat.SetTexture("_ReflectionTex", m_ReflectionTexture);
    }
    
    // Set matrix on the shader that transforms UVs from object space into screen
    // space. We want to just project reflection texture on screen.
    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 mtx = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z));
    mtx = scaleOffset * cam.projectionMatrix * cam.worldToCameraMatrix * mtx;
    foreach (Material mat in materials)
    {
    mat.SetMatrix("_ProjMatrix", mtx);
    }
    
    // Restore pixel light count
    if (m_DisablePixelLights)
    QualitySettings.pixelLightCount = oldPixelLightCount;
    
    s_InsideRendering = false;
    }
    
    // Cleanup all the objects we possibly have created
    void OnDisable()
    {
    if (m_ReflectionTexture)
    {
    DestroyImmediate(m_ReflectionTexture);
    m_ReflectionTexture = null;
    }
    foreach (DictionaryEntry kvp in m_ReflectionCameras)
    DestroyImmediate(((Camera)kvp.Value).gameObject);
    m_ReflectionCameras.Clear();
    }
    
    private void UpdateCameraModes(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.farClipPlane = src.farClipPlane;
    dest.nearClipPlane = src.nearClipPlane;
    dest.orthographic = src.orthographic;
    dest.fieldOfView = src.fieldOfView;
    dest.aspect = src.aspect;
    dest.orthographicSize = src.orthographicSize;
    }
    
    // On-demand create any objects we need
    private void CreateMirrorObjects(Camera currentCamera, out Camera reflectionCamera)
    {
    reflectionCamera = null;
    
    // Reflection render texture
    if (!m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize)
    {
    if (m_ReflectionTexture)
    DestroyImmediate(m_ReflectionTexture);
    m_ReflectionTexture = new RenderTexture(m_TextureSize, m_TextureSize, 16);
    m_ReflectionTexture.name = "__MirrorReflection" + GetInstanceID();
    m_ReflectionTexture.isPowerOfTwo = true;
    m_ReflectionTexture.hideFlags = HideFlags.DontSave;
    m_OldReflectionTextureSize = m_TextureSize;
    }
    
    // Camera for reflection
    reflectionCamera = m_ReflectionCameras[currentCamera] as Camera;
    if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO
    {
    GameObject go = new GameObject("Mirror Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox));
    reflectionCamera = go.camera;
    reflectionCamera.enabled = false;
    reflectionCamera.transform.position = transform.position;
    reflectionCamera.transform.rotation = transform.rotation;
    reflectionCamera.gameObject.AddComponent("FlareLayer");
    go.hideFlags = HideFlags.HideAndDontSave;
    m_ReflectionCameras[currentCamera] = reflectionCamera;
    }
    }
    
    // Extended sign: returns -1, 0 or 1 based on sign of a
    private static float sgn(float a)
    {
    if (a > 0.0f) return 1.0f;
    if (a < 0.0f) return -1.0f;
    return 0.0f;
    }
    
    // Given position/normal of the plane, calculates plane in camera space.
    private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
    {
    Vector3 offsetPos = pos + normal * m_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));
    }
    
    // Adjusts the given projection matrix so that near plane is the given clipPlane
    // clipPlane is given in camera space. See article in Game Programming Gems 5.
    private static void CalculateObliqueMatrix(ref Matrix4x4 projection, Vector4 clipPlane)
    {
    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 – projection[3];
    projection[6] = c.y – projection[7];
    projection[10] = c.z – projection[11];
    projection[14] = c.w – projection[15];
    }
    
    // Calculates reflection matrix around the given plane
    private static void CalculateReflectionMatrix(ref 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;
    }
    }
    


     

    展开全文
  • Unity3D镜面反射

    千次阅读 2014-12-03 11:56:46
    点击这里下载 原文地址点击这里
    展开全文
  • Unity3D 镜面反射

    千次阅读 2013-10-16 14:37:18
    Unity3D 镜面反射  这是官方CharacterCustomization事例中的镜面反射shader。 1.首先需要一个plane当镜子,将代码MirrorReflection.cs文件绑定到镜子上。 2.新建一个材质,绑定到镜子上,选择shader FX/Ref
    原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅
    QQ群:【119706192 本文链接地址:
    Unity3D 镜面反射 
    

    这是官方CharacterCustomization事例中的镜面反射shader。

    1.首先需要一个plane当镜子,将代码MirrorReflection.cs文件绑定到镜子上。

    2.新建一个材质,绑定到镜子上,选择shader FX/Reflection。

    3.TextureSize 越大,越清晰~

    展开全文
  • Unity实现镜面反射效果

    千次阅读 2019-09-30 10:33:21
    1、准备工作 ①创建一个Sphere为发射点,添加LineRenderer组件...③最后随便创建几个Cube当反射墙面(顺便修改tag为"Mirro")。 2、编写脚本,挂到Sphere上。 using System.Collections.Generic; using UnityEngine...

    1、准备工作

    ①创建一个Sphere为发射点,添加LineRenderer组件。
    ②调整LineRenderer组件下的宽度属性:
    在这里插入图片描述
    当然想更好看些可以添加个材质修改个颜色啥的。
    在这里插入图片描述
    ③最后随便创建几个Cube当反射墙面(顺便修改tag为"Mirro")。
    在这里插入图片描述

    2、编写脚本,挂到Sphere上。

    using System.Collections.Generic;
    using UnityEngine;
    
    public class LaserControl : MonoBehaviour
    {
        /// <summary>
        /// LineRenderer组件
        /// </summary>
        public LineRenderer lr;
        /// <summary>
        /// 发射点
        /// </summary>
        public Transform gunTransfrom;
        /// <summary>
        /// 射线检测到的碰撞信息
        /// </summary>
        private RaycastHit hit;
        /// <summary>
        /// LineRenderer线段的两端点信息
        /// </summary>
        private List<Vector3> linePoints = new List<Vector3>();
    
    
        private void Update()
        {
            //清空上一帧的两端点信息
            linePoints.Clear();
            //执行反射方法
            Reflection(gunTransfrom.position, gunTransfrom.forward);
            //设置LineRenderer端点数量
            lr.positionCount = linePoints.Count;
            //遍历所有端点
            for (int i = 0; i < linePoints.Count; i++)
            {
                //设置两端点信息
                lr.SetPosition(i, linePoints[i]);
            }
        }
        /// <summary>
        /// 反射方法
        /// </summary>
        /// <param name="position">发射点位置</param>
        /// <param name="direction">方向</param>
        private void Reflection(Vector3 position, Vector3 direction)
        {
            //在Scene视图中观察射线是否正确射出
            Debug.DrawRay(position, direction * 1000, Color.red);
            //判断射线是否打到墙面
            if (Physics.Raycast(position, direction, out hit, float.PositiveInfinity))
            {
                //如果碰到的是墙面
                if (hit.collider.tag == "Mirro")
                {
                    //入射向量
                    Vector3 inLine = hit.point - position;
                    //入射线与法向量的夹角
                    float angle = 180 - Vector3.Angle(inLine, hit.normal);
                    //法向量的长度
                    float normalx = Mathf.Cos(angle * Mathf.Deg2Rad) * Vector3.Distance(position, hit.point);
                    //法向量的终点
                    Vector3 normalPoint = hit.point + hit.normal.normalized * normalx;
                    //反射点
                    Vector3 outPoint = normalPoint - position + normalPoint;
                    //反射向量
                    Vector3 outLine = outPoint - hit.point;
                    //存储端点
                    linePoints.Add(position);
                    //递归
                    Reflection(hit.point, outLine);
                }
                //如果不是墙面
                else if (hit.collider != null)
                {  
                    //停止反射
                    linePoints.Add(position);
                    linePoints.Add(hit.point);
                }
            }
            //如果没有照射到任何物体
            else
            {
                //射线正常射出5000的长度
                linePoints.Add(position);
                linePoints.Add(direction.normalized * 5000);
            }
        }
    }
    
    

    最后别忘了回到Unity中给LineRenderer和发射点赋值:在这里插入图片描述
    (两个都把Sphere拖上去就行)
    这样就完成了简单的反射效果。

    有更好的方法欢迎指点。

    如果对你有帮助,酌情打赏~

    在这里插入图片描述 在这里插入图片描述

    展开全文
  • Unity3D——镜面反射原理及实现

    千次阅读 2016-12-23 17:03:22
    原文:http://gad.qq.com/user/myarticle?id=438905
  • 无需自己找镜子Shader,只需2个脚本即可在Unity中创建一个简单的模拟镜面反射效果。 使用教程链接:https://blog.csdn.net/ChinarCSDN/article/details/80862999
  • 镜面反射与观察视角的联系 系列6中我已经说明了材料表面的平整程度决定了镜面反射的明显与否,现实生活中找不到绝对平的物体表面,所以我们引入一个概念,每一种材料的表面的平整程度为Nshininess, n越大越平整,越...
  • Unity:镜面反射

    千次阅读 2012-09-25 00:15:01
    http://bbs.9ria.com/thread-122235-1-1.html 管用,试过了~~~
  • Unity 镜面反射

    2017-09-11 17:09:09
    一、公式 specuColor = Kd*_LightColor0*pow(max(R·V 0), _Shininess); Kd–环境光颜色、顶点...R·V–反射光向量 · 观察向量 二、逐顶点着色(古罗着色)Shader "Custom/MySpecular_Vertex" { Properties {
  • Unity镜面反射脚本

    2020-10-17 10:16:49
    unity镜面反射脚本,包里4个文件 Mirror.cs :与shader互动的脚本,使用这组材质同时要把这个脚本拖给使用的物体才能生效 Mirror-BumpSpec.shader 实时镜面反射shader 可以配合法线贴图一起用 适用于平面物体 ...
  • 最终的效果;地址 http://bbs.9ria.com/forum.php?mod=viewthread&tid=122235&extra=page%3D1%26filter%3Dtypeid%26typeid%3D329&page=1
  • 今天来说一下在游戏中如何使用镜面反射来给玩家制造出强烈的视觉冲击和超现实感。  在Unity中,已经为我们提供了一个高光函数,我们可以在自己的着色器中使用。这个函数也就是BlinnPhong镜面反射光照模型,它是...
  • Unity环境镜面效果

    2020-07-30 23:32:00
    Unity环境镜面反射效果 利用Unity提供的设置、Shader、Cube、 简单的设置即可完成对环境的反射效果,无需写代码。 教程地址:https://blog.csdn.net/chinarcsdn/article/details/80210924
  • 很好用的Unity镜面脚本~里面带有说明文档!
  • shader镜面反射
  • 什么是镜面反射?   镜面反射(Specular)又叫高光反射,主要可以来模拟非常光滑的平面受到光线照射所产生的反射效果,使得物体看起来更光滑有光泽。 如何实现镜面反射?   镜面反射主要有两种实现方式:   Phong...
  • 话不多说先上图,有镜面反射,投影器方式实现阴影,下雨效果,工程放最后 镜面反射 镜面反射原理:通俗点说法就是就是在摄象机对称的正下方和主摄象机看同一个焦点,这个反射摄象机看到的东西就是镜面反射的东西...
  • 前几天,家里出了一些问题,搞得心情很不好,面试我也取消了。 唉,反正那个伤心啊,不过,昨天处理好了。 所以说啊,家和万事兴。...今天实现:Unity Shader - 实现类似镜面反射、水面扰动效果 Quad ...
1 2 3 4 5 ... 20
收藏数 2,117
精华内容 846
热门标签
关键字:

unity 镜面反射