Last active
June 11, 2020 13:06
-
-
Save unitycoder/ba657285ac05046cc3539841fd863e24 to your computer and use it in GitHub Desktop.
Unity Standard Shader - Accessing BoxProfected Reflection Probe Cubemap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Moved most of the functions from includes into the shader | |
// Removed lots of unnecessary stuff (i just want the reflection probe cube) | |
// Still plenty to cleanup | |
// NEW: http://forum.unity3d.com/threads/reflection-probes-in-a-custom-surface-shader.378549/#post-2685603 | |
// References (none of the scripts worked..) | |
// http://forum.unity3d.com/threads/reflection-probes-in-a-custom-surface-shader.378549/ | |
// http://forum.unity3d.com/threads/reflection-probes-in-custom-shader.322562/ | |
// http://forum.unity3d.com/threads/accessing-reflection-probe-cubemaps.307077/ | |
Shader "StandardReflectionProbe" | |
{ | |
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 | |
[Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 | |
_MetallicGlossMap("Metallic", 2D) = "white" {} | |
_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", 2D) = "bump" {} | |
[Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0 | |
// 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 | |
} | |
CGINCLUDE | |
#define UNITY_SETUP_BRDF_INPUT MetallicSetup | |
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 | |
// TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT | |
#pragma exclude_renderers gles | |
#define UNITY_STANDARD_SIMPLE 1 | |
// ------------------------------------- | |
//#pragma shader_feature _NORMALMAP | |
//#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON | |
//#pragma shader_feature _EMISSION | |
//#pragma shader_feature _METALLICGLOSSMAP | |
//#pragma shader_feature ___ _DETAIL_MULX2 | |
//#pragma shader_feature _PARALLAXMAP | |
#pragma multi_compile_fwdbase | |
#pragma multi_compile_fog | |
#pragma vertex vertBase | |
#pragma fragment fragBase | |
//#include "UnityStandardCoreForward.cginc" | |
#ifndef UNITY_STANDARD_CORE_FORWARD_SIMPLE_INCLUDED | |
#define UNITY_STANDARD_CORE_FORWARD_SIMPLE_INCLUDED | |
#include "UnityStandardCore.cginc" | |
// Does not support: _PARALLAXMAP, DIRLIGHTMAP_COMBINED, DIRLIGHTMAP_SEPARATE | |
#define GLOSSMAP (defined(_SPECGLOSSMAP) || defined(_METALLICGLOSSMAP)) | |
#ifndef SPECULAR_HIGHLIGHTS | |
#define SPECULAR_HIGHLIGHTS 1 | |
#endif | |
struct VertexOutputBaseSimple | |
{ | |
float4 pos : SV_POSITION; | |
float4 tex : TEXCOORD0; | |
half4 eyeVec : TEXCOORD1; // w: grazingTerm | |
half4 ambientOrLightmapUV : TEXCOORD2; // SH or Lightmap UV | |
SHADOW_COORDS(3) | |
UNITY_FOG_COORDS_PACKED(4, half4) // x: fogCoord, yzw: reflectVec | |
half4 normalWorld : TEXCOORD5; // w: fresnelTerm | |
#ifdef _NORMALMAP | |
half3 tangentSpaceLightDir : TEXCOORD6; | |
#if SPECULAR_HIGHLIGHTS | |
half3 tangentSpaceEyeVec : TEXCOORD7; | |
#endif | |
#endif | |
#if UNITY_SPECCUBE_BOX_PROJECTION | |
float3 posWorld : TEXCOORD8; | |
#endif | |
}; | |
// UNIFORM_REFLECTIVITY(): workaround to get (uniform) reflecivity based on UNITY_SETUP_BRDF_INPUT | |
half MetallicSetup_Reflectivity() | |
{ | |
return 1.0h - OneMinusReflectivityFromMetallic(_Metallic); | |
} | |
half SpecularSetup_Reflectivity() | |
{ | |
return SpecularStrength(_SpecColor.rgb); | |
} | |
#define JOIN2(a, b) a##b | |
#define JOIN(a, b) JOIN2(a,b) | |
#define UNIFORM_REFLECTIVITY JOIN(UNITY_SETUP_BRDF_INPUT, _Reflectivity) | |
#ifdef _NORMALMAP | |
half3 TransformToTangentSpace(half3 tangent, half3 binormal, half3 normal, half3 v) | |
{ | |
// Mali400 shader compiler prefers explicit dot product over using a half3x3 matrix | |
return half3(dot(tangent, v), dot(binormal, v), dot(normal, v)); | |
} | |
void TangentSpaceLightingInput(half3 normalWorld, half4 vTangent, half3 lightDirWorld, half3 eyeVecWorld, out half3 tangentSpaceLightDir, out half3 tangentSpaceEyeVec) | |
{ | |
half3 tangentWorld = UnityObjectToWorldDir(vTangent.xyz); | |
half sign = half(vTangent.w) * half(unity_WorldTransformParams.w); | |
half3 binormalWorld = cross(normalWorld, tangentWorld) * sign; | |
tangentSpaceLightDir = TransformToTangentSpace(tangentWorld, binormalWorld, normalWorld, lightDirWorld); | |
#if SPECULAR_HIGHLIGHTS | |
tangentSpaceEyeVec = normalize(TransformToTangentSpace(tangentWorld, binormalWorld, normalWorld, eyeVecWorld)); | |
#else | |
tangentSpaceEyeVec = 0; | |
#endif | |
} | |
#endif // _NORMALMAP | |
VertexOutputBaseSimple vertForwardBaseSimple (VertexInput v) | |
{ | |
VertexOutputBaseSimple o; | |
UNITY_INITIALIZE_OUTPUT(VertexOutputBaseSimple, o); | |
float4 posWorld = mul(_Object2World, v.vertex); | |
#if UNITY_SPECCUBE_BOX_PROJECTION | |
o.posWorld = posWorld.xyz; | |
#endif | |
o.pos = mul(UNITY_MATRIX_MVP, v.vertex); | |
o.tex = TexCoords(v); | |
half3 eyeVec = normalize(posWorld.xyz - _WorldSpaceCameraPos); | |
half3 normalWorld = UnityObjectToWorldNormal(v.normal); | |
o.normalWorld.xyz = normalWorld; | |
o.eyeVec.xyz = eyeVec; | |
#ifdef _NORMALMAP | |
half3 tangentSpaceEyeVec; | |
TangentSpaceLightingInput(normalWorld, v.tangent, _WorldSpaceLightPos0.xyz, eyeVec, o.tangentSpaceLightDir, tangentSpaceEyeVec); | |
#if SPECULAR_HIGHLIGHTS | |
o.tangentSpaceEyeVec = tangentSpaceEyeVec; | |
#endif | |
#endif | |
//We need this for shadow receiving | |
TRANSFER_SHADOW(o); | |
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld); | |
o.fogCoord.yzw = reflect(eyeVec, normalWorld); | |
o.normalWorld.w = Pow4(1 - DotClamped (normalWorld, -eyeVec)); // fresnel term | |
#if !GLOSSMAP | |
o.eyeVec.w = saturate(_Glossiness + UNIFORM_REFLECTIVITY()); // grazing term | |
#endif | |
UNITY_TRANSFER_FOG(o, o.pos); | |
return o; | |
} | |
FragmentCommonData FragmentSetupSimple(VertexOutputBaseSimple i) | |
{ | |
FragmentCommonData s = UNITY_SETUP_BRDF_INPUT (i.tex); | |
// NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha) | |
//s.diffColor = PreMultiplyAlpha (s.diffColor, 1, s.oneMinusReflectivity, /*out*/ s.alpha); | |
s.diffColor = s.diffColor; //PreMultiplyAlpha (s.diffColor, 1, s.oneMinusReflectivity, /*out*/ s.alpha); | |
s.normalWorld = i.normalWorld.xyz; | |
s.eyeVec = i.eyeVec.xyz; | |
s.posWorld = IN_WORLDPOS(i); | |
s.reflUVW = i.fogCoord.yzw; | |
#ifdef _NORMALMAP | |
s.tangentSpaceNormal = NormalInTangentSpace(i.tex); | |
#else | |
s.tangentSpaceNormal = 0; | |
#endif | |
return s; | |
} | |
UnityLight MainLightSimple(VertexOutputBaseSimple i, FragmentCommonData s) | |
{ | |
UnityLight mainLight = MainLight(s.normalWorld); | |
#if defined(LIGHTMAP_OFF) && defined(_NORMALMAP) | |
mainLight.ndotl = LambertTerm(s.tangentSpaceNormal, i.tangentSpaceLightDir); | |
#endif | |
return mainLight; | |
} | |
half PerVertexGrazingTerm(VertexOutputBaseSimple i, FragmentCommonData s) | |
{ | |
#if GLOSSMAP | |
return saturate(s.oneMinusRoughness + (1-s.oneMinusReflectivity)); | |
#else | |
return i.eyeVec.w; | |
#endif | |
} | |
half PerVertexFresnelTerm(VertexOutputBaseSimple i) | |
{ | |
return i.normalWorld.w; | |
} | |
#if !SPECULAR_HIGHLIGHTS | |
# define REFLECTVEC_FOR_SPECULAR(i, s) half3(0, 0, 0) | |
#elif defined(_NORMALMAP) | |
# define REFLECTVEC_FOR_SPECULAR(i, s) reflect(i.tangentSpaceEyeVec, s.tangentSpaceNormal) | |
#else | |
# define REFLECTVEC_FOR_SPECULAR(i, s) s.reflUVW | |
#endif | |
half3 LightDirForSpecular(VertexOutputBaseSimple i, UnityLight mainLight) | |
{ | |
#if SPECULAR_HIGHLIGHTS && defined(_NORMALMAP) | |
return i.tangentSpaceLightDir; | |
#else | |
return mainLight.dir; | |
#endif | |
} | |
half3 BRDF3DirectSimple(half3 diffColor, half3 specColor, half oneMinusRoughness, half rl) | |
{ | |
#if SPECULAR_HIGHLIGHTS | |
return BRDF3_Direct(diffColor, specColor, Pow4(rl), oneMinusRoughness); | |
#else | |
return diffColor; | |
#endif | |
} | |
// ************ modified overrides here ***************** | |
inline UnityGI UnityGI_BaseCustom(UnityGIInput data, half occlusion, half3 normalWorld) | |
{ | |
UnityGI o_gi; | |
ResetUnityGI(o_gi); | |
#if !defined(LIGHTMAP_ON) | |
o_gi.light = data.light; | |
o_gi.light.color *= data.atten; | |
#endif | |
#if UNITY_SHOULD_SAMPLE_SH | |
o_gi.indirect.diffuse = ShadeSHPerPixel (normalWorld, data.ambient); | |
#endif | |
#if defined(LIGHTMAP_ON) | |
// Baked lightmaps | |
fixed4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy); | |
half3 bakedColor = DecodeLightmap(bakedColorTex); | |
#ifdef DIRLIGHTMAP_OFF | |
o_gi.indirect.diffuse = bakedColor; | |
#ifdef SHADOWS_SCREEN | |
o_gi.indirect.diffuse = MixLightmapWithRealtimeAttenuation (o_gi.indirect.diffuse, data.atten, bakedColorTex); | |
#endif // SHADOWS_SCREEN | |
#elif DIRLIGHTMAP_COMBINED | |
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy); | |
o_gi.indirect.diffuse = DecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld); | |
#ifdef SHADOWS_SCREEN | |
o_gi.indirect.diffuse = MixLightmapWithRealtimeAttenuation (o_gi.indirect.diffuse, data.atten, bakedColorTex); | |
#endif // SHADOWS_SCREEN | |
#elif DIRLIGHTMAP_SEPARATE | |
// Left halves of both intensity and direction lightmaps store direct light; right halves - indirect. | |
// Direct | |
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy); | |
o_gi.indirect.diffuse = DecodeDirectionalSpecularLightmap (bakedColor, bakedDirTex, normalWorld, false, 0, o_gi.light); | |
// Indirect | |
half2 uvIndirect = data.lightmapUV.xy + half2(0.5, 0); | |
bakedColor = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, uvIndirect)); | |
bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_LightmapInd, unity_Lightmap, uvIndirect); | |
o_gi.indirect.diffuse += DecodeDirectionalSpecularLightmap (bakedColor, bakedDirTex, normalWorld, false, 0, o_gi.light2); | |
#endif | |
#endif | |
#ifdef DYNAMICLIGHTMAP_ON | |
// Dynamic lightmaps | |
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw); | |
half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex); | |
#ifdef DIRLIGHTMAP_OFF | |
o_gi.indirect.diffuse += realtimeColor; | |
#elif DIRLIGHTMAP_COMBINED | |
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw); | |
o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld); | |
#elif DIRLIGHTMAP_SEPARATE | |
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw); | |
half4 realtimeNormalTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicNormal, unity_DynamicLightmap, data.lightmapUV.zw); | |
o_gi.indirect.diffuse += DecodeDirectionalSpecularLightmap (realtimeColor, realtimeDirTex, normalWorld, true, realtimeNormalTex, o_gi.light3); | |
#endif | |
#endif | |
o_gi.indirect.diffuse *= occlusion; | |
return o_gi; | |
} | |
inline half3 BoxProjectedCubemapDirectionCustom (half3 worldRefl, float3 worldPos, float4 cubemapCenter, float4 boxMin, float4 boxMax) | |
{ | |
// Do we have a valid reflection probe? | |
UNITY_BRANCH | |
if (cubemapCenter.w > 0.0) | |
{ | |
half3 nrdir = normalize(worldRefl); | |
#if 1 | |
half3 rbmax = (boxMax.xyz - worldPos) / nrdir; | |
half3 rbmin = (boxMin.xyz - worldPos) / nrdir; | |
half3 rbminmax = (nrdir > 0.0f) ? rbmax : rbmin; | |
#else // Optimized version | |
half3 rbmax = (boxMax.xyz - worldPos); | |
half3 rbmin = (boxMin.xyz - worldPos); | |
half3 select = step (half3(0,0,0), nrdir); | |
half3 rbminmax = lerp (rbmax, rbmin, select); | |
rbminmax /= nrdir; | |
#endif | |
half fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); | |
worldPos -= cubemapCenter.xyz; | |
worldRefl = worldPos + nrdir * fa; | |
} | |
return worldRefl; | |
} | |
half3 Unity_GlossyEnvironmentCustom (UNITY_ARGS_TEXCUBE(tex), half4 hdr, Unity_GlossyEnvironmentData glossIn) | |
{ | |
#if UNITY_GLOSS_MATCHES_MARMOSET_TOOLBAG2 && (SHADER_TARGET >= 30) | |
// TODO: remove pow, store cubemap mips differently | |
half roughness = pow(glossIn.roughness, 3.0/4.0); | |
#else | |
half roughness = glossIn.roughness; // MM: switched to this | |
#endif | |
//roughness = sqrt(sqrt(2/(64.0+2))); // spec power to the square root of real roughness | |
#if 0 | |
/* | |
float m = roughness*roughness; // m is the real roughness parameter | |
const float fEps = 1.192092896e-07F; // smallest such that 1.0+FLT_EPSILON != 1.0 (+1e-4h is NOT good here. is visibly very wrong) | |
float n = (2.0/max(fEps, m*m))-2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf | |
n /= 4; // remap from n_dot_h formulatino to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html | |
roughness = pow( 2/(n+2), 0.25); // remap back to square root of real roughness*/ | |
#else | |
// MM: came up with a surprisingly close approximation to what the #if 0'ed out code above does. | |
roughness = roughness*(1.7 - 0.7*roughness); | |
#endif | |
/* | |
#if UNITY_OPTIMIZE_TEXCUBELOD | |
half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, glossIn.reflUVW, 4); | |
if(roughness > 0.5) | |
rgbm = lerp(rgbm, UNITY_SAMPLE_TEXCUBE_LOD(tex, glossIn.reflUVW, 8), 2*roughness-1); | |
else | |
rgbm = lerp(UNITY_SAMPLE_TEXCUBE(tex, glossIn.reflUVW), rgbm, 2*roughness); | |
#else*/ | |
half mip = roughness * UNITY_SPECCUBE_LOD_STEPS; | |
half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, glossIn.reflUVW, mip); // WOHOO, here it is | |
//#endif | |
// return DecodeHDR_NoLinearSupportInSM2 (rgbm, hdr); | |
return rgbm; | |
} | |
inline half3 UnityGI_IndirectSpecularCustom(UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn) | |
{ | |
half3 specular; | |
//#if UNITY_SPECCUBE_BOX_PROJECTION | |
// we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice), so keep original to pass into BoxProjectedCubemapDirection | |
half3 originalReflUVW = glossIn.reflUVW; | |
//#endif | |
//#if UNITY_SPECCUBE_BOX_PROJECTION | |
glossIn.reflUVW = BoxProjectedCubemapDirectionCustom (originalReflUVW, data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]); | |
//#endif | |
// half3 env0 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], glossIn); | |
half3 env0 = Unity_GlossyEnvironmentCustom (UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], glossIn); | |
/* | |
#if UNITY_SPECCUBE_BLENDING | |
const float kBlendFactor = 0.99999; | |
float blendLerp = data.boxMin[0].w; | |
UNITY_BRANCH | |
if (blendLerp < kBlendFactor) | |
{ | |
#if UNITY_SPECCUBE_BOX_PROJECTION | |
glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[1], data.boxMin[1], data.boxMax[1]); | |
#endif | |
half3 env1 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE(unity_SpecCube1), data.probeHDR[1], glossIn); | |
specular = lerp(env1, env0, blendLerp); | |
} | |
else | |
{ | |
specular = env0; | |
} | |
#else*/ | |
specular = env0; | |
//#endif | |
return specular;// * occlusion; | |
} | |
inline UnityGI UnityGlobalIlluminationCustom (UnityGIInput data, half occlusion, half3 normalWorld) | |
{ | |
return UnityGI_BaseCustom(data, occlusion, normalWorld); | |
} | |
inline UnityGI UnityGlobalIlluminationCustom (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn) | |
{ | |
UnityGI o_gi = UnityGI_BaseCustom(data, occlusion, normalWorld); | |
o_gi.indirect.specular = UnityGI_IndirectSpecularCustom(data, occlusion, normalWorld, glossIn); | |
return o_gi; | |
} | |
inline UnityGI FragmentGICustom (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections) | |
//inline float4 FragmentGICustom (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections, samplerCUBE i_tex) | |
{ | |
UnityGIInput d; | |
d.light = light; | |
d.worldPos = s.posWorld; | |
d.worldViewDir = -s.eyeVec; | |
d.atten = atten; | |
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON) | |
d.ambient = 0; | |
d.lightmapUV = i_ambientOrLightmapUV; | |
#else | |
d.ambient = i_ambientOrLightmapUV.rgb; | |
d.lightmapUV = 0; | |
#endif | |
d.boxMax[0] = unity_SpecCube0_BoxMax; | |
d.boxMin[0] = unity_SpecCube0_BoxMin; | |
d.probePosition[0] = unity_SpecCube0_ProbePosition; | |
d.probeHDR[0] = unity_SpecCube0_HDR; | |
d.boxMax[1] = unity_SpecCube1_BoxMax; | |
d.boxMin[1] = unity_SpecCube1_BoxMin; | |
d.probePosition[1] = unity_SpecCube1_ProbePosition; | |
d.probeHDR[1] = unity_SpecCube1_HDR; | |
//if(reflections) | |
{ | |
Unity_GlossyEnvironmentData g; | |
g.roughness = 1 - s.oneMinusRoughness; | |
//#if UNITY_OPTIMIZE_TEXCUBELOD || UNITY_STANDARD_SIMPLE | |
g.reflUVW = s.reflUVW; | |
//#else | |
// g.reflUVW = reflect(s.eyeVec, s.normalWorld); | |
//#endif | |
//o_gi.indirect.specular = (data, occlusion, normalWorld, glossIn); | |
//return UNITY_SAMPLE_TEXCUBE_LOD(i_tex, s.normalWorld, 1 ); | |
//return texCUBElod (i_tex, s.normalWorld, 1); | |
//return UnityGI_IndirectSpecularCustom (d, occlusion, s.normalWorld, g); | |
// skip this | |
return UnityGlobalIlluminationCustom (d, occlusion, s.normalWorld, g); | |
} | |
//else | |
{ | |
//return UnityGlobalIllumination (d, occlusion, s.normalWorld); | |
} | |
} | |
/* | |
inline UnityGI FragmentGICustom (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, samplerCUBE i_tex) | |
{ | |
return FragmentGICustom(s, occlusion, i_ambientOrLightmapUV, atten, light, true, i_tex); | |
} | |
*/ | |
half4 fragForwardBaseSimpleInternal (VertexOutputBaseSimple i) | |
{ | |
FragmentCommonData s = FragmentSetupSimple(i); | |
UnityLight mainLight = MainLightSimple(i, s); | |
//half atten = SHADOW_ATTENUATION(i); | |
half occlusion = Occlusion(i.tex.xy); | |
//half rl = dot(REFLECTVEC_FOR_SPECULAR(i, s), LightDirForSpecular(i, mainLight)); | |
// UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, 0, mainLight); | |
UnityGI gi = FragmentGICustom (s, 1, i.ambientOrLightmapUV, 0, mainLight, false); | |
//float4 cc = FragmentGICustom (s, 1, i.ambientOrLightmapUV, 0, mainLight, false, i.tex); | |
//half3 attenuatedLightColor = gi.light.color * mainLight.ndotl; | |
//half3 attenuatedLightColor = half3(1,1,1); | |
// half3 c = BRDF3_Indirect(s.diffColor, s.specColor, gi.indirect, PerVertexGrazingTerm(i, s), PerVertexFresnelTerm(i)); | |
//half3 c = BRDF3_Indirect(s.diffColor, s.specColor, gi.indirect, PerVertexGrazingTerm(i, s), PerVertexFresnelTerm(i)); | |
// NOTE: gi.indirect.diffuse = ambient color | |
half3 c = 0;//gi.indirect.diffuse * s.diffColor; | |
c += gi.indirect.specular;// * lerp (s.specColor, PerVertexGrazingTerm(i, s), PerVertexFresnelTerm(i)); | |
//c += BRDF3DirectSimple(s.diffColor, s.specColor, s.oneMinusRoughness, rl) * attenuatedLightColor; | |
//c += UNITY_BRDF_GI (s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, -s.eyeVec, occlusion, gi); | |
//c += Emission(i.tex.xy); | |
//UNITY_APPLY_FOG(i.fogCoord, c); | |
return OutputForward (half4(c, 1), 1); | |
} | |
half4 fragForwardBaseSimple (VertexOutputBaseSimple i) : SV_Target // backward compatibility (this used to be the fragment entry function) | |
{ | |
return fragForwardBaseSimpleInternal(i); | |
} | |
struct VertexOutputForwardAddSimple | |
{ | |
float4 pos : SV_POSITION; | |
float4 tex : TEXCOORD0; | |
LIGHTING_COORDS(1,2) | |
#if !defined(_NORMALMAP) && SPECULAR_HIGHLIGHTS | |
UNITY_FOG_COORDS_PACKED(3, half4) // x: fogCoord, yzw: reflectVec | |
#else | |
UNITY_FOG_COORDS_PACKED(3, half1) | |
#endif | |
half3 lightDir : TEXCOORD4; | |
#if defined(_NORMALMAP) | |
#if SPECULAR_HIGHLIGHTS | |
half3 tangentSpaceEyeVec : TEXCOORD5; | |
#endif | |
#else | |
half3 normalWorld : TEXCOORD5; | |
#endif | |
}; | |
VertexOutputForwardAddSimple vertForwardAddSimple (VertexInput v) | |
{ | |
VertexOutputForwardAddSimple o; | |
UNITY_INITIALIZE_OUTPUT(VertexOutputForwardAddSimple, o); | |
float4 posWorld = mul(_Object2World, v.vertex); | |
o.pos = mul(UNITY_MATRIX_MVP, v.vertex); | |
o.tex = TexCoords(v); | |
//We need this for shadow receiving | |
TRANSFER_VERTEX_TO_FRAGMENT(o); | |
//half3 lightDir = _WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w; | |
#ifndef USING_DIRECTIONAL_LIGHT | |
//lightDir = NormalizePerVertexNormal(lightDir); | |
#endif | |
#if SPECULAR_HIGHLIGHTS | |
//half3 eyeVec = normalize(posWorld.xyz - _WorldSpaceCameraPos); | |
#endif | |
half3 normalWorld = UnityObjectToWorldNormal(v.normal); | |
#ifdef _NORMALMAP | |
#if SPECULAR_HIGHLIGHTS | |
//TangentSpaceLightingInput(normalWorld, v.tangent, lightDir, eyeVec, o.lightDir, o.tangentSpaceEyeVec); | |
#else | |
half3 ignore; | |
//TangentSpaceLightingInput(normalWorld, v.tangent, lightDir, 0, o.lightDir, ignore); | |
#endif | |
#else | |
//o.lightDir = lightDir; | |
//o.normalWorld = normalWorld; | |
#if SPECULAR_HIGHLIGHTS | |
//o.fogCoord.yzw = reflect(eyeVec, normalWorld); | |
#endif | |
#endif | |
//UNITY_TRANSFER_FOG(o,o.pos); | |
return o; | |
} | |
FragmentCommonData FragmentSetupSimpleAdd(VertexOutputForwardAddSimple i) | |
{ | |
/* | |
half alpha = Alpha(i.tex.xy); | |
#if defined(_ALPHATEST_ON) | |
clip (alpha - _Cutoff); | |
#endif | |
*/ | |
FragmentCommonData s = UNITY_SETUP_BRDF_INPUT (i.tex); | |
// NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha) | |
//s.diffColor = s.diffColor; //PreMultiplyAlpha (s.diffColor, alpha, s.oneMinusReflectivity, /*out*/ s.alpha); | |
/* | |
s.eyeVec = 0; | |
s.posWorld = 0; | |
#ifdef _NORMALMAP | |
s.tangentSpaceNormal = NormalInTangentSpace(i.tex); | |
s.normalWorld = 0; | |
#else | |
s.tangentSpaceNormal = 0; | |
s.normalWorld = i.normalWorld; | |
#endif | |
#if SPECULAR_HIGHLIGHTS && !defined(_NORMALMAP) | |
s.reflUVW = i.fogCoord.yzw; | |
#else | |
s.reflUVW = 0; | |
#endif*/ | |
return s; | |
} | |
half3 LightSpaceNormal(VertexOutputForwardAddSimple i, FragmentCommonData s) | |
{ | |
#ifdef _NORMALMAP | |
return s.tangentSpaceNormal; | |
#else | |
return i.normalWorld; | |
#endif | |
} | |
half4 fragForwardAddSimpleInternal (VertexOutputForwardAddSimple i) | |
{ | |
return 1;/* | |
FragmentCommonData s = FragmentSetupSimpleAdd(i); | |
half3 c = BRDF3DirectSimple(s.diffColor, s.specColor, s.oneMinusRoughness, dot(REFLECTVEC_FOR_SPECULAR(i, s), i.lightDir)); | |
#if SPECULAR_HIGHLIGHTS // else diffColor has premultiplied light color | |
c *= _LightColor0.rgb; | |
#endif | |
c *= LIGHT_ATTENUATION(i) * LambertTerm(LightSpaceNormal(i, s), i.lightDir); | |
UNITY_APPLY_FOG_COLOR(i.fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass | |
return OutputForward (half4(c, 1), s.alpha);*/ | |
} | |
half4 fragForwardAddSimple (VertexOutputForwardAddSimple i) : SV_Target // backward compatibility (this used to be the fragment entry function) | |
{ | |
return 1;//fragForwardAddSimpleInternal(i); | |
} | |
#endif // UNITY_STANDARD_CORE_FORWARD_SIMPLE_INCLUDED | |
//#include "UnityStandardCoreForwardSimple.cginc" | |
VertexOutputBaseSimple vertBase (VertexInput v) { return vertForwardBaseSimple(v); } | |
VertexOutputForwardAddSimple vertAdd (VertexInput v) { return vertForwardAddSimple(v); } | |
half4 fragBase (VertexOutputBaseSimple i) : SV_Target { return fragForwardBaseSimpleInternal(i); } | |
half4 fragAdd (VertexOutputForwardAddSimple i) : SV_Target { return fragForwardAddSimpleInternal(i); } | |
ENDCG | |
} | |
} | |
FallBack "VertexLit" | |
CustomEditor "StandardShaderGUI" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment