Unity3d 镜面反射 vertex and frag Shader源代码
Unity3d 镜面反射
网上能找到的基本上是固定管道或表面渲染的shader。
特此翻译为顶点、片段渲染的Shader,
本源代码仅仅涉及shader与cs部分。
Editor部分使用NGUI绘制的,
请自行下载NGUI
unity3d 版本号:v4.3.1
ReflectionMirror.cs
using UnityEngine;
using System.Collections;
using System; /// <summary>
/// 反射效果
/// </summary>
[AddComponentMenu("GameCore/SpecialEffect/Reflection Mirror")]
[ExecuteInEditMode]
public class ReflectionMirror : MonoBehaviour
{
public bool DisablePixelLights = true;
public int TextureSize = 512;
public float ClipPlaneOffset = 0;
public LayerMask 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 (DisablePixelLights)
QualitySettings.pixelLightCount = 0; CoreTool.CloneCameraModes(cam, reflectionCamera); // Render reflection
// Reflect camera around reflection plane
float d = -Vector3.Dot(normal, pos) - ClipPlaneOffset;
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, ClipPlaneOffset); Matrix4x4 projection = cam.projectionMatrix; projection = CoreTool.CalculateObliqueMatrix(projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.cullingMask = ~(1 << 4) & 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 (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();
} // 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 != TextureSize)
{
if (m_ReflectionTexture)
DestroyImmediate(m_ReflectionTexture);
m_ReflectionTexture = new RenderTexture(TextureSize, TextureSize,0);
m_ReflectionTexture.name = "__MirrorReflection" + GetInstanceID();
m_ReflectionTexture.isPowerOfTwo = true;
m_ReflectionTexture.hideFlags = HideFlags.DontSave;
m_ReflectionTexture.antiAliasing = 4;
m_ReflectionTexture.anisoLevel = 0;
m_OldReflectionTextureSize = 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;
}
}
}
ReflectionMirrorEditor.cs
using System.Collections;
using System;
using UnityEditor;
using UnityEngine;
/// <summary>
/// 反射效果
/// </summary>
[CustomEditor(typeof(ReflectionMirror))]
public class ReflectionMirrorEditor : Editor
{
string[] _renderTextureOptions = new string[8] { "16", "32", "64", "128", "256", "512", "1024", "2048" };
int _renderTextureWidthDefaultIndex = 5;
int _renderTextureWidthIndex = 5;
SerializedProperty _sp;
public override void OnInspectorGUI()
{
EditorGUILayout.HelpBox("This the reflection effect,it has mirror or sphere reflection!",MessageType.Info);
if (NGUIEditorTools.DrawHeader("Reflection Settings"))
{
NGUIEditorTools.BeginContents();
{
NGUIEditorTools.DrawProperty("Disable PixelLights", this.serializedObject, "DisablePixelLights");
NGUIEditorTools.DrawProperty("Reflect Layers", this.serializedObject, "ReflectLayers");
NGUIEditorTools.DrawProperty("ClipPlane Offset", this.serializedObject, "ClipPlaneOffset");
}
NGUIEditorTools.EndContents();
}
if (NGUIEditorTools.DrawHeader("Render Texture Settings"))
{
NGUIEditorTools.BeginContents();
{
_sp = this.serializedObject.FindProperty("TextureSize");
_renderTextureWidthIndex = GetTextureOptionsIndex(_sp.intValue.ToString());
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("TexSize:", GUILayout.Width(100));
_renderTextureWidthIndex = EditorGUILayout.Popup(_renderTextureWidthIndex, _renderTextureOptions);
EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Make Default Value"))
{
_renderTextureWidthIndex = _renderTextureWidthDefaultIndex;
}
_sp.intValue = int.Parse(_renderTextureOptions[_renderTextureWidthIndex]);
}
NGUIEditorTools.EndContents();
} this.serializedObject.ApplyModifiedProperties();
} int GetTextureOptionsIndex(string value)
{
int index = 0;
for (int i = 0; i < _renderTextureOptions.Length; i++)
{
if (_renderTextureOptions[i].Equals(value, StringComparison.OrdinalIgnoreCase))
{
index = i;
}
}
return index;
}
}
Shader
Shader "GameCore/SpecialEffect/Reflection Mirror"
{
Properties {
_ReflectionTex ("Reflection", 2D) = "white" {TexGen ObjectLinear }
_ReflectionColor("Color",Color) = (1,1,1,1)
}
//PC
SubShader {
Tags {
"RenderType"="Opaque"}
LOD 100
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" uniform float4x4 _ProjMatrix;
uniform sampler2D _ReflectionTex;
float4 _ReflectionColor;
struct outvertex {
float4 pos : SV_POSITION;
float3 uv : TEXCOORD0;
};
outvertex vert(appdata_tan v) {
outvertex o;
o.pos = mul (UNITY_MATRIX_MVP,v.vertex);
float3 viewDir = ObjSpaceViewDir(v.vertex);
o.uv = mul(_ProjMatrix,float4(viewDir,0));
return o;
} float4 frag(outvertex i) : COLOR {
half4 reflcol = tex2Dproj(_ReflectionTex,i.uv);
return reflcol*_ReflectionColor;
}
ENDCG
}
}
//Mobile
SubShader {
Tags {
"RenderType"="Opaque"}
LOD 100
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" uniform float4x4 _ProjMatrix;
uniform sampler2D _ReflectionTex;
float4 _ReflectionColor;
struct outvertex {
float4 pos : SV_POSITION;
float3 uv : TEXCOORD0;
float4 posProj;
};
outvertex vert(appdata_tan v) {
outvertex o;
o.pos = mul (UNITY_MATRIX_MVP,v.vertex);
o.posProj = mul(_ProjMatrix, v.vertex);
return o;
}
float4 frag(outvertex i) : COLOR {
half4 reflcol = tex2D(_ReflectionTex,float2(i.posProj) / i.posProj.w);
return reflcol*_ReflectionColor;
}
ENDCG
}
}
}
来源链接: http://pan.baidu.com/s/1gdyzyNL
Unity3d 镜面反射 vertex and frag Shader源代码的更多相关文章
- Unity3d 镜面折射 vertex and frag Shader源代码
Unity3d 镜面折射 网上能找到的基本上是固定管道或表面渲染的shader. 特此翻译为顶点.片段渲染的Shader, 本源代码仅仅涉及shader与cs部分, 请自行下载NGUI unity ...
- unity3D 涂涂乐使用shader实现上色效果
unity3D 涂涂乐使用shader实现上色效果 之前我博文里面发过一个简单的通过截图方式来实现的模型上色方法,但是那个方法不合适商用,因为你需要对的很准确才可以把贴图完美截取下来,只要你手抖了一下 ...
- UnityShader之顶点片段着色器Vertex and Fragment Shader【Shader资料】
顶点片段着色器 V&F Shader:英文全称Vertex and Fragment Shader,最强大的Shader类型,也是我们在使用ShaderLab中的重点部分,属于可编程管线,使用 ...
- Vertex And Fragment Shader(顶点和片段着色器)
Vertex And Fragment Shader(顶点和片段着色器) Shader "Unlit/ Vertex_And_Fragment_Shader " { Proper ...
- Unity3D之高级渲染-Shader Forge增强版
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家.特邀编辑.畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...
- ShaderLab中vertex fragment类Shader基础格式笔记
//U3D用的shader语言叫ShaderLab,基础语法官方文档地址 //https://docs.unity3d.com/Manual/SL-Shader.html //开头指明名字,可以在别的 ...
- Unity3D学习笔记3——Unity Shader的初步使用
目录 1. 概述 2. 详论 2.1. 创建材质 2.2. 着色器 2.2.1. 名称 2.2.2. 属性 2.2.3. SubShader 2.2.3.1. 标签(Tags) 2.2.3.2. 渲染 ...
- Vertex and Fragment Shader
Semantics语义词: 定义:GPU工作时,数据通常暂存在寄存器,那么在Cg中,语义词就指定了输入/输出数据和图形硬件寄存器之间的映射关系. 原理:根据输入语义,图形处理器从某个寄存器取数据:然后 ...
- Unity3D 屏幕空间雪场景Shader渲染
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
随机推荐
- The example program of C on point
计划一: #include<stdio.h> #define N_VALUES 5 int main( void ) { float values[N_VALUES]; float *vp ...
- java线程池的注意事项
java线程池是建立一个技术进步的线程.到来之前线程池打造一批在线程的线程尚未,队列上的备用,然后再利用这些资源.减少频繁创建和销毁对象, 1.jdk1.5以上提供了现成的线程池 2.java线程池的 ...
- 【从翻译mos文章】Weblogic AdminServer 启动fail,报错"unable to get file lock, will retry"
Weblogic AdminServer 启动fail,报错"unable to get file lock, will retry" 参考原始: Weblogic AdminSe ...
- [Windows Phone] 以多国语言做为开发前提 (2)
原文:[Windows Phone] 以多国语言做为开发前提 (2) ? 前言 在先前的文章 [Windows Phone 开发 - 以多国语言做为开发前提 (1)] 中说明了简单的多国语言范例,今天 ...
- ASCII与Unicode编码消息写文件浅析
[文章摘要] ASCII与Unicode是两种常见的字符编码. 它们的表示方法不一样,因而在程序中就要差别处理. 本文基于作者的实际开发经验,对ASCII与Unicode两种字符编码消息的写文件过程进 ...
- C++primer读书笔记9-转换和类类型
有时指定自己的类类型来表示某些类型的数据,如SmallInt,然后在为了便于计算将指定一个转换算,类类型,在某些情况下,自己主动转换为指定的类型 <1>转换操作符 operator typ ...
- swift的struct本节描述结构的类型
<span style="font-size:24px;">struct David { var x = 0;//一个结构的定义,两个字段x,y var y = 0;/ ...
- Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.ClassVisitor
1.错误描写叙述 信息: Setting autowire strategy to name 2014-7-13 1:37:43 org.apache.struts2.spring.StrutsSpr ...
- Cocos发展Visual Studio下一个libcurl图书馆开发环境的搭建
我们解释win32在Visual Studio下一个libcurl图书馆开发环境的搭建.Cocos2d-x发动机实际上与Win32在访问libcurl库.Cocos2d-x 3.x在libcurl库文 ...
- javascript中的三角学
三角学主要研究三角形和它们的边角关系,包含一个90度角的三角形被称为直角三角形.在这里主要研究直角三角形相关的知识. 1. 角度和弧度 360(角度) = 2*Math.PI(弧度) degrees ...