效果图:
(立方体是自传,另一个是不动的。同时转动了一下相机,技术有限,外加美术资源匮乏,效果粗鄙~~,但是技术和知识点是没有问题的)
(一)晶体效果分析:
1.外围是自发光( fresnal 效果)
2.中间是要显示的图像效果( 依然是用fresnal因子裁剪的效果)
3.随着相机视角的变动。。。 看到的中间的效果始终是面向相机的(利用相机空间中的xy作为uv 对纹理采样,) 其中调整uv的缩放和拉伸 实现最终的效果。
注释:在frag中的向量: normal viewDir 等 都要归一化后再用作计算。。。
(二)晶体逻辑:
Shader "Unlit/Crystal_Code"
{
Properties
{
_EmissMask("EmissMask",2D) = "white"{}
_MainTex ("Texture", 2D) = "white" {}
_UVDistort("MainUV Distort Scaler",Range(0,1)) = 0.1
_ReflectCube ("RelectCube",Cube) = "_Skybox"{}
_ReflectIntensity("_ReflectIntensity",float) = 2
_NormalMap("normalmap",2D) = "white"{}
_BumpScaler("BumpScaler",float) = 1.0
_RimColor("RimColor",color) = (0,1,0,1)
_FresnelBias("_FresnelBias",Range(0,1)) = 0.5
_FresnelSacle("_FresnelSacle",float) = 0.5
_FresnelPower("_FresnelPower",float) = 5
_MainTexTillingAndScale("MainTexTillingAndScale",vector) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float4 T2N0 : TEXCOORD1;
float4 T2N1 : TEXCOORD2;
float4 T2N2 : TEXCOORD3;
float3 worldView : TEXCOORD4;
float3 worldReflect : TEXCOORD5;
float2 UVMain : TEXCOORD6;
};
sampler2D _MainTex,_EmissMask;
float4 _MainTex_ST;
samplerCUBE _ReflectCube;
sampler2D _NormalMap;
float _BumpScaler;
float4 _RimColor;
float _FresnelSacle;
float _FresnelBias;
float _FresnelPower;
float _ReflectIntensity;
float _UVDistort;
float4 _MainTexTillingAndScale;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
float3 worldT = UnityObjectToWorldDir(v.tangent);
float3 worldN = UnityObjectToWorldNormal(v.normal);
float3 worldB = cross(worldT,worldN) * v.tangent.w;
float3 worldPos = mul(unity_ObjectToWorld,v.vertex);
// 在view空间中的位置 和偏移量
float3 viewPos = UnityObjectToViewPos(v.vertex.xyz);
//float3 viewPos = mul(unity_ObjectToView,v.vertex);
float3 viewRoot = UnityObjectToViewPos(float3(0,0,0));
float3 diff = viewPos - viewRoot;
// 先缩放 后平移
float2 mainUV = diff.xy * _MainTexTillingAndScale.xy + _MainTexTillingAndScale.zw;
o.UVMain = mainUV;
o.T2N0 = float4(worldT.x,worldB.x,worldN.x,worldPos.x);
o.T2N1 = float4(worldT.y,worldB.y,worldN.y,worldPos.y);
o.T2N2 = float4(worldT.z,worldB.z,worldN.z,worldPos.z);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float3 worldPos = float3(i.T2N0.z,i.T2N1.z,i.T2N2.z);
float3 worldNormal = UnpackNormal(tex2D(_NormalMap,i.uv));
//worldNormal.xy *= _BumpScaler;
//worldNormal.z = sqrt( 1.0- saturate(dot(worldNormal.xy,worldNormal.xy)));
worldNormal = float3(dot(float3(i.T2N0.xyz),worldNormal),dot(float3(i.T2N1.xyz),worldNormal),dot(float3(i.T2N2.xyz),worldNormal));
float3 worldView = normalize(UnityWorldSpaceViewDir(worldPos));
float fresnelFactor = saturate(1 - dot(worldNormal,worldView));
float fresnel = _FresnelSacle * pow(1 - dot(worldNormal,worldView),_FresnelPower);
// 反射
float3 worldReflect = reflect(-worldView,worldNormal);
float4 refCol = texCUBE(_ReflectCube,worldReflect) * _ReflectIntensity * fresnelFactor;
// 自发光
float4 endCol = _RimColor * (fresnel + tex2D(_EmissMask,i.uv).r);
// 此处的uv 扭曲 用view空间中normal 会更好(为了体现出多面体的不规则的折射感觉)
float2 mainUV = i.UVMain + worldNormal.xy * _UVDistort;
// sample the texture
fixed4 mainCol = tex2D(_MainTex, i.UVMain);
return refCol + endCol + mainCol;
}
ENDCG
}
}
}
由于是始终面向相机, 你是不是想到了 ”广告牌“技术!!!
好像想到的关联的东西越来越多。。。。