继续实现反射(非高光)
之前(昨天晚上)第4篇文章留了点尾巴,还是尽量完成球面反射,镜面反射
不过这又和PBR越走越远
PBR -> uNITY-pbr -> surfuace shader -> .cginc -> 反射探针
一路走来,本来打算第3篇能提供一个能用的pbr模板,已经是最低要求,先估计要第8,第9篇还能完成
反射原理
网易大佬的回复:
在算完光照之后的colorbuffer上做一次全屏处理(图像处理):根据当前像素的世界坐标,结合对应的遮挡信息,以及水的各种波纹,得到水面的法线,然后根据法线计算高光和反射,最后得到的高光和反射再和colorbuffer的当前像素做一个alphablend(减弱地表的diffuse,加了一层高光)。
之前我还在犹豫,积水反射效果能不能在地表套一层材质,好像套个棉袄,这不是更通用吗
但大佬的回复,让我坚定在中间color实现反射处理,追加代码(主要是Unity封装的太恶心,网易自家引擎,自行管理渲染管线还是要畅快不少)
从之前的文章,对于官方Standard 使用发射探针的例子和分析,
https://blog.csdn.net/avi9111/article/details/109709498
我们知道:
Unity的管线将反射探针渲染到一个贴图:XXXXXcube0,我们就看看能不能从中取得反射数据
也推荐另一位大佬的博客,我本来就关注很久,也能百度关键字搜到这大神的博客:unity_SpecCube0
https://blog.csdn.net/puppet_master/article/details/80808486
puppet_master 大神的博客就不用多介绍了,而且自己做过一次之后,又更发现他说的都很细,每个细节都说到了,每一个段落都是关键,需要细品
==================================
这样,在使用Reflection Probe就很简单啦,上面的CubeMap采样方法的fragment shader修改一下即可,使用Reflection Probe渲染时支持HDR格式,勾选之后可以将贴图编码为HDR格式,所以在使用之前,需要先进行一步解码操作才能得到正确的结果(与宏和配置有关)。
half4 frag (v2f i) : SV_Target
{
half4 rgbm = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, i.reflectionDir);
half3 color = DecodeHDR(rgbm, unity_SpecCube0_HDR);
return half4(color, 1.0);
}
=======================
(还有灰常详细的反射探针和SSR的例子和解释)
所以我改了下代码(一个错误的代码)
half4 rgbm = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, s.normalWorld);
half3 convert_color = DecodeHDR(rgbm, unity_SpecCube0_HDR);
c.rgb = convert_color;
return OutputForward(c, s.alpha);
关于s.normalWorld的解释
vf shader解释(大神)
https://blog.csdn.net/puppet_master/article/details/80808486
standard shader解析(我)
https://blog.csdn.net/avi9111/article/details/109709498
但上面“有点反射效果”,但还是一个错的效果
基于Standard的反射完全代码
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Unity Shaders Book/WebStuff/Standardxx (Specular setup)"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo", 2D) = "white" {}
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
_GlossMapScale("Smoothness Factor", Range(0.0, 1.0)) = 1.0
[Enum(Specular Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0
_SpecColor("Specular", Color) = (0.2,0.2,0.2)
_SpecGlossMap("Specular", 2D) = "white" {}
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0
[ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
_Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02
_ParallaxMap ("Height Map", 2D) = "black" {}
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
_OcclusionMap("Occlusion", 2D) = "white" {}
_EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_DetailMask("Detail Mask", 2D) = "white" {}
_DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}
_DetailNormalMapScale("Scale", Float) = 1.0
_DetailNormalMap("Normal Map 1", 2D) = "bump" {}
[Enum(UV0,0,UV1,1)] _UVSec("UV Set for secondary textures", Float) = 0
_WetLevel("Wet",Float) = 1
// Blending state
[HideInInspector] _Mode("__mode", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
//_VertexColorMask("Color Mask")
_AccumulatedWater("AccumulatedWater",Range(0,1)) = 1.0
}
CGINCLUDE
#define UNITY_SETUP_BRDF_INPUT SpecularSetup
ENDCG
SubShader
{
Tags { "RenderType" = "Opaque" "PerformanceChecks" = "False" }
LOD 300
// ------------------------------------------------------------------
// Base forward pass (directional light, emission, lightmaps, ...)
Pass
{
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
CGPROGRAM
#pragma target 3.0
// -------------------------------------
#pragma shader_feature _NORMALMAP
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _EMISSION
#pragma shader_feature _SPECGLOSSMAP //启用spec 贴图,是必须要用,若没有贴图,估计渲染就坍塌了。。。。
#pragma shader_feature ___ _DETAIL_MULX2
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF
#pragma shader_feature _PARALLAXMAP
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
#pragma multi_compile_instancing
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma vertex vertBase
#pragma fragment fragBase
float _WetLevel;
float _AccumulatedWater;
//sampler2D _MainTex;
//只在BRDF有用,要不会过曝
void DoWetShading(inout float3 albedo, inout float gloss, float wetLevel) {
// 越潮湿,地面越暗
albedo *= lerp(1.0,0.3, wetLevel);
//越潮湿,gloss越大,镜面反射更明亮,高光凝聚度更高。
gloss = min(gloss * lerp(1.0,2.5,wetLevel),1.0);
}
//fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _Color.rgb;
//DoWetShading(albedo,_Glossiness, _WetLevel)
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#include "UnityStandardCore.cginc"
half4 fragForwardBase_WetStuff(VertexOutputForwardBase i)
{
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
FRAGMENT_SETUP(s)
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
UnityLight mainLight = MainLight();
UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld);
half occlusion = Occlusion(i.tex.xy);
DoWetShading(s.diffColor, s.smoothness, _WetLevel);
//加上vertexColor(Mask)
//float4 VertexColor = tex2D()
//AccumulatedWater = i.VertexColor.a;
//Gloss = lerp(Gloss, 1.0, AccumulatedWater);
//前面_WetLevel已经会将.smoothness增幅
//如果前面的值太大,这里的lerp渐变空间少,会没什么效果
//(原来理解错了,不应该2个方法作用同一个参数,前面的参数应该是Gloss(Smoothness),和Specular区别)
s.smoothness = lerp(s.smoothness, 1, _AccumulatedWater);
Water F0 specular is 0.02 (based on IOR of 1.33)
//Specular = lerp(Specular, 0.02, AccumulatedWater);
//N = lerp(N, float3(0, 0, 1), AccumulatedWater);
UnityGI gi = FragmentGI(s, occlusion, i.ambientOrLightmapUV, atten, mainLight);
half4 c = UNITY_BRDF_PBS(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect);
c.rgb += Emission(i.tex.xy);
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
UNITY_APPLY_FOG(_unity_fogCoord, c.rgb);
//c = s.smoothness;
half4 rgbm = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, s.normalWorld);
half3 convert_color = DecodeHDR(rgbm, unity_SpecCube0_HDR);
c.rgb = convert_color;
return OutputForward(c, s.alpha);
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//#include "UnityStandardCoreForward.cginc"
VertexOutputForwardBase vertBase(VertexInput v) { return vertForwardBase(v); }
//VertexOutputForwardAdd vertAdd(VertexInput v) { return vertForwardAdd(v); }
half4 fragBase(VertexOutputForwardBase i) : SV_Target{ return fragForwardBase_WetStuff(i); }
//half4 fragAdd(VertexOutputForwardAdd i) : SV_Target{ return fragForwardAddInternal(i); }
ENDCG
}
// ------------------------------------------------------------------
// Additive forward pass (one light per pass)
Pass
{
Name "FORWARD_DELTA"
Tags { "LightMode" = "ForwardAdd" }
Blend [_SrcBlend] One
Fog { Color (0,0,0,0) } // in additive pass fog should be black
ZWrite Off
ZTest LEqual
CGPROGRAM
#pragma target 3.0
// -------------------------------------
#pragma shader_feature _NORMALMAP
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature ___ _DETAIL_MULX2
#pragma shader_feature _PARALLAXMAP
#pragma multi_compile_fwdadd_fullshadows
#pragma multi_compile_fog
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma vertex vertAdd
#pragma fragment fragAdd
#include "UnityStandardCoreForward.cginc"
ENDCG
}
// ------------------------------------------------------------------
// Shadow rendering pass
Pass {
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
ZWrite On ZTest LEqual
CGPROGRAM
#pragma target 3.0
// -------------------------------------
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _PARALLAXMAP
#pragma multi_compile_shadowcaster
#pragma multi_compile_instancing
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma vertex vertShadowCaster
#pragma fragment fragShadowCaster
#include "UnityStandardShadow.cginc"
ENDCG
}
// ------------------------------------------------------------------
// Deferred pass
Pass
{
Name "DEFERRED"
Tags { "LightMode" = "Deferred" }
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers nomrt
// -------------------------------------
#pragma shader_feature _NORMALMAP
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _EMISSION
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature ___ _DETAIL_MULX2
#pragma shader_feature _PARALLAXMAP
#pragma multi_compile_prepassfinal
#pragma multi_compile_instancing
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//#pragma multi_compile _ LOD_FADE_CROSSFADE
#pragma vertex vertDeferred
#pragma fragment fragDeferred
#include "UnityStandardCore.cginc"
ENDCG
}
// ------------------------------------------------------------------
// Extracts information for lightmapping, GI (emission, albedo, ...)
// This pass it not used during regular rendering.
Pass
{
Name "META"
Tags { "LightMode"="Meta" }
Cull Off
CGPROGRAM
#pragma vertex vert_meta
#pragma fragment frag_meta
#pragma shader_feature _EMISSION
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature ___ _DETAIL_MULX2
#pragma shader_feature EDITOR_VISUALIZATION
#include "UnityStandardMeta.cginc"
ENDCG
}
}
SubShader
{
Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
LOD 150
// ------------------------------------------------------------------
// Base forward pass (directional light, emission, lightmaps, ...)
Pass
{
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
CGPROGRAM
#pragma target 2.0
#pragma shader_feature _NORMALMAP
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _EMISSION
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF
#pragma shader_feature ___ _DETAIL_MULX2
// SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
#pragma skip_variants SHADOWS_SOFT DYNAMICLIGHTMAP_ON DIRLIGHTMAP_COMBINED
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
#pragma vertex vertBase
#pragma fragment fragBase
#include "UnityStandardCoreForward.cginc"
ENDCG
}
// ------------------------------------------------------------------
// Additive forward pass (one light per pass)
Pass
{
Name "FORWARD_DELTA"
Tags { "LightMode" = "ForwardAdd" }
Blend [_SrcBlend] One
Fog { Color (0,0,0,0) } // in additive pass fog should be black
ZWrite Off
ZTest LEqual
CGPROGRAM
#pragma target 2.0
#pragma shader_feature _NORMALMAP
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature ___ _DETAIL_MULX2
// SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
#pragma skip_variants SHADOWS_SOFT
#pragma multi_compile_fwdadd_fullshadows
#pragma multi_compile_fog
#pragma vertex vertAdd
#pragma fragment fragAdd
#include "UnityStandardCoreForward.cginc"
ENDCG
}
// ------------------------------------------------------------------
// Shadow rendering pass
Pass {
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
ZWrite On ZTest LEqual
CGPROGRAM
#pragma target 2.0
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma skip_variants SHADOWS_SOFT
#pragma multi_compile_shadowcaster
#pragma vertex vertShadowCaster
#pragma fragment fragShadowCaster
#include "UnityStandardShadow.cginc"
ENDCG
}
// ------------------------------------------------------------------
// Extracts information for lightmapping, GI (emission, albedo, ...)
// This pass it not used during regular rendering.
Pass
{
Name "META"
Tags { "LightMode"="Meta" }
Cull Off
CGPROGRAM
#pragma vertex vert_meta
#pragma fragment frag_meta
#pragma shader_feature _EMISSION
#pragma shader_feature _SPECGLOSSMAP
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature ___ _DETAIL_MULX2
#pragma shader_feature EDITOR_VISUALIZATION
#include "UnityStandardMeta.cginc"
ENDCG
}
}
FallBack "VertexLit"
//CustomEditor "StandardShaderGUI"
}