1.Cubemap–反射折射
使用脚本来创建Cubemap
①通过Camera.RenderToCubemap 把任意位置观察到的场景图制作成一张Cubemap之中
②脚本使用自定义编译窗体的命令 – ScriptableWizard
③于特定位置首先渲染好Cubemap
⑤lerp(a,b,w)函数, 根据w返回ab之间的插值,像是中混合
创建cubemap脚本
using UnityEngine;
using UnityEditor;
using System.Collections;
public class RenderCubemapWizard : ScriptableWizard {
//自定义编辑窗体
public Transform renderFromPosition;
public Cubemap cubemap;
void OnWizardUpdate () {
helpString = "Select transform to render from and cubemap to render into";
isValid = (renderFromPosition != null) && (cubemap != null);
}
void OnWizardCreate () {
// create temporary camera for rendering
GameObject go = new GameObject( "CubemapCamera");
go.AddComponent<Camera>();
// place it on the object
go.transform.position = renderFromPosition.position;
// render into cubemap
go.GetComponent<Camera>().RenderToCubemap(cubemap);
// destroy temporary camera
DestroyImmediate( go );
}
[MenuItem("GameObject/Render into Cubemap")]
static void RenderCubemap () {
ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
"Render cubemap", "Render!");
}
}
反射效果
完整代码
Shader "Unlit/Reflection"
{
Properties
{
_Color ("Color Tint",Color) =(1,1,1,1)
_ReflectionColor ("Reflection Color",Color) =(1,1,1,1)
_ReflectionAmount ("Reflection Amount", Range(0,1)) = 1 //反射强度初始为最大
_Cubemap ("Reflection Cubemap",Cube) = "_Skybox"{
}
//不同于其他的纹理材质,这里的初始值是默认的天空盒子
}
SubShader
{
Tags {
"RenderType"="Opaque" "Queue"="Geometry" }//后面的这个自己写的时候忘记加上了}
Pass
{
Tags {
"LigheMode"= "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
//#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
// float2 uv : TEXCOORD0;没有用这个
float3 Normal :NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos :TEXCOORD0;
float3 worldNormal :TEXCOORD1 ;
float3 worldRefl :TEXCOORD2 ;
//忘记写视角方向
float3 worldViewDir :TEXCOORD3 ;
SHADOW_COORDS(4)
};
fixed4 _Color;
fixed4 _ReflectionColor;
fixed _ReflectionAmount;
samplerCUBE _Cubemap; //用的是samplerCUBE,且没有偏移的那一堆
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//在顶点着色器中计算
o.worldPos =mul(unity_ObjectToWorld,v.vertex).xyz; //不需要w分量的数据?应该是这样
o.worldNormal = UnityObjectToWorldNormal(v.Normal);
o.worldViewDir =UnityWorldSpaceViewDir(o.worldPos);
o.worldRefl =reflect(-o.worldViewDir, o.worldNormal); //使用reflec函数输入视角方向和法线方向
TRANSFER_SHADOW(o);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 worldNormal =normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 worldViewDir =normalize (i.worldViewDir);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 diffuse = _LightColor0.rgb * _Color.rgb * _ReflectionColor.rgb;
fixed3 reflection = texCUBE(_Cubemap,i.worldRefl).rgb * _ReflectionColor.rgb;
//通过反射方向对立方体进行采样
UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);
fixed3 color = ambient +lerp(diffuse,reflection,_ReflectionAmount) *atten;
return fixed4(color,1.0);
}
ENDCG
}
}
}
折射效果
o.worldRefr = refract(-normalize(o.worldViewDir