效果:
代码:
Shader "MyShader/Jade"
{
Properties
{
_DiffuseColor("漫反射颜色",color)=(1,1,1,1)
_ThicknessMap("厚度图",2d)="white"{}
_AddColor("叠加颜色",color)=(1,1,1,1)
_CubeMap("环境贴图",Cube)="white"{}
_RotateAngle("环境贴图旋转偏移",Range(0,360))=0
_BackLightContrast("透光对比度",float)=1.0
_BackLightScale("透光亮度",float)=1.0
_Distort("扭曲程度",Range(0,1))=1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
float _BackLightContrast;
float _Distort;
float _BackLightScale;
sampler2D _ThicknessMap;
samplerCUBE _CubeMap;
float4 _CubeMap_HDR;
float _RotateAngle;
float4 _DiffuseColor;
float4 _AddColor;
float3 Rotate(float3 v,float rotateAngle)
{
float rad = rotateAngle*UNITY_PI/180.0;
float2x2 rotateMul = float2x2(cos(rad),-sin(rad),sin(rad),cos(rad));
float2 rotate_dir = mul(rotateMul,v.xz);
return float3(v.x,rotate_dir.y,v.z);
}
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 normal_world : TEXCOORD1;
float3 pos_world : TEXCOORD2;
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
o.normal_world =normalize( mul(v.normal,unity_WorldToObject).xyz);
o.pos_world = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half3 normal_world = normalize(i.normal_world);
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz-i.pos_world);
half3 light_dir = normalize(_WorldSpaceLightPos0.xyz);
//漫反射
half NdotL = saturate(dot(normal_world,light_dir));
half3 diffuse_term = NdotL*_DiffuseColor*_LightColor0.xyz+_AddColor.xyz;
//透射光
half3 back_dir = -normalize(light_dir+normal_world*_Distort); //透射方向
half VdotBL = saturate(dot(view_dir,back_dir));
half thickness = 1.0-tex2D(_ThicknessMap,i.uv).r;
half back_light = saturate(pow(VdotBL,_BackLightContrast))*_BackLightScale;
half3 backlight_term = back_light*_LightColor0.xyz*thickness;
//环境光
half3 hdr_reflect_dir = normalize(reflect(-view_dir,normal_world));
half3 rotate_hdr_reflect_dir = Rotate(hdr_reflect_dir,_RotateAngle);
half frensil = 1-saturate(dot(normal_world,view_dir));
float4 hdr_color = texCUBE(_CubeMap,rotate_hdr_reflect_dir);
half3 env_color = DecodeHDR(hdr_color,_CubeMap_HDR)*frensil;
half3 final_color = backlight_term+env_color+diffuse_term;
return fixed4(final_color,1.0);
}
ENDCG
}
Pass
{
Tags{"LightMode"="ForwardAdd"}
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
float _BackLightContrast;
float _Distort;
float _BackLightScale;
sampler2D _ThicknessMap;
float3 Rotate(float3 v,float rotateAngle)
{
float rad = rotateAngle*UNITY_PI/180.0;
float2x2 rotateMul = float2x2(cos(rad),-sin(rad),sin(rad),cos(rad));
float2 rotate_dir = mul(rotateMul,v.xz);
return float3(v.x,rotate_dir.y,v.z);
}
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 normal_world : TEXCOORD1;
float3 pos_world : TEXCOORD2;
LIGHTING_COORDS(3,4)
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
o.normal_world =normalize( mul(v.normal,unity_WorldToObject).xyz);
o.pos_world = mul(unity_ObjectToWorld,v.vertex).xyz;
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half3 normal_world = normalize(i.normal_world);
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz-i.pos_world);
half3 light_dir = normalize(_WorldSpaceLightPos0.xyz);
//透射光
half3 back_dir = -normalize(light_dir+normal_world*_Distort); //透射方向
half VdotBL = saturate(dot(view_dir,back_dir));
half thickness = 1.0-tex2D(_ThicknessMap,i.uv).r;
half back_light = saturate(pow(VdotBL,_BackLightContrast))*_BackLightScale;
half3 backlight_term = back_light*_LightColor0.xyz*thickness;
half3 atten = LIGHT_ATTENUATION(i);
half3 final_color = backlight_term*atten;
return fixed4(final_color,1.0);
}
ENDCG
}
}
}