diff options
Diffstat (limited to '')
14 files changed, 2738 insertions, 0 deletions
diff --git a/VRCSDK3Worlds/Assets/Bakery/shader.meta b/VRCSDK3Worlds/Assets/Bakery/shader.meta new file mode 100644 index 00000000..6574fe46 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3be387fd488ac2c4b98568950b9b1833 +folderAsset: yes +timeCreated: 1622807246 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Bakery.cginc b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery.cginc new file mode 100644 index 00000000..8a6bd3ca --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery.cginc @@ -0,0 +1,1240 @@ +#ifndef BAKERY_INCLUDED +#define BAKERY_INCLUDED + +float bakeryLightmapMode; +//float2 bakeryLightmapSize; +#define BAKERYMODE_DEFAULT 0 +#define BAKERYMODE_VERTEXLM 1.0f +#define BAKERYMODE_RNM 2.0f +#define BAKERYMODE_SH 3.0f + +//#define BAKERY_SSBUMP + +//#define BAKERY_COMPRESSED_VOLUME_RGBM + +// can't fit vertexLM SH to sm3_0 interpolators +#ifndef SHADER_API_D3D11 + #undef BAKERY_VERTEXLMSH +#endif + +// can't do stuff on sm2_0 due to standard shader alrady taking up all instructions +#if SHADER_TARGET < 30 + #undef BAKERY_BICUBIC + #undef BAKERY_LMSPEC + + #undef BAKERY_RNM + #undef BAKERY_SH + #undef BAKERY_VERTEXLM +#endif + +#ifndef _NORMALMAP + #undef BAKERY_RNM + //#undef BAKERY_SH +#endif + +#ifndef UNITY_SHOULD_SAMPLE_SH + #undef BAKERY_PROBESHNONLINEAR +#endif + +#if defined(BAKERY_RNM) && defined(BAKERY_LMSPEC) +#define BAKERY_RNMSPEC +#endif + +#ifndef BAKERY_VERTEXLM + #undef BAKERY_VERTEXLMDIR + #undef BAKERY_VERTEXLMSH + #undef BAKERY_VERTEXLMMASK +#endif + +#define lumaConv float3(0.2125f, 0.7154f, 0.0721f) + +#if defined(BAKERY_SH) || defined(BAKERY_VERTEXLMSH) || defined(BAKERY_PROBESHNONLINEAR) || defined(BAKERY_VOLUME) +float shEvaluateDiffuseL1Geomerics(float L0, float3 L1, float3 n) +{ + // average energy + float R0 = L0; + + // avg direction of incoming light + float3 R1 = 0.5f * L1; + + // directional brightness + float lenR1 = length(R1); + + // linear angle between normal and direction 0-1 + //float q = 0.5f * (1.0f + dot(R1 / lenR1, n)); + //float q = dot(R1 / lenR1, n) * 0.5 + 0.5; + float q = dot(normalize(R1), n) * 0.5 + 0.5; + + // power for q + // lerps from 1 (linear) to 3 (cubic) based on directionality + float p = 1.0f + 2.0f * lenR1 / R0; + + // dynamic range constant + // should vary between 4 (highly directional) and 0 (ambient) + float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0); + + return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p)); +} +#endif + +#ifdef BAKERY_VERTEXLM + float4 unpack4NFloats(float src) { + //return fmod(float4(src / 262144.0, src / 4096.0, src / 64.0, src), 64.0)/64.0; + return frac(float4(src / (262144.0*64), src / (4096.0*64), src / (64.0*64), src)); + } + float3 unpack3NFloats(float src) { + float r = frac(src); + float g = frac(src * 256.0); + float b = frac(src * 65536.0); + return float3(r, g, b); + } +#if defined(BAKERY_VERTEXLMDIR) + void BakeryVertexLMDirection(inout float3 diffuseColor, inout float3 specularColor, float3 lightDirection, float3 vertexNormalWorld, float3 normalWorld, float3 viewDir, float smoothness) + { + float3 dominantDir = Unity_SafeNormalize(lightDirection); + half halfLambert = dot(normalWorld, dominantDir) * 0.5 + 0.5; + half flatNormalHalfLambert = dot(vertexNormalWorld, dominantDir) * 0.5 + 0.5; + + #ifdef BAKERY_LMSPEC + half3 halfDir = Unity_SafeNormalize(normalize(dominantDir) - viewDir); + half nh = saturate(dot(normalWorld, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + specularColor = spec * diffuseColor; + #endif + + diffuseColor *= halfLambert / max(1e-4h, flatNormalHalfLambert); + } +#elif defined(BAKERY_VERTEXLMSH) + void BakeryVertexLMSH(inout float3 diffuseColor, inout float3 specularColor, float3 shL1x, float3 shL1y, float3 shL1z, float3 normalWorld, float3 viewDir, float smoothness) + { + float3 L0 = diffuseColor; + float3 nL1x = shL1x; + float3 nL1y = shL1y; + float3 nL1z = shL1z; + float3 L1x = nL1x * L0 * 2; + float3 L1y = nL1y * L0 * 2; + float3 L1z = nL1z * L0 * 2; + + float3 sh; + #if BAKERY_SHNONLINEAR + //sh.r = shEvaluateDiffuseL1Geomerics(L0.r, float3(L1x.r, L1y.r, L1z.r), normalWorld); + //sh.g = shEvaluateDiffuseL1Geomerics(L0.g, float3(L1x.g, L1y.g, L1z.g), normalWorld); + //sh.b = shEvaluateDiffuseL1Geomerics(L0.b, float3(L1x.b, L1y.b, L1z.b), normalWorld); + + float lumaL0 = dot(L0, 1); + float lumaL1x = dot(L1x, 1); + float lumaL1y = dot(L1y, 1); + float lumaL1z = dot(L1z, 1); + float lumaSH = shEvaluateDiffuseL1Geomerics(lumaL0, float3(lumaL1x, lumaL1y, lumaL1z), normalWorld); + + sh = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; + float regularLumaSH = dot(sh, 1); + //sh *= regularLumaSH < 0.001 ? 1 : (lumaSH / regularLumaSH); + sh *= lerp(1, lumaSH / regularLumaSH, saturate(regularLumaSH*16)); + + #else + sh = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; + #endif + + diffuseColor = max(sh, 0.0); + + #ifdef BAKERY_LMSPEC + float3 dominantDir = float3(dot(nL1x, lumaConv), dot(nL1y, lumaConv), dot(nL1z, lumaConv)); + float focus = saturate(length(dominantDir)); + half3 halfDir = Unity_SafeNormalize(normalize(dominantDir) - viewDir); + half nh = saturate(dot(normalWorld, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness );//* sqrt(focus)); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + specularColor = max(spec * sh, 0.0); + #endif + } +#endif +#endif + +#ifdef BAKERY_BICUBIC +float BakeryBicubic_w0(float a) +{ + return (1.0f/6.0f)*(a*(a*(-a + 3.0f) - 3.0f) + 1.0f); +} + +float BakeryBicubic_w1(float a) +{ + return (1.0f/6.0f)*(a*a*(3.0f*a - 6.0f) + 4.0f); +} + +float BakeryBicubic_w2(float a) +{ + return (1.0f/6.0f)*(a*(a*(-3.0f*a + 3.0f) + 3.0f) + 1.0f); +} + +float BakeryBicubic_w3(float a) +{ + return (1.0f/6.0f)*(a*a*a); +} + +float BakeryBicubic_g0(float a) +{ + return BakeryBicubic_w0(a) + BakeryBicubic_w1(a); +} + +float BakeryBicubic_g1(float a) +{ + return BakeryBicubic_w2(a) + BakeryBicubic_w3(a); +} + +float BakeryBicubic_h0(float a) +{ + return -1.0f + BakeryBicubic_w1(a) / (BakeryBicubic_w0(a) + BakeryBicubic_w1(a)) + 0.5f; +} + +float BakeryBicubic_h1(float a) +{ + return 1.0f + BakeryBicubic_w3(a) / (BakeryBicubic_w2(a) + BakeryBicubic_w3(a)) + 0.5f; +} +#endif + +struct BakeryVertexInput +{ + float4 vertex : POSITION; +#ifdef BAKERY_VERTEXLM + fixed4 color : COLOR; + #ifdef BAKERY_VERTEXLMSH + float2 uv3 : TEXCOORD3; + #endif +#endif + half3 normal : NORMAL; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; +#if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META) + float2 uv2 : TEXCOORD2; +#endif +#if defined(_TANGENT_TO_WORLD) || defined(BAKERY_RNMSPEC) + half4 tangent : TANGENT; +#endif + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +float4 BakeryTexCoords(BakeryVertexInput v) +{ + float4 texcoord; + texcoord.xy = TRANSFORM_TEX(v.uv0, _MainTex); // Always source from uv0 + texcoord.zw = TRANSFORM_TEX(((_UVSec == 0) ? v.uv0 : v.uv1), _DetailAlbedoMap); + return texcoord; +} + +inline half4 BakeryVertexGIForward(BakeryVertexInput v, float3 posWorld, half3 normalWorld) +{ + half4 ambientOrLightmapUV = 0; + // Static lightmaps +#ifndef LIGHTMAP_OFF + ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; + ambientOrLightmapUV.zw = 0; + // Sample light probe for Dynamic objects only (no static or dynamic lightmaps) +#elif UNITY_SHOULD_SAMPLE_SH +#ifdef VERTEXLIGHT_ON + // Approximated illumination from non-important point lights + ambientOrLightmapUV.rgb = Shade4PointLights( + unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, + unity_4LightAtten0, posWorld, normalWorld); +#endif + + ambientOrLightmapUV.rgb = ShadeSHPerVertex(normalWorld, ambientOrLightmapUV.rgb); +#endif + +#ifdef DYNAMICLIGHTMAP_ON + ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; +#endif + +#ifdef BAKERY_VERTEXLM + if (bakeryLightmapMode == BAKERYMODE_VERTEXLM) + { + #ifdef BAKERY_VERTEXLMMASK + ambientOrLightmapUV = unpack4NFloats(v.uv1.x); + #endif + } +#endif + + return ambientOrLightmapUV; +} + +//Forward Pass +struct BakeryVertexOutputForwardBase +{ + float4 pos : SV_POSITION; + float4 tex : TEXCOORD0; + half3 eyeVec : TEXCOORD1; + +#if UNITY_VERSION >= 201740 + float4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] +#else + half4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] +#endif + +#if defined(BAKERY_RNMSPEC) + half3 viewDirForParallax : TEXCOORD13; +#endif + + half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV + UNITY_SHADOW_COORDS(6) + UNITY_FOG_COORDS(7) + +#ifdef BAKERY_VERTEXLM + float4 color : COLOR_centroid; + #if defined(BAKERY_VERTEXLMDIR) + float3 lightDirection : TEXCOORD10_centroid; // is this even legal + #elif defined(BAKERY_VERTEXLMSH) + float3 shL1x : TEXCOORD10_centroid; + float3 shL1y : TEXCOORD11_centroid; + float3 shL1z : TEXCOORD12_centroid; + #endif +#endif + + // next ones would not fit into SM2.0 limits, but they are always for SM3.0+ +#if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME || (UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT) + float3 posWorld : TEXCOORD8; +#endif + +#if UNITY_OPTIMIZE_TEXCUBELOD + #if UNITY_SPECCUBE_BOX_PROJECTION + half3 reflUVW : TEXCOORD9; + #else + half3 reflUVW : TEXCOORD8; + #endif +#endif + + UNITY_VERTEX_INPUT_INSTANCE_ID + UNITY_VERTEX_OUTPUT_STEREO +}; + +BakeryVertexOutputForwardBase bakeryVertForwardBase(BakeryVertexInput v) +{ + UNITY_SETUP_INSTANCE_ID(v); + BakeryVertexOutputForwardBase o; + UNITY_INITIALIZE_OUTPUT(BakeryVertexOutputForwardBase, o); + UNITY_TRANSFER_INSTANCE_ID(v, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + float4 posWorld = mul(unity_ObjectToWorld, v.vertex); + #if UNITY_REQUIRE_FRAG_WORLDPOS + #if UNITY_PACK_WORLDPOS_WITH_TANGENT + o.tangentToWorldAndPackedData[0].w = posWorld.x; + o.tangentToWorldAndPackedData[1].w = posWorld.y; + o.tangentToWorldAndPackedData[2].w = posWorld.z; + #else + o.posWorld = posWorld.xyz; + #endif + #endif + o.pos = UnityObjectToClipPos(v.vertex); + + float3 normalWorld = UnityObjectToWorldNormal(v.normal); + o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); + + o.tex = BakeryTexCoords(v); +#ifdef _TANGENT_TO_WORLD + float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); + + float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); + o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0]; + o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1]; + o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2]; +#else + o.tangentToWorldAndPackedData[0].xyz = 0; + o.tangentToWorldAndPackedData[1].xyz = 0; + o.tangentToWorldAndPackedData[2].xyz = normalWorld; +#endif + //We need this for shadow receving + UNITY_TRANSFER_SHADOW(o, v.uv1); + + o.ambientOrLightmapUV = BakeryVertexGIForward(v, posWorld, normalWorld); + +#if defined(_PARALLAXMAP) || defined(BAKERY_RNMSPEC) + TANGENT_SPACE_ROTATION; +#endif + +#if defined(_PARALLAXMAP) + half3 viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex)); + o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x; + o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y; + o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z; +#endif + +#if defined(BAKERY_RNMSPEC) + o.viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex)); +#endif + +#if UNITY_OPTIMIZE_TEXCUBELOD + o.reflUVW = reflect(o.eyeVec, normalWorld); +#endif + +#ifdef BAKERY_VERTEXLM + // Unpack from RGBM + o.color = v.color; + o.color.rgb *= o.color.a * 8.0f; + o.color.rgb *= o.color.rgb; + + #if defined(BAKERY_VERTEXLMDIR) + o.lightDirection = unpack3NFloats(v.uv1.y) * 2 - 1; + #elif defined(BAKERY_VERTEXLMSH) + o.shL1x = unpack3NFloats(v.uv1.y) * 2 - 1; + o.shL1y = unpack3NFloats(v.uv3.x) * 2 - 1; + o.shL1z = unpack3NFloats(v.uv3.y) * 2 - 1; + #endif +#endif + + UNITY_TRANSFER_FOG(o, o.pos); + return o; +} + +/* +inline UnityGI BakeryFragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections) +{ + 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.probeHDR[0] = unity_SpecCube0_HDR; + d.probeHDR[1] = unity_SpecCube1_HDR; + #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) + d.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending + #endif + #ifdef UNITY_SPECCUBE_BOX_PROJECTION + d.boxMax[0] = unity_SpecCube0_BoxMax; + d.probePosition[0] = unity_SpecCube0_ProbePosition; + d.boxMax[1] = unity_SpecCube1_BoxMax; + d.boxMin[1] = unity_SpecCube1_BoxMin; + d.probePosition[1] = unity_SpecCube1_ProbePosition; + #endif + + if(reflections) + { + Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.smoothness, -s.eyeVec, s.normalWorld, s.specColor); + // Replace the reflUVW if it has been compute in Vertex shader. Note: the compiler will optimize the calcul in UnityGlossyEnvironmentSetup itself + #if UNITY_STANDARD_SIMPLE + g.reflUVW = s.reflUVW; + #endif + + return UnityGlobalIllumination (d, occlusion, s.normalWorld, g); + } + else + { + return UnityGlobalIllumination (d, occlusion, s.normalWorld); + } +} +*/ + +#if defined(BAKERY_RNM) || defined(BAKERY_SH) +sampler2D _RNM0, _RNM1, _RNM2; +float4 _RNM0_TexelSize; +#endif + +#ifdef BAKERY_VOLUME +Texture3D _Volume0, _Volume1, _Volume2, _VolumeMask; +SamplerState sampler_Volume0; +float3 _VolumeMin, _VolumeInvSize; +float3 _GlobalVolumeMin, _GlobalVolumeInvSize; + #ifdef BAKERY_COMPRESSED_VOLUME + Texture3D _Volume3; + #endif + #ifdef BAKERY_VOLROTATION + float4x4 _GlobalVolumeMatrix, _VolumeMatrix; + #endif +#endif + +#ifdef BAKERY_BICUBIC + // Bicubic + float4 BakeryTex2D(sampler2D tex, float2 uv, float4 texelSize) + { + float x = uv.x * texelSize.z; + float y = uv.y * texelSize.z; + + x -= 0.5f; + y -= 0.5f; + + float px = floor(x); + float py = floor(y); + + float fx = x - px; + float fy = y - py; + + float g0x = BakeryBicubic_g0(fx); + float g1x = BakeryBicubic_g1(fx); + float h0x = BakeryBicubic_h0(fx); + float h1x = BakeryBicubic_h1(fx); + float h0y = BakeryBicubic_h0(fy); + float h1y = BakeryBicubic_h1(fy); + + return BakeryBicubic_g0(fy) * ( g0x * tex2D(tex, (float2(px + h0x, py + h0y) * texelSize.x)) + + g1x * tex2D(tex, (float2(px + h1x, py + h0y) * texelSize.x))) + + + BakeryBicubic_g1(fy) * ( g0x * tex2D(tex, (float2(px + h0x, py + h1y) * texelSize.x)) + + g1x * tex2D(tex, (float2(px + h1x, py + h1y) * texelSize.x))); + } + float4 BakeryTex2D(Texture2D tex, SamplerState s, float2 uv, float4 texelSize) + { + float x = uv.x * texelSize.z; + float y = uv.y * texelSize.z; + + x -= 0.5f; + y -= 0.5f; + + float px = floor(x); + float py = floor(y); + + float fx = x - px; + float fy = y - py; + + float g0x = BakeryBicubic_g0(fx); + float g1x = BakeryBicubic_g1(fx); + float h0x = BakeryBicubic_h0(fx); + float h1x = BakeryBicubic_h1(fx); + float h0y = BakeryBicubic_h0(fy); + float h1y = BakeryBicubic_h1(fy); + + return BakeryBicubic_g0(fy) * ( g0x * tex.Sample(s, (float2(px + h0x, py + h0y) * texelSize.x)) + + g1x * tex.Sample(s, (float2(px + h1x, py + h0y) * texelSize.x))) + + + BakeryBicubic_g1(fy) * ( g0x * tex.Sample(s, (float2(px + h0x, py + h1y) * texelSize.x)) + + g1x * tex.Sample(s, (float2(px + h1x, py + h1y) * texelSize.x))); + } +#else + // Bilinear + float4 BakeryTex2D(sampler2D tex, float2 uv, float4 texelSize) + { + return tex2D(tex, uv); + } + float4 BakeryTex2D(Texture2D tex, SamplerState s, float2 uv, float4 texelSize) + { + return tex.Sample(s, uv); + } +#endif + +#ifdef DIRLIGHTMAP_COMBINED +#ifdef BAKERY_LMSPEC +float BakeryDirectionalLightmapSpecular(float2 lmUV, float3 normalWorld, float3 viewDir, float smoothness) +{ + float3 dominantDir = UNITY_SAMPLE_TEX2D_SAMPLER(unity_LightmapInd, unity_Lightmap, lmUV).xyz * 2 - 1; + half3 halfDir = Unity_SafeNormalize(normalize(dominantDir) - viewDir); + half nh = saturate(dot(normalWorld, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + return spec; +} +#endif +#endif + +#ifdef BAKERY_RNM +void BakeryRNM(inout float3 diffuseColor, inout float3 specularColor, float2 lmUV, float3 normalMap, float smoothness, float3 viewDirT) +{ + const float3 rnmBasis0 = float3(0.816496580927726f, 0, 0.5773502691896258f); + const float3 rnmBasis1 = float3(-0.4082482904638631f, 0.7071067811865475f, 0.5773502691896258f); + const float3 rnmBasis2 = float3(-0.4082482904638631f, -0.7071067811865475f, 0.5773502691896258f); + + float3 rnm0 = DecodeLightmap(BakeryTex2D(_RNM0, lmUV, _RNM0_TexelSize)); + float3 rnm1 = DecodeLightmap(BakeryTex2D(_RNM1, lmUV, _RNM0_TexelSize)); + float3 rnm2 = DecodeLightmap(BakeryTex2D(_RNM2, lmUV, _RNM0_TexelSize)); + + #ifdef BAKERY_SSBUMP + diffuseColor = normalMap.x * rnm0 + + normalMap.z * rnm1 + + normalMap.y * rnm2; + diffuseColor *= 2; + #else + diffuseColor = saturate(dot(rnmBasis0, normalMap)) * rnm0 + + saturate(dot(rnmBasis1, normalMap)) * rnm1 + + saturate(dot(rnmBasis2, normalMap)) * rnm2; + #endif + + #ifdef BAKERY_LMSPEC + float3 dominantDirT = rnmBasis0 * dot(rnm0, lumaConv) + + rnmBasis1 * dot(rnm1, lumaConv) + + rnmBasis2 * dot(rnm2, lumaConv); + + float3 dominantDirTN = NormalizePerPixelNormal(dominantDirT); + float3 specColor = saturate(dot(rnmBasis0, dominantDirTN)) * rnm0 + + saturate(dot(rnmBasis1, dominantDirTN)) * rnm1 + + saturate(dot(rnmBasis2, dominantDirTN)) * rnm2; + + half3 halfDir = Unity_SafeNormalize(dominantDirTN - viewDirT); + half nh = saturate(dot(normalMap, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + specularColor = spec * specColor; + #endif +} +#endif + +#ifdef BAKERY_SH +void BakerySH(inout float3 diffuseColor, inout float3 specularColor, float2 lmUV, float3 normalWorld, float3 viewDir, float smoothness) +{ +#ifdef SHADER_API_D3D11 + float3 L0 = DecodeLightmap(BakeryTex2D(unity_Lightmap, samplerunity_Lightmap, lmUV, _RNM0_TexelSize)); +#else + float3 L0 = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, lmUV)); +#endif + float3 nL1x = BakeryTex2D(_RNM0, lmUV, _RNM0_TexelSize) * 2 - 1; + float3 nL1y = BakeryTex2D(_RNM1, lmUV, _RNM0_TexelSize) * 2 - 1; + float3 nL1z = BakeryTex2D(_RNM2, lmUV, _RNM0_TexelSize) * 2 - 1; + float3 L1x = nL1x * L0 * 2; + float3 L1y = nL1y * L0 * 2; + float3 L1z = nL1z * L0 * 2; + + float3 sh; +#if BAKERY_SHNONLINEAR + float lumaL0 = dot(L0, 1); + float lumaL1x = dot(L1x, 1); + float lumaL1y = dot(L1y, 1); + float lumaL1z = dot(L1z, 1); + float lumaSH = shEvaluateDiffuseL1Geomerics(lumaL0, float3(lumaL1x, lumaL1y, lumaL1z), normalWorld); + + sh = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; + float regularLumaSH = dot(sh, 1); + //sh *= regularLumaSH < 0.001 ? 1 : (lumaSH / regularLumaSH); + sh *= lerp(1, lumaSH / regularLumaSH, saturate(regularLumaSH*16)); + + //sh.r = shEvaluateDiffuseL1Geomerics(L0.r, float3(L1x.r, L1y.r, L1z.r), normalWorld); + //sh.g = shEvaluateDiffuseL1Geomerics(L0.g, float3(L1x.g, L1y.g, L1z.g), normalWorld); + //sh.b = shEvaluateDiffuseL1Geomerics(L0.b, float3(L1x.b, L1y.b, L1z.b), normalWorld); + +#else + sh = L0 + normalWorld.x * L1x + normalWorld.y * L1y + normalWorld.z * L1z; +#endif + + diffuseColor = max(sh, 0.0); + + #ifdef BAKERY_LMSPEC + float3 dominantDir = float3(dot(nL1x, lumaConv), dot(nL1y, lumaConv), dot(nL1z, lumaConv)); + float focus = saturate(length(dominantDir)); + half3 halfDir = Unity_SafeNormalize(normalize(dominantDir) - viewDir); + half nh = saturate(dot(normalWorld, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness );//* sqrt(focus)); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + + sh = L0 + dominantDir.x * L1x + dominantDir.y * L1y + dominantDir.z * L1z; + + specularColor = max(spec * sh, 0.0); + #endif +} +#endif + +half4 bakeryFragForwardBase(BakeryVertexOutputForwardBase i) : SV_Target +{ + FRAGMENT_SETUP(s) +#if UNITY_OPTIMIZE_TEXCUBELOD + s.reflUVW = i.reflUVW; +#endif + + UnityLight mainLight = MainLight (); + UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld); + +#ifdef BAKERY_VOLUME + bool isGlobal = _VolumeInvSize.x > 1000000; // ~inf + float3 volViewDir = s.eyeVec; + #ifdef BAKERY_VOLROTATION + float4x4 volMatrix = (isGlobal ? _GlobalVolumeMatrix : _VolumeMatrix); + float3 volInvSize = (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize); + float3 lpUV = mul(volMatrix, float4(s.posWorld,1)).xyz * volInvSize + 0.5f; + float3 volNormal = mul((float3x3)volMatrix, s.normalWorld); + #ifdef BAKERY_LMSPEC + volViewDir = mul((float3x3)volMatrix, volViewDir); + #endif + #else + float3 lpUV = (s.posWorld - (isGlobal ? _GlobalVolumeMin : _VolumeMin)) * (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize); + float3 volNormal = s.normalWorld; + #endif +#endif + +#ifdef BAKERY_VOLUME + mainLight.color *= saturate(dot(_VolumeMask.Sample(sampler_Volume0, lpUV), unity_OcclusionMaskSelector)); +#elif BAKERY_VERTEXLMMASK + if (bakeryLightmapMode == BAKERYMODE_VERTEXLM) + { + mainLight.color *= saturate(dot(i.ambientOrLightmapUV, unity_OcclusionMaskSelector)); + } +#endif + + half occlusion = Occlusion(i.tex.xy); + UnityGI gi = FragmentGI(s, occlusion, i.ambientOrLightmapUV, atten, mainLight); + +#ifdef BAKERY_VOLUME + + #ifdef BAKERY_COMPRESSED_VOLUME + float4 tex0, tex1, tex2, tex3; + float3 L0, L1x, L1y, L1z; + tex0 = _Volume0.Sample(sampler_Volume0, lpUV); + tex1 = _Volume1.Sample(sampler_Volume0, lpUV) * 2 - 1; + tex2 = _Volume2.Sample(sampler_Volume0, lpUV) * 2 - 1; + tex3 = _Volume3.Sample(sampler_Volume0, lpUV) * 2 - 1; + #ifdef BAKERY_COMPRESSED_VOLUME_RGBM + L0 = tex0.xyz * (tex0.w * 8.0f); + L0 *= L0; + #else + L0 = tex0.xyz; + #endif + L1x = tex1.xyz * L0; + L1y = tex2.xyz * L0; + L1z = tex3.xyz * L0; + #else + float4 tex0, tex1, tex2; + float3 L0, L1x, L1y, L1z; + tex0 = _Volume0.Sample(sampler_Volume0, lpUV); + tex1 = _Volume1.Sample(sampler_Volume0, lpUV); + tex2 = _Volume2.Sample(sampler_Volume0, lpUV); + L0 = tex0.xyz; + L1x = tex1.xyz; + L1y = tex2.xyz; + L1z = float3(tex0.w, tex1.w, tex2.w); + #endif + gi.indirect.diffuse.r = shEvaluateDiffuseL1Geomerics(L0.r, float3(L1x.r, L1y.r, L1z.r), volNormal); + gi.indirect.diffuse.g = shEvaluateDiffuseL1Geomerics(L0.g, float3(L1x.g, L1y.g, L1z.g), volNormal); + gi.indirect.diffuse.b = shEvaluateDiffuseL1Geomerics(L0.b, float3(L1x.b, L1y.b, L1z.b), volNormal); + + #ifdef UNITY_COLORSPACE_GAMMA + gi.indirect.diffuse = pow(gi.indirect.diffuse, 1.0f / 2.2f); + #endif + + #ifdef BAKERY_LMSPEC + float3 nL1x = L1x / L0; + float3 nL1y = L1y / L0; + float3 nL1z = L1z / L0; + float3 dominantDir = float3(dot(nL1x, lumaConv), dot(nL1y, lumaConv), dot(nL1z, lumaConv)); + half3 halfDir = Unity_SafeNormalize(normalize(dominantDir) - volViewDir); + half nh = saturate(dot(volNormal, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(s.smoothness); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + float3 sh = L0 + dominantDir.x * L1x + dominantDir.y * L1y + dominantDir.z * L1z; + gi.indirect.specular += max(spec * sh, 0.0); + #endif + +#elif BAKERY_PROBESHNONLINEAR + float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); + gi.indirect.diffuse.r = shEvaluateDiffuseL1Geomerics(L0.r, unity_SHAr.xyz, s.normalWorld); + gi.indirect.diffuse.g = shEvaluateDiffuseL1Geomerics(L0.g, unity_SHAg.xyz, s.normalWorld); + gi.indirect.diffuse.b = shEvaluateDiffuseL1Geomerics(L0.b, unity_SHAb.xyz, s.normalWorld); +#endif + +#ifdef DIRLIGHTMAP_COMBINED +#ifdef BAKERY_LMSPEC + if (bakeryLightmapMode == BAKERYMODE_DEFAULT) + { + gi.indirect.specular += BakeryDirectionalLightmapSpecular(i.ambientOrLightmapUV.xy, s.normalWorld, s.eyeVec, s.smoothness) * gi.indirect.diffuse; + } +#endif +#endif + +#ifdef BAKERY_VERTEXLM + if (bakeryLightmapMode == BAKERYMODE_VERTEXLM) + { + gi.indirect.diffuse = i.color.rgb; + float3 prevSpec = gi.indirect.specular; + + #if defined(BAKERY_VERTEXLMDIR) + BakeryVertexLMDirection(gi.indirect.diffuse, gi.indirect.specular, i.lightDirection, i.tangentToWorldAndPackedData[2].xyz, s.normalWorld, s.eyeVec, s.smoothness); + gi.indirect.specular += prevSpec; + #elif defined (BAKERY_VERTEXLMSH) + BakeryVertexLMSH(gi.indirect.diffuse, gi.indirect.specular, i.shL1x, i.shL1y, i.shL1z, s.normalWorld, s.eyeVec, s.smoothness); + gi.indirect.specular += prevSpec; + #endif + } +#endif + +#ifdef BAKERY_RNM + if (bakeryLightmapMode == BAKERYMODE_RNM) + { + #ifdef BAKERY_SSBUMP + float3 normalMap = tex2D(_BumpMap, i.tex.xy).xyz; + #else + float3 normalMap = NormalInTangentSpace(i.tex); + #endif + + float3 eyeVecT = 0; + #ifdef BAKERY_LMSPEC + eyeVecT = -NormalizePerPixelNormal(i.viewDirForParallax); + #endif + + float3 prevSpec = gi.indirect.specular; + BakeryRNM(gi.indirect.diffuse, gi.indirect.specular, i.ambientOrLightmapUV.xy, normalMap, s.smoothness, eyeVecT); + gi.indirect.specular += prevSpec; + } +#endif + +#ifdef BAKERY_SH + #if SHADER_TARGET >= 30 + if (bakeryLightmapMode == BAKERYMODE_SH) + #endif + { + float3 prevSpec = gi.indirect.specular; + BakerySH(gi.indirect.diffuse, gi.indirect.specular, i.ambientOrLightmapUV.xy, s.normalWorld, s.eyeVec, s.smoothness); + gi.indirect.specular += prevSpec; + } +#endif + + half4 c = UNITY_BRDF_PBS(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect); + + c.rgb += UNITY_BRDF_GI(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, occlusion, gi); + c.rgb += Emission(i.tex.xy); + + UNITY_APPLY_FOG(i.fogCoord, c.rgb); + + return OutputForward(c, s.alpha); +} + + +// Additive forward pass (one light per pass) +struct BakeryVertexOutputForwardAdd +{ + float4 pos : SV_POSITION; + float4 tex : TEXCOORD0; + half3 eyeVec : TEXCOORD1; +#if UNITY_VERSION >= 201740 + float4 tangentToWorldAndLightDir[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] +#else + half4 tangentToWorldAndLightDir[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] +#endif + float3 posWorld : TEXCOORD5; + UNITY_SHADOW_COORDS(6) + UNITY_FOG_COORDS(7) + + // next ones would not fit into SM2.0 limits, but they are always for SM3.0+ +#if defined(_PARALLAXMAP) + half3 viewDirForParallax : TEXCOORD8; +#endif + +#ifdef BAKERY_VERTEXLMMASK + fixed4 shadowMask : COLOR; +#endif + + UNITY_VERTEX_OUTPUT_STEREO +}; + +BakeryVertexOutputForwardAdd bakeryVertForwardAdd(BakeryVertexInput v) +{ + UNITY_SETUP_INSTANCE_ID(v); + BakeryVertexOutputForwardAdd o; + UNITY_INITIALIZE_OUTPUT(BakeryVertexOutputForwardAdd, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + float4 posWorld = mul(unity_ObjectToWorld, v.vertex); + o.pos = UnityObjectToClipPos(v.vertex); + + o.tex = BakeryTexCoords(v); + o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); + o.posWorld = posWorld.xyz; + float3 normalWorld = UnityObjectToWorldNormal(v.normal); +#ifdef _TANGENT_TO_WORLD + float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); + + float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); + o.tangentToWorldAndLightDir[0].xyz = tangentToWorld[0]; + o.tangentToWorldAndLightDir[1].xyz = tangentToWorld[1]; + o.tangentToWorldAndLightDir[2].xyz = tangentToWorld[2]; +#else + o.tangentToWorldAndLightDir[0].xyz = 0; + o.tangentToWorldAndLightDir[1].xyz = 0; + o.tangentToWorldAndLightDir[2].xyz = normalWorld; +#endif + //We need this for shadow receving + UNITY_TRANSFER_SHADOW(o, v.uv1); + + float3 lightDir = _WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w; +#ifndef USING_DIRECTIONAL_LIGHT + lightDir = NormalizePerVertexNormal(lightDir); +#endif + o.tangentToWorldAndLightDir[0].w = lightDir.x; + o.tangentToWorldAndLightDir[1].w = lightDir.y; + o.tangentToWorldAndLightDir[2].w = lightDir.z; + +#ifdef _PARALLAXMAP + TANGENT_SPACE_ROTATION; + o.viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex)); +#endif + +#ifdef BAKERY_VERTEXLMMASK + o.shadowMask = unpack4NFloats(v.uv1.x); +#endif + + UNITY_TRANSFER_FOG(o, o.pos); + return o; +} + +half4 bakeryFragForwardAdd(BakeryVertexOutputForwardAdd i) : SV_Target +{ + FRAGMENT_SETUP_FWDADD(s) + + UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld) + UnityLight light = AdditiveLight (IN_LIGHTDIR_FWDADD(i), atten); + UnityIndirect noIndirect = ZeroIndirect (); + + half4 c = UNITY_BRDF_PBS(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, light, noIndirect); + +#ifdef BAKERY_VOLUME + bool isGlobal = _VolumeInvSize.x > 1000000; // ~inf + + #ifdef BAKERY_VOLROTATION + float4x4 volMatrix = (isGlobal ? _GlobalVolumeMatrix : _VolumeMatrix); + float3 volInvSize = (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize); + float3 lpUV = mul(volMatrix, float4(s.posWorld,1)).xyz * volInvSize + 0.5f; + #else + float3 lpUV = (s.posWorld - (isGlobal ? _GlobalVolumeMin : _VolumeMin)) * (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize); + #endif + + c *= saturate(dot(_VolumeMask.Sample(sampler_Volume0, lpUV), unity_OcclusionMaskSelector)); + +#elif BAKERY_VERTEXLMMASK + if (bakeryLightmapMode == BAKERYMODE_VERTEXLM) + { + c *= saturate(dot(i.shadowMask, unity_OcclusionMaskSelector)); + } +#endif + + UNITY_APPLY_FOG_COLOR(i.fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass + + return OutputForward(c, s.alpha); +} + + +//Deferred Pass +struct BakeryVertexOutputDeferred +{ + float4 pos : SV_POSITION; + float4 tex : TEXCOORD0; + half3 eyeVec : TEXCOORD1; + +#if UNITY_VERSION >= 201740 + float4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] +#else + half4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax] +#endif + +#if defined(BAKERY_RNMSPEC) + half3 viewDirForParallax : TEXCOORD9; +#endif + + half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UVs + +#ifdef BAKERY_VERTEXLM + fixed4 color : COLOR; + #if defined(BAKERY_VERTEXLMDIR) + float3 lightDirection : TEXCOORD8; + #elif defined(BAKERY_VERTEXLMSH) + float3 shL1x : TEXCOORD8_centroid; + float3 shL1y : TEXCOORD10_centroid; + float3 shL1z : TEXCOORD11_centroid; + #endif +#endif + +#if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME || (UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT) || BAKERY_VOLUME + float3 posWorld : TEXCOORD6; +#endif + +#if UNITY_OPTIMIZE_TEXCUBELOD +#if UNITY_SPECCUBE_BOX_PROJECTION + half3 reflUVW : TEXCOORD7; +#else + half3 reflUVW : TEXCOORD6; +#endif +#endif + + UNITY_VERTEX_OUTPUT_STEREO +}; + +BakeryVertexOutputDeferred bakeryVertDeferred(BakeryVertexInput v) +{ + UNITY_SETUP_INSTANCE_ID(v); + BakeryVertexOutputDeferred o; + UNITY_INITIALIZE_OUTPUT(BakeryVertexOutputDeferred, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + float4 posWorld = mul(unity_ObjectToWorld, v.vertex); +#if UNITY_SPECCUBE_BOX_PROJECTION || UNITY_LIGHT_PROBE_PROXY_VOLUME || BAKERY_VOLUME + o.posWorld = posWorld; +#endif + o.pos = UnityObjectToClipPos(v.vertex); + + o.tex = BakeryTexCoords(v); + o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos); + float3 normalWorld = UnityObjectToWorldNormal(v.normal); +#ifdef _TANGENT_TO_WORLD + float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); + + float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); + o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0]; + o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1]; + o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2]; +#else + o.tangentToWorldAndPackedData[0].xyz = 0; + o.tangentToWorldAndPackedData[1].xyz = 0; + o.tangentToWorldAndPackedData[2].xyz = normalWorld; +#endif + + o.ambientOrLightmapUV = 0; + +#ifndef LIGHTMAP_OFF + o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; +#elif UNITY_SHOULD_SAMPLE_SH + o.ambientOrLightmapUV.rgb = ShadeSHPerVertex(normalWorld, o.ambientOrLightmapUV.rgb); +#endif +#ifdef DYNAMICLIGHTMAP_ON + o.ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; +#endif + +#ifdef BAKERY_VERTEXLMMASK + if (bakeryLightmapMode == BAKERYMODE_VERTEXLM) + { + o.ambientOrLightmapUV = unpack4NFloats(v.uv1); + } +#endif + +#if defined(_PARALLAXMAP) || defined(BAKERY_RNMSPEC) + TANGENT_SPACE_ROTATION; +#endif + +#if defined(_PARALLAXMAP) + half3 viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex)); + o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x; + o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y; + o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z; +#endif + +#if defined(BAKERY_RNMSPEC) + o.viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex)); +#endif + +#ifdef BAKERY_VERTEXLM + // Unpack from RGBM + o.color = v.color; + o.color.rgb *= o.color.a * 8.0f; + o.color.rgb *= o.color.rgb; + + #if defined(BAKERY_VERTEXLMDIR) + o.lightDirection = unpack3NFloats(v.uv1.y) * 2 - 1; + #elif defined(BAKERY_VERTEXLMSH) + o.shL1x = unpack3NFloats(v.uv1.y) * 2 - 1; + o.shL1y = unpack3NFloats(v.uv3.x) * 2 - 1; + o.shL1z = unpack3NFloats(v.uv3.y) * 2 - 1; + #endif +#endif + +#if UNITY_OPTIMIZE_TEXCUBELOD + o.reflUVW = reflect(o.eyeVec, normalWorld); +#endif + + return o; +} + +void bakeryFragDeferred( + BakeryVertexOutputDeferred i, + out half4 outDiffuse : SV_Target0, // RT0: diffuse color (rgb), occlusion (a) + out half4 outSpecSmoothness : SV_Target1, // RT1: spec color (rgb), smoothness (a) + out half4 outNormal : SV_Target2, // RT2: normal (rgb), --unused, very low precision-- (a) + out half4 outEmission : SV_Target3 // RT3: emission (rgb), --unused-- (a) +#if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4) + ,out half4 outShadowMask : SV_Target4 // RT4: shadowmask (rgba) +#endif +) +{ +#if (SHADER_TARGET < 30) + outDiffuse = 1; + outSpecSmoothness = 1; + outNormal = 0; + outEmission = 0; + #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4) + outShadowMask = 1; + #endif + return; +#endif + + FRAGMENT_SETUP(s) +#if UNITY_OPTIMIZE_TEXCUBELOD + s.reflUVW = i.reflUVW; +#endif + + // no analytic lights in this pass + UnityLight dummyLight = DummyLight(); + half atten = 1; + + // only GI + half occlusion = Occlusion(i.tex.xy); +#if UNITY_ENABLE_REFLECTION_BUFFERS + bool sampleReflectionsInDeferred = false; +#else + bool sampleReflectionsInDeferred = true; +#endif + + UnityGI gi = FragmentGI(s, occlusion, i.ambientOrLightmapUV, atten, dummyLight, sampleReflectionsInDeferred); + +#ifdef BAKERY_VOLUME + bool isGlobal = _VolumeInvSize.x > 1000000; // ~inf + float3 volViewDir = s.eyeVec; + + #ifdef BAKERY_VOLROTATION + float4x4 volMatrix = (isGlobal ? _GlobalVolumeMatrix : _VolumeMatrix); + float3 volInvSize = (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize); + float3 lpUV = mul(volMatrix, float4(i.posWorld,1)).xyz * volInvSize + 0.5f; + float3 volNormal = mul((float3x3)volMatrix, s.normalWorld); + #ifdef BAKERY_LMSPEC + volViewDir = mul((float3x3)volMatrix, volViewDir); + #endif + #else + float3 lpUV = (i.posWorld - (isGlobal ? _GlobalVolumeMin : _VolumeMin)) * (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize); + float3 volNormal = s.normalWorld; + #endif + + #ifdef BAKERY_COMPRESSED_VOLUME + float4 tex0, tex1, tex2, tex3; + float3 L0, L1x, L1y, L1z; + tex0 = _Volume0.Sample(sampler_Volume0, lpUV); + tex1 = _Volume1.Sample(sampler_Volume0, lpUV) * 2 - 1; + tex2 = _Volume2.Sample(sampler_Volume0, lpUV) * 2 - 1; + tex3 = _Volume3.Sample(sampler_Volume0, lpUV) * 2 - 1; + #ifdef BAKERY_COMPRESSED_VOLUME_RGBM + L0 = tex0.xyz * (tex0.w * 8.0f); + L0 *= L0; + #else + L0 = tex0.xyz; + #endif + L1x = tex1.xyz * L0; + L1y = tex2.xyz * L0; + L1z = tex3.xyz * L0; + #else + float4 tex0, tex1, tex2; + float3 L0, L1x, L1y, L1z; + tex0 = _Volume0.Sample(sampler_Volume0, lpUV); + tex1 = _Volume1.Sample(sampler_Volume0, lpUV); + tex2 = _Volume2.Sample(sampler_Volume0, lpUV); + L0 = tex0.xyz; + L1x = tex1.xyz; + L1y = tex2.xyz; + L1z = float3(tex0.w, tex1.w, tex2.w); + #endif + + gi.indirect.diffuse.r = shEvaluateDiffuseL1Geomerics(L0.r, float3(L1x.r, L1y.r, L1z.r), volNormal); + gi.indirect.diffuse.g = shEvaluateDiffuseL1Geomerics(L0.g, float3(L1x.g, L1y.g, L1z.g), volNormal); + gi.indirect.diffuse.b = shEvaluateDiffuseL1Geomerics(L0.b, float3(L1x.b, L1y.b, L1z.b), volNormal); + #ifdef UNITY_COLORSPACE_GAMMA + gi.indirect.diffuse = pow(gi.indirect.diffuse, 1.0f / 2.2f); + #endif + + #ifdef BAKERY_LMSPEC + float3 nL1x = L1x / L0; + float3 nL1y = L1y / L0; + float3 nL1z = L1z / L0; + float3 dominantDir = float3(dot(nL1x, lumaConv), dot(nL1y, lumaConv), dot(nL1z, lumaConv)); + half3 halfDir = Unity_SafeNormalize(normalize(dominantDir) - volViewDir); + half nh = saturate(dot(volNormal, halfDir)); + half perceptualRoughness = SmoothnessToPerceptualRoughness(s.smoothness); + half roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + half spec = GGXTerm(nh, roughness); + float3 sh = L0 + dominantDir.x * L1x + dominantDir.y * L1y + dominantDir.z * L1z; + gi.indirect.specular += max(spec * sh, 0.0); + #endif + +#elif BAKERY_PROBESHNONLINEAR + float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); + gi.indirect.diffuse.r = shEvaluateDiffuseL1Geomerics(L0.r, unity_SHAr.xyz, s.normalWorld); + gi.indirect.diffuse.g = shEvaluateDiffuseL1Geomerics(L0.g, unity_SHAg.xyz, s.normalWorld); + gi.indirect.diffuse.b = shEvaluateDiffuseL1Geomerics(L0.b, unity_SHAb.xyz, s.normalWorld); +#endif + +#ifdef DIRLIGHTMAP_COMBINED +#ifdef BAKERY_LMSPEC + if (bakeryLightmapMode == BAKERYMODE_DEFAULT) + { + gi.indirect.specular += BakeryDirectionalLightmapSpecular(i.ambientOrLightmapUV.xy, s.normalWorld, s.eyeVec, s.smoothness) * gi.indirect.diffuse; + } +#endif +#endif + +#ifdef BAKERY_VERTEXLM + if (bakeryLightmapMode == BAKERYMODE_VERTEXLM) + { + gi.indirect.diffuse = i.color.rgb; + float3 prevSpec = gi.indirect.specular; + + #if defined(BAKERY_VERTEXLMDIR) + BakeryVertexLMDirection(gi.indirect.diffuse, gi.indirect.specular, i.lightDirection, i.tangentToWorldAndPackedData[2].xyz, s.normalWorld, s.eyeVec, s.smoothness); + gi.indirect.specular += prevSpec; + #elif defined (BAKERY_VERTEXLMSH) + BakeryVertexLMSH(gi.indirect.diffuse, gi.indirect.specular, i.shL1x, i.shL1y, i.shL1z, s.normalWorld, s.eyeVec, s.smoothness); + gi.indirect.specular += prevSpec; + #endif + } +#endif + +#ifdef BAKERY_RNM + if (bakeryLightmapMode == BAKERYMODE_RNM) + { + #ifdef BAKERY_SSBUMP + float3 normalMap = tex2D(_BumpMap, i.tex.xy).xyz; + #else + float3 normalMap = NormalInTangentSpace(i.tex); + #endif + + float3 eyeVecT = 0; + #ifdef BAKERY_LMSPEC + eyeVecT = -NormalizePerPixelNormal(i.viewDirForParallax); + #endif + + float3 prevSpec = gi.indirect.specular; + BakeryRNM(gi.indirect.diffuse, gi.indirect.specular, i.ambientOrLightmapUV.xy, normalMap, s.smoothness, eyeVecT); + gi.indirect.specular += prevSpec; + } +#endif + +#ifdef BAKERY_SH + #if SHADER_TARGET >= 30 + if (bakeryLightmapMode == BAKERYMODE_SH) + #endif + { + float3 prevSpec = gi.indirect.specular; + BakerySH(gi.indirect.diffuse, gi.indirect.specular, i.ambientOrLightmapUV.xy, s.normalWorld, s.eyeVec, s.smoothness); + gi.indirect.specular += prevSpec; + } +#endif + + half3 color = UNITY_BRDF_PBS(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb; + + color += UNITY_BRDF_GI(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, occlusion, gi); + +#ifdef _EMISSION + color += Emission(i.tex.xy); +#endif + +#ifndef UNITY_HDR_ON + color.rgb = exp2(-color.rgb); +#endif + + outDiffuse = half4(s.diffColor, occlusion); + outSpecSmoothness = half4(s.specColor, s.smoothness); + outNormal = half4(s.normalWorld*0.5 + 0.5, 1); + outEmission = half4(color, 1); + +// Baked direct lighting occlusion if any +#if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4) + #ifdef BAKERY_VOLUME + outShadowMask = _VolumeMask.Sample(sampler_Volume0, lpUV); + #elif BAKERY_VERTEXLMMASK + outShadowMask = i.ambientOrLightmapUV; + #else + outShadowMask = UnityGetRawBakedOcclusions(i.ambientOrLightmapUV.xy, IN_WORLDPOS(i)); + #endif +#endif +} + +#endif diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Bakery.cginc.meta b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery.cginc.meta new file mode 100644 index 00000000..2dca2546 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1f45fcc349188584095300fd024e8f8b +timeCreated: 1538411299 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandard.shader b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandard.shader new file mode 100644 index 00000000..3f4b35cf --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandard.shader @@ -0,0 +1,417 @@ +Shader "Bakery/Standard" +{ + 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 Scale", Range(0.0, 1.0)) = 1.0 + [Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0 + + [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 + _MetallicGlossMap("Metallic", 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", 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 + + _Volume0("Volume0", 3D) = "black" {} + _Volume1("Volume1", 3D) = "black" {} + _Volume2("Volume2", 3D) = "black" {} + _VolumeMask("Volume Mask", 3D) = "white" {} + _VolumeMin("Volume min", Vector) = (0,0,0) + _VolumeInvSize("Volume Inv Size", Vector) = (1000001, 1000001, 1000001) + + [HideInInspector] _BAKERY_2SIDED ("__2s", Float) = 2.0 + [Toggle(BAKERY_2SIDEDON)] _BAKERY_2SIDEDON ("Double-sided", Float) = 0 + [Toggle(BAKERY_VERTEXLM)] _BAKERY_VERTEXLM ("Enable vertex LM", Float) = 0 + [Toggle(BAKERY_VERTEXLMDIR)] _BAKERY_VERTEXLMDIR ("Enable directional vertex LM", Float) = 0 + [Toggle(BAKERY_VERTEXLMSH)] _BAKERY_VERTEXLMSH ("Enable SH vertex LM", Float) = 0 + [Toggle(BAKERY_VERTEXLMMASK)] _BAKERY_VERTEXLMMASK ("Enable shadowmask vertex LM", Float) = 0 + [Toggle(BAKERY_SH)] _BAKERY_SH ("Enable SH", Float) = 0 + [Toggle(BAKERY_SHNONLINEAR)] _BAKERY_SHNONLINEAR ("SH non-linear mode", Float) = 1 + [Toggle(BAKERY_RNM)] _BAKERY_RNM ("Enable RNM", Float) = 0 + [Toggle(BAKERY_LMSPEC)] _BAKERY_LMSPEC ("Enable Lightmap Specular", Float) = 0 + [Toggle(BAKERY_BICUBIC)] _BAKERY_BICUBIC ("Enable Bicubic Filter", Float) = 0 + [Toggle(BAKERY_PROBESHNONLINEAR)] _BAKERY_PROBESHNONLINEAR ("Use non-linear SH for light probes", Float) = 0 + [Toggle(BAKERY_VOLUME)] _BAKERY_VOLUME ("Use volumes", Float) = 0 + [Toggle(BAKERY_VOLROTATION)] _BAKERY_VOLROTATION ("Support volume rotation", Float) = 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] + Cull [_BAKERY_2SIDED] + + 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 _METALLICGLOSSMAP + #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 shader_feature UNITY_SPECCUBE_BOX_PROJECTION + + #pragma shader_feature BAKERY_VERTEXLM + #pragma shader_feature BAKERY_VERTEXLMDIR + #pragma shader_feature BAKERY_VERTEXLMSH + #pragma shader_feature BAKERY_VERTEXLMMASK + #pragma shader_feature BAKERY_SH + #pragma shader_feature BAKERY_SHNONLINEAR + #pragma shader_feature BAKERY_RNM + #pragma shader_feature BAKERY_LMSPEC + #pragma shader_feature BAKERY_BICUBIC + #pragma shader_feature BAKERY_PROBESHNONLINEAR + #pragma shader_feature BAKERY_VOLUME + #pragma shader_feature BAKERY_COMPRESSED_VOLUME + #pragma shader_feature BAKERY_VOLROTATION + + #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 bakeryVertForwardBase + #pragma fragment bakeryFragForwardBase + + #include "UnityStandardCoreForward.cginc" + #include "Bakery.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 3.0 + + // ------------------------------------- + + + #pragma shader_feature _NORMALMAP + #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON + #pragma shader_feature _METALLICGLOSSMAP + #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 bakeryVertForwardAdd + #pragma fragment bakeryFragForwardAdd + + #include "UnityStandardCoreForward.cginc" + #include "Bakery.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 _METALLICGLOSSMAP + #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" } + + Cull [_BAKERY_2SIDED] + + 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 _METALLICGLOSSMAP + #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF + #pragma shader_feature ___ _DETAIL_MULX2 + #pragma shader_feature _PARALLAXMAP + + #pragma shader_feature BAKERY_VERTEXLM + #pragma shader_feature BAKERY_VERTEXLMDIR + #pragma shader_feature BAKERY_VERTEXLMSH + #pragma shader_feature BAKERY_VERTEXLMMASK + #pragma shader_feature BAKERY_SH + #pragma shader_feature BAKERY_SHNONLINEAR + #pragma shader_feature BAKERY_RNM + #pragma shader_feature BAKERY_LMSPEC + #pragma shader_feature BAKERY_BICUBIC + #pragma shader_feature BAKERY_PROBESHNONLINEAR + #pragma shader_feature BAKERY_VOLUME + #pragma shader_feature BAKERY_COMPRESSED_VOLUME + #pragma shader_feature BAKERY_VOLROTATION + + #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 bakeryVertDeferred + #pragma fragment bakeryFragDeferred + + #include "UnityStandardCore.cginc" + #include "Bakery.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 _METALLICGLOSSMAP + #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] + Cull [_BAKERY_2SIDED] + + 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 _METALLICGLOSSMAP + #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF + #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF + + //#pragma shader_feature BAKERY_VERTEXLM + //#pragma shader_feature BAKERY_VERTEXLMDIR + //#pragma shader_feature BAKERY_VERTEXLMSH + //#pragma shader_feature BAKERY_VERTEXLMMASK + //#pragma shader_feature BAKERY_SH + //#pragma shader_feature BAKERY_SHNONLINEAR + //#pragma shader_feature BAKERY_RNM + //#pragma shader_feature BAKERY_LMSPEC + //#pragma shader_feature BAKERY_BICUBIC + + // SM2.0: NOT SUPPORTED shader_feature ___ _DETAIL_MULX2 + // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP + + #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED + + #pragma multi_compile_fwdbase + #pragma multi_compile_fog + + #pragma vertex bakeryVertForwardBase + #pragma fragment bakeryFragForwardBase + + #include "UnityStandardCoreForward.cginc" + #include "Bakery.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 _METALLICGLOSSMAP + #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 bakeryVertForwardAdd + #pragma fragment bakeryFragForwardAdd + + #include "UnityStandardCoreForward.cginc" + #include "Bakery.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 _METALLICGLOSSMAP + #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 _METALLICGLOSSMAP + #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 "BakeryShaderGUI" +} diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandard.shader.meta b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandard.shader.meta new file mode 100644 index 00000000..6e78a210 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandard.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3334d0a534d2dac45b2c1a9a7e0a6c64 +timeCreated: 1538411300 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandardSpecular.shader b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandardSpecular.shader new file mode 100644 index 00000000..fc861934 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandardSpecular.shader @@ -0,0 +1,410 @@ +Shader "Bakery/Standard Specular" +{ + 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", 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 + + _Volume0("Volume0", 3D) = "black" {} + _Volume1("Volume1", 3D) = "black" {} + _Volume2("Volume2", 3D) = "black" {} + _VolumeMask("Volume Mask", 3D) = "white" {} + _VolumeMin("Volume min", Vector) = (0,0,0) + _VolumeInvSize("Volume Inv Size", Vector) = (1000001, 1000001, 1000001) + + [HideInInspector] _BAKERY_2SIDED ("__2s", Float) = 2.0 + [Toggle(BAKERY_2SIDEDON)] _BAKERY_2SIDEDON ("Double-sided", Float) = 0 + [Toggle(BAKERY_VERTEXLM)] _BAKERY_VERTEXLM ("Enable vertex LM", Float) = 0 + [Toggle(BAKERY_VERTEXLMDIR)] _BAKERY_VERTEXLMDIR ("Enable directional vertex LM", Float) = 0 + [Toggle(BAKERY_VERTEXLMSH)] _BAKERY_VERTEXLMSH ("Enable SH vertex LM", Float) = 0 + [Toggle(BAKERY_VERTEXLMMASK)] _BAKERY_VERTEXLMMASK ("Enable shadowmask vertex LM", Float) = 0 + [Toggle(BAKERY_SH)] _BAKERY_SH ("Enable SH", Float) = 0 + [Toggle(BAKERY_SHNONLINEAR)] _BAKERY_SHNONLINEAR ("SH non-linear mode", Float) = 1 + [Toggle(BAKERY_RNM)] _BAKERY_RNM ("Enable RNM", Float) = 0 + [Toggle(BAKERY_LMSPEC)] _BAKERY_LMSPEC ("Enable Lightmap Specular", Float) = 0 + [Toggle(BAKERY_BICUBIC)] _BAKERY_BICUBIC ("Enable Bicubic Filter", Float) = 0 + [Toggle(BAKERY_PROBESHNONLINEAR)] _BAKERY_PROBESHNONLINEAR ("Use non-linear SH for light probes", Float) = 0 + [Toggle(BAKERY_VOLUME)] _BAKERY_VOLUME ("Use volumes", Float) = 0 + [Toggle(BAKERY_VOLROTATION)] _BAKERY_VOLROTATION ("Support volume rotation", Float) = 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] + Cull [_BAKERY_2SIDED] + + 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 + #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 shader_feature BAKERY_VERTEXLM + #pragma shader_feature BAKERY_VERTEXLMDIR + #pragma shader_feature BAKERY_VERTEXLMSH + #pragma shader_feature BAKERY_VERTEXLMMASK + #pragma shader_feature BAKERY_SH + #pragma shader_feature BAKERY_SHNONLINEAR + #pragma shader_feature BAKERY_RNM + #pragma shader_feature BAKERY_LMSPEC + #pragma shader_feature BAKERY_BICUBIC + #pragma shader_feature BAKERY_PROBESHNONLINEAR + #pragma shader_feature BAKERY_VOLUME + #pragma shader_feature BAKERY_COMPRESSED_VOLUME + #pragma shader_feature BAKERY_VOLROTATION + + #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 bakeryVertForwardBase + #pragma fragment bakeryFragForwardBase + + #include "UnityStandardCore.cginc" + #include "Bakery.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 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 bakeryVertForwardAdd + #pragma fragment bakeryFragForwardAdd + + #include "UnityStandardCore.cginc" + #include "Bakery.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 multi_compile_shadowcaster + + #pragma vertex vertShadowCaster + #pragma fragment fragShadowCaster + + #include "UnityStandardShadow.cginc" + + ENDCG + } + // ------------------------------------------------------------------ + // Deferred pass + Pass + { + Name "DEFERRED" + Tags { "LightMode" = "Deferred" } + + Cull [_BAKERY_2SIDED] + + 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 shader_feature BAKERY_VERTEXLM + #pragma shader_feature BAKERY_VERTEXLMDIR + #pragma shader_feature BAKERY_VERTEXLMSH + #pragma shader_feature BAKERY_VERTEXLMMASK + #pragma shader_feature BAKERY_SH + #pragma shader_feature BAKERY_SHNONLINEAR + #pragma shader_feature BAKERY_RNM + #pragma shader_feature BAKERY_LMSPEC + #pragma shader_feature BAKERY_BICUBIC + #pragma shader_feature BAKERY_PROBESHNONLINEAR + #pragma shader_feature BAKERY_VOLUME + #pragma shader_feature BAKERY_COMPRESSED_VOLUME + #pragma shader_feature BAKERY_VOLROTATION + + #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 bakeryVertDeferred + #pragma fragment bakeryFragDeferred + + #include "UnityStandardCore.cginc" + #include "Bakery.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 + + #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] + Cull [_BAKERY_2SIDED] + + 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 + + /* + #pragma shader_feature BAKERY_VERTEXLM + #pragma shader_feature BAKERY_VERTEXLMDIR + #pragma shader_feature BAKERY_VERTEXLMSH + #pragma shader_feature BAKERY_VERTEXLMMASK + #pragma shader_feature BAKERY_SH + #pragma shader_feature BAKERY_SHNONLINEAR + #pragma shader_feature BAKERY_RNM + #pragma shader_feature BAKERY_LMSPEC + #pragma shader_feature BAKERY_BICUBIC + */ + + // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP + + #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED + + #pragma multi_compile_fwdbase + #pragma multi_compile_fog + + #pragma vertex bakeryVertForwardBase + #pragma fragment bakeryFragForwardBase + + #include "UnityStandardCoreForward.cginc" + #include "Bakery.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 bakeryVertForwardAdd + #pragma fragment bakeryFragForwardAdd + + #include "UnityStandardCoreForward.cginc" + #include "Bakery.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 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 "BakeryShaderGUI" +} diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandardSpecular.shader.meta b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandardSpecular.shader.meta new file mode 100644 index 00000000..2307655a --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/BakeryStandardSpecular.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2ad53c3d60baf17489980f3b010d040e +timeCreated: 1538413381 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphHDRP.unitypackage b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphHDRP.unitypackage Binary files differnew file mode 100644 index 00000000..85858672 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphHDRP.unitypackage diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphHDRP.unitypackage.meta b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphHDRP.unitypackage.meta new file mode 100644 index 00000000..a023a5e6 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphHDRP.unitypackage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b1b95168f2f925246bf670cb2bc2bf79 +timeCreated: 1573412449 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphURP.unitypackage b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphURP.unitypackage Binary files differnew file mode 100644 index 00000000..24818435 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphURP.unitypackage diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphURP.unitypackage.meta b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphURP.unitypackage.meta new file mode 100644 index 00000000..c57a21cc --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Bakery_ShaderGraphURP.unitypackage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec3754b09ac1517429546e96e7b25708 +timeCreated: 1606124300 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Editor.meta b/VRCSDK3Worlds/Assets/Bakery/shader/Editor.meta new file mode 100644 index 00000000..8e7899c6 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1687b0c80b20fd04fa36532aa60c6a2d +folderAsset: yes +timeCreated: 1622807246 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Editor/BakeryShaderGUI.cs b/VRCSDK3Worlds/Assets/Bakery/shader/Editor/BakeryShaderGUI.cs new file mode 100644 index 00000000..b8efd093 --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Editor/BakeryShaderGUI.cs @@ -0,0 +1,598 @@ +#if UNITY_EDITOR + +// Disable 'obsolete' warnings +#pragma warning disable 0618 +#pragma warning disable 0612 + +using System; +using UnityEngine; + +namespace UnityEditor +{ + public class BakeryShaderGUI : ShaderGUI + { + private enum WorkflowMode + { + Specular, + Metallic, + Dielectric + } + + public enum BlendMode + { + Opaque, + Cutout, + Fade, // Old school alpha-blending mode, fresnel does not affect amount of transparency + Transparent // Physically plausible transparency mode, implemented as alpha pre-multiply + } + + public enum SmoothnessMapChannel + { + SpecularMetallicAlpha, + AlbedoAlpha, + } + + private static class Styles + { + public static GUIStyle optionsButton = "PaneOptions"; + public static GUIContent uvSetLabel = new GUIContent("UV Set"); + public static GUIContent[] uvSetOptions = new GUIContent[] { new GUIContent("UV channel 0"), new GUIContent("UV channel 1") }; + + public static string emptyTootip = ""; + public static GUIContent albedoText = new GUIContent("Albedo", "Albedo (RGB) and Transparency (A)"); + public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff"); + public static GUIContent specularMapText = new GUIContent("Specular", "Specular (RGB) and Smoothness (A)"); + public static GUIContent metallicMapText = new GUIContent("Metallic", "Metallic (R) and Smoothness (A)"); + public static GUIContent smoothnessText = new GUIContent("Smoothness", "Smoothness value"); + public static GUIContent smoothnessScaleText = new GUIContent("Smoothness", "Smoothness scale factor"); + public static GUIContent smoothnessMapChannelText = new GUIContent("Source", "Smoothness texture and channel"); + public static GUIContent highlightsText = new GUIContent("Specular Highlights", "Specular Highlights"); + public static GUIContent reflectionsText = new GUIContent("Reflections", "Glossy Reflections"); + public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map"); + public static GUIContent heightMapText = new GUIContent("Height Map", "Height Map (G)"); + public static GUIContent occlusionText = new GUIContent("Occlusion", "Occlusion (G)"); + public static GUIContent emissionText = new GUIContent("Emission", "Emission (RGB)"); + public static GUIContent detailMaskText = new GUIContent("Detail Mask", "Mask for Secondary Maps (A)"); + public static GUIContent detailAlbedoText = new GUIContent("Detail Albedo x2", "Albedo (RGB) multiplied by 2"); + public static GUIContent detailNormalMapText = new GUIContent("Normal Map", "Normal Map"); + + public static string whiteSpaceString = " "; + public static string primaryMapsText = "Main Maps"; + public static string secondaryMapsText = "Secondary Maps"; + public static string forwardText = "Forward Rendering Options"; + public static string renderingMode = "Rendering Mode"; + public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive."); + public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect."); + public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode)); + + public static string bakeryText = "Bakery Options"; + public static GUIContent doubleSidedLabel = new GUIContent("Double-sided", "Render both sides of triangles."); + public static GUIContent vertexLMLabel = new GUIContent("Allow Vertex Lightmaps", "Allows this material to use vertex lightmaps, if present."); + public static GUIContent vertexLMdirLabel = new GUIContent("Enable VertexLM directional", "Enables directional vertex lightmaps."); + public static GUIContent vertexLMSHLabel = new GUIContent("Enable VertexLM SH", "Enables SH vertex lightmaps."); + public static GUIContent vertexLMMaskLabel = new GUIContent("Enable VertexLM Shadowmask", "Enables per-vertex shadowmasks."); + public static GUIContent rnmLabel = new GUIContent("Allow RNM Lightmaps", "Allows this material to use RNM lightmaps, if present."); + public static GUIContent shLabel = new GUIContent("Allow SH Lightmaps", "Allows this material to use SH lightmaps, if present."); + public static GUIContent shnLabel = new GUIContent("Non-linear SH", "This option can enhance contrast (closer to ground truth), but it makes the shader a bit slower."); + public static GUIContent specLabel = new GUIContent("Enable Lightmap Specular", "Enables baked specular for all directional modes."); + public static GUIContent bicubicLabel = new GUIContent("Force Bicubic Filter", "Enables bicubic filtering for all lightmaps (color/shadowmask/direction/etc) used in the material."); + public static GUIContent pshnLabel = new GUIContent("Non-linear Light Probe SH", "Prevents negative values in light probes. This is recommended when baking probes in L1 mode. Can slow down the shader a bit."); + public static GUIContent volLabel = new GUIContent("Enable Volumes", "Enable usages of BakeryVolumes"); + public static GUIContent volLabelRot = new GUIContent("Support Volume Rotation", "Normally volumes can only be repositioned or rescaled at runtime. With this checkbox volume's rotation matrix will also be used. Volumes must have a similar checkbox enabled."); + public static GUIContent volLabel0 = new GUIContent("Volume 0"); + public static GUIContent volLabel1 = new GUIContent("Volume 1"); + public static GUIContent volLabel2 = new GUIContent("Volume 2"); + public static GUIContent volLabelMask = new GUIContent("Volume mask"); + } + + MaterialProperty blendMode = null; + MaterialProperty albedoMap = null; + MaterialProperty albedoColor = null; + MaterialProperty alphaCutoff = null; + MaterialProperty specularMap = null; + MaterialProperty specularColor = null; + MaterialProperty metallicMap = null; + MaterialProperty metallic = null; + MaterialProperty smoothness = null; + MaterialProperty smoothnessScale = null; + MaterialProperty smoothnessMapChannel = null; + MaterialProperty highlights = null; + MaterialProperty reflections = null; + MaterialProperty bumpScale = null; + MaterialProperty bumpMap = null; + MaterialProperty occlusionStrength = null; + MaterialProperty occlusionMap = null; + MaterialProperty heigtMapScale = null; + MaterialProperty heightMap = null; + MaterialProperty emissionColorForRendering = null; + MaterialProperty emissionMap = null; + MaterialProperty detailMask = null; + MaterialProperty detailAlbedoMap = null; + MaterialProperty detailNormalMapScale = null; + MaterialProperty detailNormalMap = null; + MaterialProperty uvSetSecondary = null; + MaterialProperty enableDoubleSided = null; + MaterialProperty enableDoubleSidedOn = null; + MaterialProperty enableVertexLM = null; + MaterialProperty enableVertexLMdir = null; + MaterialProperty enableVertexLMSH = null; + MaterialProperty enableVertexLMmask = null; + MaterialProperty enableSH = null; + MaterialProperty enableSHN = null; + MaterialProperty enableRNM = null; + MaterialProperty enableSpec = null; + MaterialProperty enableBicubic = null; + MaterialProperty enablePSHN = null; + MaterialProperty enableVolumes = null; + MaterialProperty enableVolumeRot = null; + MaterialProperty volume0 = null; + MaterialProperty volume1 = null; + MaterialProperty volume2 = null; + MaterialProperty volumeMask = null; + MaterialProperty volumeMin = null; + MaterialProperty volumeInvSize = null; + + BakeryVolume assignedVolume = null; + + MaterialEditor m_MaterialEditor; + WorkflowMode m_WorkflowMode = WorkflowMode.Specular; + ColorPickerHDRConfig m_ColorPickerHDRConfig = new ColorPickerHDRConfig(0f, 99f, 1 / 99f, 3f); + + bool m_FirstTimeApply = true; + + public void FindProperties(MaterialProperty[] props) + { + blendMode = FindProperty("_Mode", props); + albedoMap = FindProperty("_MainTex", props); + albedoColor = FindProperty("_Color", props); + alphaCutoff = FindProperty("_Cutoff", props); + specularMap = FindProperty("_SpecGlossMap", props, false); + specularColor = FindProperty("_SpecColor", props, false); + metallicMap = FindProperty("_MetallicGlossMap", props, false); + metallic = FindProperty("_Metallic", props, false); + if (specularMap != null && specularColor != null) + m_WorkflowMode = WorkflowMode.Specular; + else if (metallicMap != null && metallic != null) + m_WorkflowMode = WorkflowMode.Metallic; + else + m_WorkflowMode = WorkflowMode.Dielectric; + smoothness = FindProperty("_Glossiness", props); + smoothnessScale = FindProperty("_GlossMapScale", props, false); + smoothnessMapChannel = FindProperty("_SmoothnessTextureChannel", props, false); + highlights = FindProperty("_SpecularHighlights", props, false); + reflections = FindProperty("_GlossyReflections", props, false); + bumpScale = FindProperty("_BumpScale", props); + bumpMap = FindProperty("_BumpMap", props); + heigtMapScale = FindProperty("_Parallax", props); + heightMap = FindProperty("_ParallaxMap", props); + occlusionStrength = FindProperty("_OcclusionStrength", props); + occlusionMap = FindProperty("_OcclusionMap", props); + emissionColorForRendering = FindProperty("_EmissionColor", props); + emissionMap = FindProperty("_EmissionMap", props); + detailMask = FindProperty("_DetailMask", props); + detailAlbedoMap = FindProperty("_DetailAlbedoMap", props); + detailNormalMapScale = FindProperty("_DetailNormalMapScale", props); + detailNormalMap = FindProperty("_DetailNormalMap", props); + uvSetSecondary = FindProperty("_UVSec", props); + enableDoubleSided = FindProperty("_BAKERY_2SIDED", props); + enableDoubleSidedOn = FindProperty("_BAKERY_2SIDEDON", props); + enableVertexLM = FindProperty("_BAKERY_VERTEXLM", props); + enableVertexLMdir = FindProperty("_BAKERY_VERTEXLMDIR", props); + enableVertexLMSH = FindProperty("_BAKERY_VERTEXLMSH", props); + enableVertexLMmask = FindProperty("_BAKERY_VERTEXLMMASK", props); + enableSH = FindProperty("_BAKERY_SH", props); + enableSHN = FindProperty("_BAKERY_SHNONLINEAR", props); + enableRNM = FindProperty("_BAKERY_RNM", props); + enableSpec = FindProperty("_BAKERY_LMSPEC", props); + enableBicubic = FindProperty("_BAKERY_BICUBIC", props); + enablePSHN = FindProperty("_BAKERY_PROBESHNONLINEAR", props); + try + { + enableVolumes = FindProperty("_BAKERY_VOLUME", props); + enableVolumeRot = FindProperty("_BAKERY_VOLROTATION", props); + volume0 = FindProperty("_Volume0", props); + volume1 = FindProperty("_Volume1", props); + volume2 = FindProperty("_Volume2", props); + volumeMask = FindProperty("_VolumeMask", props); + volumeMin = FindProperty("_VolumeMin", props); + volumeInvSize = FindProperty("_VolumeInvSize", props); + } + catch + { + + } + } + + public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) + { + FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly + m_MaterialEditor = materialEditor; + Material material = materialEditor.target as Material; + + // Make sure that needed keywords are set up if we're switching some existing + // material to a standard shader. + if (m_FirstTimeApply) + { + SetMaterialKeywords(material, m_WorkflowMode); + m_FirstTimeApply = false; + } + + ShaderPropertiesGUI(material); + } + + public void ShaderPropertiesGUI(Material material) + { + // Use default labelWidth + EditorGUIUtility.labelWidth = 0f; + + // Detect any changes to the material + EditorGUI.BeginChangeCheck(); + { + BlendModePopup(); + + // Primary properties + GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel); + DoAlbedoArea(material); + DoSpecularMetallicArea(); + m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ? bumpScale : null); + m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap, heightMap.textureValue != null ? heigtMapScale : null); + m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap, occlusionMap.textureValue != null ? occlusionStrength : null); + DoEmissionArea(material); + m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask); + EditorGUI.BeginChangeCheck(); + m_MaterialEditor.TextureScaleOffsetProperty(albedoMap); + if (EditorGUI.EndChangeCheck()) + { + emissionMap.textureScaleAndOffset = albedoMap.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake + } + + EditorGUILayout.Space(); + + // Secondary properties + GUILayout.Label(Styles.secondaryMapsText, EditorStyles.boldLabel); + m_MaterialEditor.TexturePropertySingleLine(Styles.detailAlbedoText, detailAlbedoMap); + m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, detailNormalMap, detailNormalMapScale); + m_MaterialEditor.TextureScaleOffsetProperty(detailAlbedoMap); + m_MaterialEditor.ShaderProperty(uvSetSecondary, Styles.uvSetLabel.text); + + // Third properties + GUILayout.Label(Styles.forwardText, EditorStyles.boldLabel); + if (highlights != null) + m_MaterialEditor.ShaderProperty(highlights, Styles.highlightsText); + if (reflections != null) + m_MaterialEditor.ShaderProperty(reflections, Styles.reflectionsText); + + GUILayout.Label(Styles.bakeryText, EditorStyles.boldLabel); + + m_MaterialEditor.ShaderProperty(enableDoubleSidedOn, Styles.doubleSidedLabel); + enableDoubleSided.floatValue = enableDoubleSidedOn.floatValue > 0 ? 0 : 2; + + m_MaterialEditor.ShaderProperty(enableVertexLM, Styles.vertexLMLabel); + if (enableVertexLM.floatValue > 0) + { + m_MaterialEditor.ShaderProperty(enableVertexLMdir, Styles.vertexLMdirLabel); + //if (enableVertexLMdir.floatValue > 0) enableVertexLMSH.floatValue = 0; + } + if (enableVertexLM.floatValue > 0) + { + m_MaterialEditor.ShaderProperty(enableVertexLMSH, Styles.vertexLMSHLabel); + //if (enableVertexLMSH.floatValue > 0) enableVertexLMdir.floatValue = 0; + } + if (enableVertexLM.floatValue > 0) + { + m_MaterialEditor.ShaderProperty(enableVertexLMmask, Styles.vertexLMMaskLabel); + } + m_MaterialEditor.ShaderProperty(enableRNM, Styles.rnmLabel); + m_MaterialEditor.ShaderProperty(enableSH, Styles.shLabel); + if (enableSH.floatValue > 0 || enableVertexLMSH.floatValue > 0) + m_MaterialEditor.ShaderProperty(enableSHN, Styles.shnLabel); + m_MaterialEditor.ShaderProperty(enableSpec, Styles.specLabel); + m_MaterialEditor.ShaderProperty(enableBicubic, Styles.bicubicLabel); + m_MaterialEditor.ShaderProperty(enablePSHN, Styles.pshnLabel); + + try + { + m_MaterialEditor.ShaderProperty(enableVolumes, Styles.volLabel); + if (enableVolumes.floatValue > 0) + { + var prevAssignedVolume = assignedVolume; + assignedVolume = EditorGUILayout.ObjectField(volume0.textureValue == null ? "Assign volume" : "Assign different volume", assignedVolume, typeof(BakeryVolume), true) as BakeryVolume; + if (prevAssignedVolume != assignedVolume) + { + volume0.textureValue = assignedVolume.bakedTexture0; + volume1.textureValue = assignedVolume.bakedTexture1; + volume2.textureValue = assignedVolume.bakedTexture2; + volumeMask.textureValue = assignedVolume.bakedMask; + var b = assignedVolume.bounds; + volumeMin.vectorValue = b.min; + volumeInvSize.vectorValue = new Vector3(1.0f/b.size.x, 1.0f/b.size.y, 1.0f/b.size.z); + assignedVolume = null; + } + if (volume0.textureValue != null) + { + if (GUILayout.Button("Unset volume")) + { + volume0.textureValue = null; + volume1.textureValue = null; + volume2.textureValue = null; + volumeMask.textureValue = null; + volumeMin.vectorValue = Vector3.zero; + volumeInvSize.vectorValue = Vector3.one * 1000001; + } + } + EditorGUILayout.LabelField("Current Volume: " + (volume0.textureValue == null ? "<none or global>" : volume0.textureValue.name.Substring(0, volume0.textureValue.name.Length-1))); + EditorGUI.BeginDisabledGroup(true); + m_MaterialEditor.TexturePropertySingleLine(Styles.volLabel0, volume0); + m_MaterialEditor.TexturePropertySingleLine(Styles.volLabel1, volume1); + m_MaterialEditor.TexturePropertySingleLine(Styles.volLabel2, volume2); + m_MaterialEditor.TexturePropertySingleLine(Styles.volLabelMask, volumeMask); + var bmin4 = volumeMin.vectorValue; + var bmin = new Vector3(bmin4.x, bmin4.y, bmin4.z); + var invSize = volumeInvSize.vectorValue; + var bmax = new Vector3(1.0f/invSize.x + bmin.x, 1.0f/invSize.y + bmin.y, 1.0f/invSize.z + bmin.z); + EditorGUILayout.LabelField("Min: " + bmin); + EditorGUILayout.LabelField("Max: " + bmax); + EditorGUI.EndDisabledGroup(); + m_MaterialEditor.ShaderProperty(enableVolumeRot, Styles.volLabelRot); + } + } + catch + { + + } + + EditorGUILayout.Space(); + } + if (EditorGUI.EndChangeCheck()) + { + foreach (var obj in blendMode.targets) + MaterialChanged((Material)obj, m_WorkflowMode); + } + } + + internal void DetermineWorkflow(MaterialProperty[] props) + { + if (FindProperty("_SpecGlossMap", props, false) != null && FindProperty("_SpecColor", props, false) != null) + m_WorkflowMode = WorkflowMode.Specular; + else if (FindProperty("_MetallicGlossMap", props, false) != null && FindProperty("_Metallic", props, false) != null) + m_WorkflowMode = WorkflowMode.Metallic; + else + m_WorkflowMode = WorkflowMode.Dielectric; + } + + public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) + { + // _Emission property is lost after assigning Standard shader to the material + // thus transfer it before assigning the new shader + if (material.HasProperty("_Emission")) + { + material.SetColor("_EmissionColor", material.GetColor("_Emission")); + } + + base.AssignNewShaderToMaterial(material, oldShader, newShader); + + if (oldShader == null || !oldShader.name.Contains("Legacy Shaders/")) + { + SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode")); + return; + } + + BlendMode blendMode = BlendMode.Opaque; + if (oldShader.name.Contains("/Transparent/Cutout/")) + { + blendMode = BlendMode.Cutout; + } + else if (oldShader.name.Contains("/Transparent/")) + { + // NOTE: legacy shaders did not provide physically based transparency + // therefore Fade mode + blendMode = BlendMode.Fade; + } + material.SetFloat("_Mode", (float)blendMode); + + DetermineWorkflow(MaterialEditor.GetMaterialProperties(new Material[] { material })); + MaterialChanged(material, m_WorkflowMode); + } + + void BlendModePopup() + { + EditorGUI.showMixedValue = blendMode.hasMixedValue; + var mode = (BlendMode)blendMode.floatValue; + + EditorGUI.BeginChangeCheck(); + mode = (BlendMode)EditorGUILayout.Popup(Styles.renderingMode, (int)mode, Styles.blendNames); + if (EditorGUI.EndChangeCheck()) + { + m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Mode"); + blendMode.floatValue = (float)mode; + } + + EditorGUI.showMixedValue = false; + } + + void DoAlbedoArea(Material material) + { + m_MaterialEditor.TexturePropertySingleLine(Styles.albedoText, albedoMap, albedoColor); + if (((BlendMode)material.GetFloat("_Mode") == BlendMode.Cutout)) + { + m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1); + } + } + + void DoEmissionArea(Material material) + { + bool showHelpBox = !HasValidEmissiveKeyword(material); + + bool hadEmissionTexture = emissionMap.textureValue != null; + + // Texture and HDR color controls + m_MaterialEditor.TexturePropertyWithHDRColor(Styles.emissionText, emissionMap, emissionColorForRendering, m_ColorPickerHDRConfig, false); + + // If texture was assigned and color was black set color to white + float brightness = emissionColorForRendering.colorValue.maxColorComponent; + if (emissionMap.textureValue != null && !hadEmissionTexture && brightness <= 0f) + emissionColorForRendering.colorValue = Color.white; + + // Emission for GI? + m_MaterialEditor.LightmapEmissionProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1); + + if (showHelpBox) + { + EditorGUILayout.HelpBox(Styles.emissiveWarning.text, MessageType.Warning); + } + } + + void DoSpecularMetallicArea() + { + bool hasGlossMap = false; + if (m_WorkflowMode == WorkflowMode.Specular) + { + hasGlossMap = specularMap.textureValue != null; + m_MaterialEditor.TexturePropertySingleLine(Styles.specularMapText, specularMap, hasGlossMap ? null : specularColor); + } + else if (m_WorkflowMode == WorkflowMode.Metallic) + { + hasGlossMap = metallicMap.textureValue != null; + m_MaterialEditor.TexturePropertySingleLine(Styles.metallicMapText, metallicMap, hasGlossMap ? null : metallic); + } + + bool showSmoothnessScale = hasGlossMap; + if (smoothnessMapChannel != null) + { + int smoothnessChannel = (int)smoothnessMapChannel.floatValue; + if (smoothnessChannel == (int)SmoothnessMapChannel.AlbedoAlpha) + showSmoothnessScale = true; + } + + int indentation = 2; // align with labels of texture properties + m_MaterialEditor.ShaderProperty(showSmoothnessScale ? smoothnessScale : smoothness, showSmoothnessScale ? Styles.smoothnessScaleText : Styles.smoothnessText, indentation); + + ++indentation; + if (smoothnessMapChannel != null) + m_MaterialEditor.ShaderProperty(smoothnessMapChannel, Styles.smoothnessMapChannelText, indentation); + } + + public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode) + { + switch (blendMode) + { + case BlendMode.Opaque: + material.SetOverrideTag("RenderType", "Opaque"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + break; + case BlendMode.Cutout: + material.SetOverrideTag("RenderType", "TransparentCutout"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.EnableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest; + break; + case BlendMode.Fade: + material.SetOverrideTag("RenderType", "Transparent"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetInt("_ZWrite", 0); + material.DisableKeyword("_ALPHATEST_ON"); + material.EnableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; + break; + case BlendMode.Transparent: + material.SetOverrideTag("RenderType", "Transparent"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetInt("_ZWrite", 0); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; + break; + } + } + + static SmoothnessMapChannel GetSmoothnessMapChannel(Material material) + { + int ch = (int)material.GetFloat("_SmoothnessTextureChannel"); + if (ch == (int)SmoothnessMapChannel.AlbedoAlpha) + return SmoothnessMapChannel.AlbedoAlpha; + else + return SmoothnessMapChannel.SpecularMetallicAlpha; + } + + static bool ShouldEmissionBeEnabled(Material mat, Color color) + { + var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0; + return color.maxColorComponent > 0.1f / 255.0f || realtimeEmission; + } + + static void SetMaterialKeywords(Material material, WorkflowMode workflowMode) + { + // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation + // (MaterialProperty value might come from renderer material property block) + SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap")); + if (workflowMode == WorkflowMode.Specular) + SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap")); + else if (workflowMode == WorkflowMode.Metallic) + SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap")); + SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); + SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); + + bool shouldEmissionBeEnabled = ShouldEmissionBeEnabled(material, material.GetColor("_EmissionColor")); + SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); + + if (material.HasProperty("_SmoothnessTextureChannel")) + { + SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha); + } + + // Setup lightmap emissive flags + MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags; + if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) + { + flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; + if (!shouldEmissionBeEnabled) + flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; + + material.globalIlluminationFlags = flags; + } + } + + bool HasValidEmissiveKeyword(Material material) + { + // Material animation might be out of sync with the material keyword. + // So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning. + // (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering)) + bool hasEmissionKeyword = material.IsKeywordEnabled("_EMISSION"); + if (!hasEmissionKeyword && ShouldEmissionBeEnabled(material, emissionColorForRendering.colorValue)) + return false; + else + return true; + } + + static void MaterialChanged(Material material, WorkflowMode workflowMode) + { + SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode")); + + SetMaterialKeywords(material, workflowMode); + } + + static void SetKeyword(Material m, string keyword, bool state) + { + if (state) + m.EnableKeyword(keyword); + else + m.DisableKeyword(keyword); + } + } +} + +#endif diff --git a/VRCSDK3Worlds/Assets/Bakery/shader/Editor/BakeryShaderGUI.cs.meta b/VRCSDK3Worlds/Assets/Bakery/shader/Editor/BakeryShaderGUI.cs.meta new file mode 100644 index 00000000..6c58ef8a --- /dev/null +++ b/VRCSDK3Worlds/Assets/Bakery/shader/Editor/BakeryShaderGUI.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0465c9a9a7404f34fadd23fd32de6557 +timeCreated: 1538411297 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |