unity3d 实时动态反射周围世界

先截出一个效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29sZjk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

要反射出周围世界

我们仅仅须要一个周围世界的cubemap

先来看反射的shader

首先声明变量:

_Cubemap                  须要反射的cubemap

_ReflAmount              反射的强度

	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_MainTint ("Diffuse Color", Color) = (1, 1, 1, 1)
		_Cubemap ("CubeMap", CUBE) = ""{}
		_ReflAmount ("Reflection Amount", Range(0.01, 1)) = 0.5
	}

还须要为input结构体添加一个參数

float3 worldRefl

worldRef 即为世界空间的反射向量

内置的worldRefl 来做立方图反射

		struct Input {
			float2 uv_MainTex;
			float3 worldRefl;////worldRefl:即为世界空间的反射向量///内置的worldRefl 来做立方图反射(cubemap         reflection)//为了计算反射
		};

在surf函数中给Emission(像素的发散颜色)赋值

texCUBE函数,获得立方图纹理的信息

再乘上我们之前定义的_ReflAmount反射强度

o.Emission = texCUBE(_Cubemap, IN.worldRefl).rgb * _ReflAmount;

然后就ok了,

我们获得了一个能够反射周围世界的shader

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
			o.Emission = texCUBE(_Cubemap, IN.worldRefl).rgb * _ReflAmount;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}

接下来要解决的问题就是实时

假设我们能实时更新这个cubemap,就能够实时反射了。

接下来我们建立一个c#脚本

所有变量:

要更新的cubemap

public Cubemap cubmap;

这里须要注意:我们要新建立一个camera放在要反射的物体的位置上。成为要反射的物体的子物体

不是main camera

public Camera cam;

这里的材质就是上面shader的材质

private Material curMat;

    public Cubemap cubmap;
    public Camera cam;
    private Material curMat;

初始化curMat。

就是获取我们要反射物体的材质

curMat = renderer.sharedMaterial;

在start函数中建立一个定时器

InvokeRepeating("UpdateChange", 1, 0.1f);

1秒后调用UpdateChange () 函数。之后每0.1秒调用一次

    void Start()
    {
        InvokeRepeating("UpdateChange", 1, 0.1f);
        curMat = renderer.sharedMaterial;
    }

再建立这个 UpdateChange () 函数

保证相机的角度不变

cam.transform.rotation = Quaternion.identity;

这个是我们的核心函数。

RenderToCubemap渲染到立方图,烘焙场景的静态立方贴图,赋给參数

cam.camera.RenderToCubemap(cubmap);

再把这个cubemap传给上面shader的_Cubemap变量中,就做到了实时更新

curMat.SetTexture("_Cubemap", cubmap);

    void UpdateChange()
    {
        cam.transform.rotation = Quaternion.identity;
        cam.camera.RenderToCubemap(cubmap);

        curMat.SetTexture("_Cubemap", cubmap);
    }

ok。

先来看看效果:

从波动的水体就能看出来确实实时反射了周围的环境

再让我们分析一下效果与效率问题,

不可否认的是,这样的方法尽管能做到实时反射,可是确实非常“浪费”,并且清晰度高了会非常卡

看看cubemap的FaceSize值对效果的影响

32:

非常明显,32相当模糊。相当“锯齿”

64:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29sZjk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

64也是非常模糊。可是比32的要好一些,已经有一些凹凸感了

128:

128的效果感觉还能够。可是不是特别清晰

256:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29sZjk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

到256的时候能够说实在这么简单的场景里面刚好不卡。

在512时就有一点点卡了。

事实上256在游戏其中也不有用。

建议在128一下

512:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29sZjk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

512已经非常清晰了,有一点点卡。

1024:

截这张1024时,我的unity差点儿卡的不动了,帧率不到10fps吧,= =;有点清晰的过头了

看1024卡的那么嚣张就没敢试2048的预计也和1024几乎相同。

以上就结束了,

本片不须要什么图片资源大家能够试试

下面所有代码:

c#;

using UnityEngine;
using System.Collections;

public class d_cubMap : MonoBehaviour
{
    public Cubemap cubmap;
    public Camera cam;
    private Material curMat;
    // Use this for initialization
    void Start()
    {
        InvokeRepeating("UpdateChange", 1, 0.1f);
        curMat = renderer.sharedMaterial;
    }
    void UpdateChange()
    {
        cam.transform.rotation = Quaternion.identity;
        cam.camera.RenderToCubemap(cubmap);

        curMat.SetTexture("_Cubemap", cubmap);
    }

}

shader;

Shader "Custom/cubmap" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_MainTint ("Diffuse Color", Color) = (1, 1, 1, 1)
		_Cubemap ("CubeMap", CUBE) = ""{}
		_ReflAmount ("Reflection Amount", Range(0.01, 1)) = 0.5
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

			CGPROGRAM
#pragma surface surf Lambert

			sampler2D _MainTex;
		samplerCUBE _Cubemap;
		float4 _MainTint;
		float _ReflAmount;

		struct Input {
			float2 uv_MainTex;
			float3 worldRefl;////worldRefl:即为世界空间的反射向量///内置的worldRefl 来做立方图反射(cubemap         reflection)//为了计算反射
		};

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
			o.Emission = texCUBE(_Cubemap, IN.worldRefl).rgb * _ReflAmount;
			//	o.Albedo = texCUBE(_Cubemap, IN.worldRefl).rgb * _ReflAmount;//c.rgb;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

---------by   wolf96

时间: 2024-11-05 12:11:04

unity3d 实时动态反射周围世界的相关文章

[Unity3D]通过反射方式获取Game View当前选择的分辨率

System.Type T = System.Type.GetType("UnityEditor.GameView,UnityEditor"); System.Reflection.MethodInfo GetMainGameView = T.GetMethod("GetMainGameView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); S

Unity3D ShaderLab 简单的立方体图反射

Unity3D ShaderLab 简单的立方体图反射 反射是着色器模拟现实环境的一个关键因素,它能使我们的着色器渲染效果更加具备视觉冲击,因为他利用了我们周围的环境, 让着色器反射外界的场景信息并将他们反射到材质表面来模拟外部环境,所以我们会使用立方图[CubeMap]的6张纹理来模拟环境的色彩情况. 首先,创建Shader,创建材质球,准备立方图,双击Shader,进入代码编辑器. 从Properties 到CGPROGRAM,再到surf,本次功能较为简单,先看代码. code start

Unity3D ShaderLab 立方体图的反射遮罩

Unity3D ShaderLab 立方体图的反射遮罩 上一篇,简单的介绍了立方体图的反射,那么我们能不能使用一张问题对其进行指定遮罩呢?这样美工可以更好的控制图像的效果. 我们接着使用上一篇的shader代码,新建一个材质球,本次修改也是数行代码而已,所以 直接看完成代码. code start -------------------------------------------------------------------- Shader "91YGame/CubeMask" 

FireFly 服务端 Unity3D黑暗世界 客户端 问题

启动服务端成功截图: 连接成功截图: 测试服务端是否启动成功: 在Web输入:http://localhost:11009/  按回车 (查看cmd启动的服务端 是否多出如下显示) 服务端启动成功.PC unity3d客户端 连接也成功.但在手机端连接不成功 一直显示连接服务器有误 请检查网络 --------- beginning of /dev/log/system--------- beginning of /dev/log/mainD/Unity (32743): GL_EXT_debu

Unity3d 实时折射与反射

这里只贴出了实时折射与反射的脚本与shader, 关于NGUI部分则请大家自行下载. 这个版本主要缺点是折射部分平面的Layer必须是water层,如果有哪位高手能把这一块去掉,请记得把代码回复到这篇文章下,谢谢! Water.cs using UnityEngine; using System.Collections; using System; using System.Collections.Generic; /// <summary> /// 水面 /// </summary&g

Unity3D开发《我的世界》之七、番外篇

转载请注明出处:http://www.cnblogs.com/shamoyuu/p/unity_minecraft_07.html 本来上一篇就结束了,但是有小伙伴私信我觉得还差了很多重要的内容,比如方块如何构成了自然的地形,液体是如何流动,光照如何实现,以及红石电路,没有这些还怎么叫<我的世界>呢? 那这一篇就给大家一点启发,没有代码,只有思路(对于想真心钻研的人来讲应该够了). 一.自然地形的生成 首先使用柏林噪音生成起伏的山脉,就跟我们前面生成的一样. 然后生成生态. <我的世界&

关于Unity3d的世界空间和本地空间的一点思考

最近才开始学Unity3d,被这个本地空间和世界空间搞得有点晕头转向的.于是花了一点时间随便写了一点代码加深理解.代码如下: 1 public class MoveX : MonoBehaviour 2 { 3 void Update() 4 { 5 if (Input.GetMouseButtonDown(0)) 6 { 7 var two = new Vector3(2, 2, 2); 8 var localSpace = transform.InverseTransformPoint(tw

【Unity Shaders】Reflecting Your World —— Unity3D中的法线贴图和反射

http://blog.csdn.net/candycat1992/article/details/24541623 本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源(当然你也可以从官网下载). ========================================== 分割线 ==================================

Unity3D Android动态反射加载程序集

这种办法在iOS下是不让用的,只能在Android下用.用起来也很方便了. 1.先创建一个c#工程,引用到的UnityEngine.dll在Unity的安装目录里找吧 2.将编译的dll放入Unity工程,并打成assetBundle.(要把缀名改成.bytes,这个类型Unity才识别,才能打成assetbundle) 打bundle代码 #if UNITY_EDITOR [MenuItem("GameObject/BuildAsset")] static void BuildAss