Initial commit

This commit is contained in:
msk
2022-01-22 20:13:49 -08:00
parent f9d23e5bcf
commit 687473573d
878 changed files with 70957 additions and 0 deletions
@@ -0,0 +1,68 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file Deferred.cginc
/// @brief Deferred passes uber-header.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_DEFERRED_CGINC
#define ALLOY_SHADERS_FRAMEWORK_DEFERRED_CGINC
#define A_DEFERRED_PASS
#define A_TANGENT_TO_WORLD_ON
#define A_REFLECTION_PROBES_ON
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/LightingImpl.cginc"
#include "UnityCG.cginc"
#include "UnityDeferredLibrary.cginc"
#include "UnityGlobalIllumination.cginc"
#include "UnityImageBasedLighting.cginc"
#include "UnityShaderVariables.cginc"
#include "UnityStandardBRDF.cginc"
#include "UnityStandardUtils.cginc"
sampler2D _CameraGBufferTexture0;
sampler2D _CameraGBufferTexture1;
sampler2D _CameraGBufferTexture2;
/// Creates a surface description from a Unity G-Buffer.
/// @param[in,out] i Unity deferred vertex format.
/// @return Material surface data.
ASurface aDeferredSurface(
inout unity_v2f_deferred i)
{
ASurface s = aNewSurface();
// Set vertex data.
i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
s.screenPosition = i.uv;
s.screenUv = s.screenPosition.xy / s.screenPosition.w;
// Convert G-Buffer to surface.
float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, s.screenUv));
half4 gbuffer0 = tex2D(_CameraGBufferTexture0, s.screenUv);
half4 gbuffer1 = tex2D(_CameraGBufferTexture1, s.screenUv);
half4 gbuffer2 = tex2D(_CameraGBufferTexture2, s.screenUv);
float4 vpos = float4(i.ray * depth, 1.0f);
s.viewDepth = vpos.z;
s.positionWorld = mul(unity_CameraToWorld, vpos).xyz;
s.viewDirWorld = normalize(UnityWorldSpaceViewDir(s.positionWorld));
s.albedo = gbuffer0.rgb;
s.specularOcclusion = gbuffer0.a;
s.f0 = gbuffer1.rgb;
s.roughness = 1.0h - gbuffer1.a;
s.beckmannRoughness = aLinearToBeckmannRoughness(s.roughness);
s.normalWorld = A_NW(s, normalize(gbuffer2.xyz * 2.0h - 1.0h));
s.materialType = gbuffer2.w;
aPreLighting(s);
return s;
}
#endif // ALLOY_SHADERS_FRAMEWORK_DEFERRED_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f07a38f558ae0be49aa491fd74692918
timeCreated: 1491528345
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,393 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file Feature.cginc
/// @brief Features uber-header. Holds methods that rely on uniforms.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_FEATURE_CGINC
#define ALLOY_SHADERS_FRAMEWORK_FEATURE_CGINC
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/Lighting.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "UnityCG.cginc"
#include "UnityStandardUtils.cginc"
/// Picks either UV0 or UV1.
#define A_TEX_UV(s, name) (aPickUv(s, name##UV))
/// Applies Unity texture transforms plus UV0.
#define A_TEX_TRANSFORM(s, name) (TRANSFORM_TEX(s.uv01.xy, name))
/// Applies Unity texture transforms plus UV-switching effect.
#define A_TEX_TRANSFORM_UV(s, name) (TRANSFORM_TEX(A_TEX_UV(s, name), name))
/// Applies Unity texture transforms plus UV-switching and our scrolling effects.
#define A_TEX_TRANSFORM_UV_SCROLL(s, name) (A_TEX_TRANSFORM_SCROLL(name, A_TEX_UV(s, name)))
/// Base UV assignment and update of associated fields.
#define A_BV(s, UV) UV; aUpdateBaseUv(s)
/// Contains accumulated splat material data.
struct ASplat {
/// Non-TriPlanar transformed base UVs.
float2 baseUv;
/// (RGB) Base Color, (A) Opacity.
/// Expects linear-space LDR color values.
half4 material0;
/// (R) Metallic, (G) AO/Specular Tint, (B) Specularity, (A) Roughness.
/// Expects values in the range [0,1].
half4 material1;
/// (RGB) Emission, (A) Specular Tint.
/// Expects linear-space HDR color values.
half4 material2;
/// World, Object, or Tangent normals.
/// Expects a normalized vector.
half3 normal;
};
/// Contains shared state for all splat functions, including TriPlanar data.
struct ASplatContext {
/// Vertex color.
/// Expects linear-space LDR color values.
half4 vertexColor;
/// The model's UV0 & UV1 texture coordinate data.
/// Be aware that it can have parallax precombined with it.
float4 uv01;
/// X-axis TriPlanar tangent to world matrix.
half3x3 xTangentToWorld;
/// Y-axis TriPlanar tangent to world matrix.
half3x3 yTangentToWorld;
/// Z-axis TriPlanar tangent to world matrix.
half3x3 zTangentToWorld;
/// Blend weights between the top, middle, and bottom TriPlanar axis.
half3 blend;
/// Position in either world or object-space.
float3 position;
/// Binary masks for the positive values in the vertex normals.
half3 axisMasks;
};
/// Cutoff value that controls where cutout occurs over opacity.
/// Expects values in the range [0,1].
half _Cutoff;
/// Toggles inverting the backface normals.
/// Expects the values 0 or 1.
float _TransInvertBackNormal;
/// The base tint color.
/// Expects a linear LDR color with alpha.
half4 _Color;
/// Base color map.
/// Expects an RGB(A) map with sRGB sampling.
A_SAMPLER_2D(_MainTex);
/// Base packed material map.
/// Expects an RGBA data map.
A_SAMPLER_2D(_SpecTex);
/// Metallic map.
/// Expects an RGB map with sRGB sampling
sampler2D _MetallicMap;
/// Ambient Occlusion map.
/// Expects an RGB map with sRGB sampling
sampler2D _AoMap;
/// Specularity map.
/// Expects an RGB map with sRGB sampling
sampler2D _SpecularityMap;
/// Roughness map.
/// Expects an RGB map with sRGB sampling
sampler2D _RoughnessMap;
/// Base normal map.
/// Expects a compressed normal map.
sampler2D _BumpMap;
/// Height map.
/// Expects an RGBA data map.
sampler2D _ParallaxMap;
/// Toggles tinting the base color by the vertex color.
/// Expects values in the range [0,1].
half _BaseColorVertexTint;
/// The base metallic scale.
/// Expects values in the range [0,1].
half _Metal;
/// The base specularity scale.
/// Expects values in the range [0,1].
half _Specularity;
// Amount that f0 is tinted by the base color.
/// Expects values in the range [0,1].
half _SpecularTint;
/// The base roughness scale.
/// Expects values in the range [0,1].
half _Roughness;
/// Ambient Occlusion strength.
/// Expects values in the range [0,1].
half _Occlusion;
/// Normal map XY scale.
half _BumpScale;
/// Height scale of the heightmap.
/// Expects values in the range [0,0.08].
float _Parallax;
/// Splat data constructor.
ASplat aNewSplat();
/// Uses surface data to make shared splat data.
/// @param s Material surface data.
/// @param sharpness Sharpness of the blend between TriPlanar axis.
/// @param positionScale Scales the position used for TriPlanar UVs.
/// @return Splat context initialized with shared data.
ASplatContext aNewSplatContext(ASurface s, half sharpness, float positionScale);
/// Converts splat to material data and assigns it to a surface.
/// @param[in,out] s Material surface data.
/// @param[in] sp Combined splat data.
void aApplySplat(inout ASurface s, ASplat sp);
/// Uses mask to blend a splat into surface.
/// @param[in,out] s Material surface data.
/// @param[in] sp Combined splat data.
void aBlendSplat(inout ASurface s, ASplat sp);
/// Uses splat opacity and mask to blend a splat into surface.
/// @param[in,out] s Material surface data.
/// @param[in] sp Combined splat data.
void aBlendSplatWithOpacity(inout ASurface s, ASplat sp);
/// Combines two splats into one, accumulating into first splat.
/// @param[in,out] sp0 Target for combined splat data ouput.
/// @param[in] sp1 Second splat to be combined.
void aMergeSplats(inout ASplat sp0, ASplat sp1);
/// Applies constant material data to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] sc Splat context.
/// @param[in] tint Base color tint.
/// @param[in] vertexTint Base color vertex color tint weight.
/// @param[in] metallic Metallic weight.
/// @param[in] specularity Specularity.
/// @param[in] specularTint Specular tint weight.
/// @param[in] roughness Linear roughness.
void aSplatMaterial(inout ASplat sp, ASplatContext sc, half4 tint, half vertexTint, half metallic, half specularity, half specularTint, half roughness);
/// TriPlanar axis applied to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] mask Masks where the effect is applied.
/// @param[in] tbn Local normal tangent to world matrix.
/// @param[in] uv Texture coordinates.
/// @param[in] occlusion Occlusion map weight.
/// @param[in] bumpScale Normal map XY scale.
/// @param[in] base Base color map.
/// @param[in] material Material map.
/// @param[in] normal Normal map.
void aTriPlanarAxis(inout ASplat sp, half mask, half3x3 tbn, float2 uv, half occlusion, half bumpScale, sampler2D base, sampler2D material, sampler2D normal);
/// X-axis triplanar material applied to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] sc Splat context.
/// @param[in] base Base color map.
/// @param[in] material Material map.
/// @param[in] normal Normal map.
/// @param[in] occlusion Occlusion map weight.
/// @param[in] bumpScale Normal map XY scale.
void aTriPlanarX(inout ASplat sp, ASplatContext sc, A_SAMPLER_PARAM(base), sampler2D material, sampler2D normal, half occlusion, half bumpScale);
/// Y-axis triplanar material applied to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] sc Splat context.
/// @param[in] base Base color map.
/// @param[in] material Material map.
/// @param[in] normal Normal map.
/// @param[in] occlusion Occlusion map weight.
/// @param[in] bumpScale Normal map XY scale.
void aTriPlanarY(inout ASplat sp, ASplatContext sc, A_SAMPLER_PARAM(base), sampler2D material, sampler2D normal, half occlusion, half bumpScale);
/// Z-axis triplanar material applied to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] sc Splat context.
/// @param[in] base Base color map.
/// @param[in] material Material map.
/// @param[in] normal Normal map.
/// @param[in] occlusion Occlusion map weight.
/// @param[in] bumpScale Normal map XY scale.
void aTriPlanarZ(inout ASplat sp, ASplatContext sc, A_SAMPLER_PARAM(base), sampler2D material, sampler2D normal, half occlusion, half bumpScale);
/// Positive Y-axis triplanar material applied to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] sc Splat context.
/// @param[in] base Base color map.
/// @param[in] material Material map.
/// @param[in] normal Normal map.
/// @param[in] occlusion Occlusion map weight.
/// @param[in] bumpScale Normal map XY scale.
void aTriPlanarPositiveY(inout ASplat sp, ASplatContext sc, A_SAMPLER_PARAM(base), sampler2D material, sampler2D normal, half occlusion, half bumpScale);
/// Negative Y-axis triplanar material applied to a splat.
/// @param[in,out] sp Splat being modified.
/// @param[in] sc Splat context.
/// @param[in] base Base color map.
/// @param[in] material Material map.
/// @param[in] normal Normal map.
/// @param[in] occlusion Occlusion map weight.
/// @param[in] bumpScale Normal map XY scale.
void aTriPlanarNegativeY(inout ASplat sp, ASplatContext sc, A_SAMPLER_PARAM(base), sampler2D material, sampler2D normal, half occlusion, half bumpScale);
/// Applies constant material data to a splat.
/// @param sc Splat context.
/// @param base Base color map.
/// @param material Material map.
/// @param normal Normal map.
/// @param tint Base color tint.
/// @param vertexTint Base vertex color tint.
/// @param metallic Metallic weight.
/// @param specularity Specularity.
/// @param specularTint Specular tint weight.
/// @param roughness Linear roughness.
/// @param occlusion Occlusion map weight.
/// @param bumpScale Normal map XY scale.
/// @return Splat populated with terrain data.
ASplat aNewSplat(ASplatContext sc, A_SAMPLER_PARAM(base), sampler2D material, sampler2D normal, half4 tint, half vertexTint, half metallic, half specularity, half specularTint, half roughness, half occlusion, half bumpScale);
/// Combine splats and convert to material data to assign to a surface.
/// @param[in,out] s Material surface data.
/// @param[in] weights Weights masking where splats are combined.
/// @param[in] sp0 Splat data.
/// @param[in] sp1 Splat data.
/// @param[in] sp2 Splat data.
void aApplyTerrainSplats(inout ASurface s, half3 weights, ASplat sp0, ASplat sp1, ASplat sp2);
/// Combine splats and convert to material data to assign to a surface.
/// @param[in,out] s Material surface data.
/// @param[in] weights Weights masking where splats are combined.
/// @param[in] sp0 Splat data.
/// @param[in] sp1 Splat data.
/// @param[in] sp2 Splat data.
/// @param[in] sp3 Splat data.
void aApplyTerrainSplats(inout ASurface s, half4 weights, ASplat sp0, ASplat sp1, ASplat sp2, ASplat sp3);
/// Converts AO to linear space and controls the strength of the effect.
/// @param ao Gamma-space LDR AO value.
/// @param weight Strength of the AO effect.
/// @return Weighted, linear-space AO value.
half aOcclusionStrength(half ao, half weight);
/// Sets up base UV for the first time.
/// @param[in,out] s Material surface data.
void aBaseUvInit(inout ASurface s);
/// Update values dependent on base UV.
void aUpdateBaseUv(inout ASurface s);
/// Pick between UV0 & UV1.
float2 aPickUv(ASurface s, float nameUv);
/// Pick between UV0 & UV1.
float2 aPickUv(ASplatContext sc, float nameUv);
/// Sets whether backface normals are inverted.
/// @param[in,out] s Material surface data.
void aTwoSided(inout ASurface s);
/// Applies cutout effect.
/// @param s Material surface data.
void aCutout(ASurface s);
/// Samples the base color map.
/// @param s Material surface data.
/// @return Base Color with alpha.
half4 aSampleBase(ASurface s);
/// Samples the base material map.
/// @param s Material surface data.
/// @return Packed material.
half4 aSampleMaterial(ASurface s);
/// Samples and scales the base bump map.
/// @param s Material surface data.
/// @param scale Normal XY scale factor.
/// @return Normalized tangent-space normal.
half3 aSampleBumpScale(ASurface s, half scale);
/// Samples the base bump map.
/// @param s Material surface data.
/// @return Normalized tangent-space normal.
half3 aSampleBump(ASurface s);
/// Samples the base bump map biasing the mipmap level sampled.
/// @param s Material surface data.
/// @param bias Mipmap level bias.
/// @return Normalized tangent-space normal.
half3 aSampleBumpBias(ASurface s, float bias);
/// Samples the base bump map biasing the mipmap level sampled.
/// @param s Material surface data.
/// @return Normalized tangent-space normal.
half aSampleHeight(ASurface s);
/// Applies color based on weight parameter.
/// @param s Material surface data.
/// @param strength Amount to blend in vertex color.
/// @return Vertex color tint.
half3 aVertexColorTint(ASurface s, half strength);
/// Applies base vertex color.
/// @param s Material surface data.
/// @return Vertex color tint.
half3 aBaseVertexColorTint(ASurface s);
/// Gets combined base color tint from uniform and vertex color.
/// @param s Material surface data.
/// @return Base Color with alpha.
half4 aBaseTint(ASurface s);
/// Gets combined base color from main channels.
/// @param s Material surface data.
/// @return Base Color with alpha.
half4 aBase(ASurface s);
/// Applies texture coordinate offsets to surface data.
/// @param[in,out] s Material surface data.
/// @param[in] offset Texture coordinate offset.
void aParallaxOffset(inout ASurface s, float2 offset);
/// Calculates Offset Bump Mapping texture offsets.
/// @param[in,out] s Material surface data.
void aOffsetBumpMapping(inout ASurface s);
/// Calculates Parallax Occlusion Mapping texture offsets.
/// @param[in,out] s Material surface data.
/// @param[in] minSamples Minimum number of samples for POM effect [1,n].
/// @param[in] maxSamples Maximum number of samples for POM effect [1,n].
void aParallaxOcclusionMapping(inout ASurface s, float minSamples, float maxSamples);
#endif // ALLOY_SHADERS_FRAMEWORK_FEATURE_CGINC
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: aeac9cf700a9bac48bf2bd38f0fcc351
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
@@ -0,0 +1,707 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file Feature.cginc
/// @brief Feature method implementations to allow disabling of features.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_FEATURE_IMPL_CGINC
#define ALLOY_SHADERS_FRAMEWORK_FEATURE_IMPL_CGINC
#if !defined(A_TEX_UV_OFF) && defined(A_PROJECTIVE_DECAL_SHADER)
#define A_TEX_UV_OFF
#endif
#if !defined(A_TRIPLANAR_MAPPING_ON) && defined(_METALLICGLOSSMAP)
#define A_TRIPLANAR_MAPPING_ON
#endif
#ifdef A_TRIPLANAR_MAPPING_ON
#ifndef _TRIPLANARMODE_WORLD
#define A_WORLD_TO_OBJECT_ON
#endif
#ifndef A_NORMAL_WORLD_ON
#define A_NORMAL_WORLD_ON
#endif
#ifndef A_POSITION_WORLD_ON
#define A_POSITION_WORLD_ON
#endif
#endif
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/Feature.cginc"
#include "Assets/Alloy/Shaders/Framework/LightingImpl.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "UnityStandardUtils.cginc"
#define A_BASE_COLOR material0.rgb
#define A_OPACITY material0.a
#define A_METALLIC material1.A_METALLIC_CHANNEL
#define A_AMBIENT_OCCLUSION material1.A_AO_CHANNEL
#define A_SPECULARITY material1.A_SPECULARITY_CHANNEL
#define A_ROUGHNESS material1.A_ROUGHNESS_CHANNEL
#ifdef A_AMBIENT_OCCLUSION_ON
#define A_SPECULAR_TINT material2.a
#else
#define A_SPECULAR_TINT material1.g
#endif
#define A_EMISSIVE_COLOR material2.rgb
ASplat aNewSplat()
{
ASplat sp;
UNITY_INITIALIZE_OUTPUT(ASplat, sp);
sp.material0 = 0.0h;
sp.material1 = 0.0h;
sp.material2 = 0.0h;
sp.normal = 0.0h;
return sp;
}
ASplatContext aNewSplatContext(
ASurface s,
half sharpness,
float positionScale)
{
ASplatContext sc;
UNITY_INITIALIZE_OUTPUT(ASplatContext, sc);
sc.uv01 = s.uv01;
sc.vertexColor = s.vertexColor;
#ifdef A_TRIPLANAR_MAPPING_ON
// Triplanar mapping
// cf http://www.gamedev.net/blog/979/entry-2250761-triplanar-texturing-and-normal-mapping/
#ifdef _TRIPLANARMODE_WORLD
half3 geoNormal = s.vertexNormalWorld;
sc.position = s.positionWorld;
#else
half3 geoNormal = UnityWorldToObjectDir(s.vertexNormalWorld);
sc.position = mul(unity_WorldToObject, float4(s.positionWorld, 1.0f)).xyz;
#endif
// Unity uses a Left-handed axis, so it requires clumsy remapping.
sc.xTangentToWorld = half3x3(A_AXIS_Z, A_AXIS_Y, geoNormal);
sc.yTangentToWorld = half3x3(A_AXIS_X, A_AXIS_Z, geoNormal);
sc.zTangentToWorld = half3x3(A_AXIS_X, A_AXIS_Y, geoNormal);
half3 blending = abs(geoNormal);
blending = normalize(max(blending, A_EPSILON));
blending = pow(blending, sharpness);
blending /= dot(blending, A_ONE);
sc.blend = blending;
sc.axisMasks = step(A_ZERO, geoNormal);
sc.position *= positionScale;
#endif
return sc;
}
void aApplySplat(
inout ASurface s,
ASplat sp)
{
half3 normal = sp.normal;
s.baseColor = sp.A_BASE_COLOR;
s.opacity = sp.A_OPACITY;
s.metallic = sp.A_METALLIC;
s.specularity = sp.A_SPECULARITY;
s.specularTint = sp.A_SPECULAR_TINT;
s.roughness = sp.A_ROUGHNESS;
#ifdef A_AMBIENT_OCCLUSION_ON
s.ambientOcclusion = sp.A_AMBIENT_OCCLUSION;
#endif
#ifdef A_EMISSIVE_COLOR_ON
s.emissiveColor = sp.A_EMISSIVE_COLOR;
#endif
#ifndef A_TRIPLANAR_MAPPING_ON
s.normalTangent = A_NT(s, normalize(normal));
#else
#ifdef _TRIPLANARMODE_WORLD
half3 normalWorld = normalize(normal);
#else
half3 normalWorld = UnityObjectToWorldNormal(normal);
#endif
s.normalWorld = A_NW(s, normalWorld);
#endif
}
void aBlendSplat(
inout ASurface s,
ASplat sp)
{
half3 normal = sp.normal;
half weight = s.mask;
s.baseColor = lerp(s.baseColor, sp.A_BASE_COLOR, weight);
s.opacity = lerp(s.opacity, sp.A_OPACITY, weight);
s.metallic = lerp(s.metallic, sp.A_METALLIC, weight);
s.specularity = lerp(s.specularity, sp.A_SPECULARITY, weight);
s.specularTint = lerp(s.specularTint, sp.A_SPECULAR_TINT, weight);
s.roughness = lerp(s.roughness, sp.A_ROUGHNESS, weight);
#ifdef A_AMBIENT_OCCLUSION_ON
s.ambientOcclusion = lerp(s.ambientOcclusion, sp.A_AMBIENT_OCCLUSION, weight);
#endif
#ifdef A_EMISSIVE_COLOR_ON
s.emissiveColor = lerp(s.emissiveColor, sp.A_EMISSIVE_COLOR, weight);
#endif
#ifndef A_TRIPLANAR_MAPPING_ON
s.normalTangent = A_NT(s, normalize(lerp(s.normalTangent, normal, weight)));
#else
#ifdef _TRIPLANARMODE_WORLD
half3 normalWorld = normalize(normal);
#else
half3 normalWorld = UnityObjectToWorldNormal(normal);
#endif
s.normalWorld = A_NW(s, normalize(lerp(s.normalWorld, normalWorld, weight)));
#endif
}
void aBlendSplatWithOpacity(
inout ASurface s,
ASplat sp)
{
s.mask *= sp.A_OPACITY;
sp.A_OPACITY = 1.0h;
aBlendSplat(s, sp);
}
void aMergeSplats(
inout ASplat sp0,
ASplat sp1)
{
sp0.material0 += sp1.material0;
sp0.material1 += sp1.material1;
sp0.normal += sp1.normal;
sp0.material2 += sp1.material2;
}
void aSplatMaterial(
inout ASplat sp,
ASplatContext sc,
half4 tint,
half vertexTint,
half metallic,
half specularity,
half specularTint,
half roughness)
{
sp.material0 *= tint;
#ifndef A_VERTEX_COLOR_IS_DATA
sp.A_BASE_COLOR *= aLerpWhiteTo(sc.vertexColor.rgb, vertexTint);
#endif
sp.A_METALLIC *= metallic;
sp.A_SPECULARITY *= specularity;
sp.A_ROUGHNESS *= roughness;
sp.A_SPECULAR_TINT = specularTint;
}
void aTriPlanarAxis(
inout ASplat sp,
half mask,
half3x3 tbn,
float2 uv,
half occlusion,
half bumpScale,
sampler2D base,
sampler2D material,
sampler2D normal)
{
ASplat sp0 = aNewSplat();
sp0.material0 = tex2D(base, uv);
sp0.normal = mul(UnpackScaleNormal(tex2D(normal, uv), bumpScale), tbn);
#ifndef A_ROUGHNESS_SOURCE_BASE_COLOR_ALPHA
sp0.material1 = tex2D(material, uv);
sp0.A_AMBIENT_OCCLUSION = aOcclusionStrength(sp0.A_AMBIENT_OCCLUSION, occlusion);
#else
sp0.A_METALLIC = 1.0h;
sp0.A_AMBIENT_OCCLUSION = 1.0h;
sp0.A_SPECULARITY = 1.0h;
sp0.A_ROUGHNESS = sp0.A_OPACITY;
sp0.A_OPACITY = 1.0h;
#endif
sp.material0 += mask * sp0.material0;
sp.material1 += mask * sp0.material1;
sp.normal += mask * sp0.normal;
}
void aTriPlanarX(
inout ASplat sp,
ASplatContext sc,
A_SAMPLER_PARAM(base),
sampler2D material,
sampler2D normal,
half occlusion,
half bumpScale)
{
aTriPlanarAxis(sp, sc.blend.x, sc.xTangentToWorld, A_TEX_TRANSFORM_SCROLL(base, sc.position.zy), occlusion, bumpScale, base, material, normal);
}
void aTriPlanarY(
inout ASplat sp,
ASplatContext sc,
A_SAMPLER_PARAM(base),
sampler2D material,
sampler2D normal,
half occlusion,
half bumpScale)
{
aTriPlanarAxis(sp, sc.blend.y, sc.yTangentToWorld, A_TEX_TRANSFORM_SCROLL(base, sc.position.xz), occlusion, bumpScale, base, material, normal);
}
void aTriPlanarZ(
inout ASplat sp,
ASplatContext sc,
A_SAMPLER_PARAM(base),
sampler2D material,
sampler2D normal,
half occlusion,
half bumpScale)
{
aTriPlanarAxis(sp, sc.blend.z, sc.zTangentToWorld, A_TEX_TRANSFORM_SCROLL(base, sc.position.xy), occlusion, bumpScale, base, material, normal);
}
void aTriPlanarPositiveY(
inout ASplat sp,
ASplatContext sc,
A_SAMPLER_PARAM(base),
sampler2D material,
sampler2D normal,
half occlusion,
half bumpScale)
{
aTriPlanarAxis(sp, sc.axisMasks.y * sc.blend.y, sc.yTangentToWorld, A_TEX_TRANSFORM_SCROLL(base, sc.position.xz), occlusion, bumpScale, base, material, normal);
}
void aTriPlanarNegativeY(
inout ASplat sp,
ASplatContext sc,
A_SAMPLER_PARAM(base),
sampler2D material,
sampler2D normal,
half occlusion,
half bumpScale)
{
aTriPlanarAxis(sp, (1.0h - sc.axisMasks.y) * sc.blend.y, sc.yTangentToWorld, A_TEX_TRANSFORM_SCROLL(base, sc.position.xz), occlusion, bumpScale, base, material, normal);
}
ASplat aNewSplat(
ASplatContext sc,
A_SAMPLER_PARAM(base),
sampler2D material,
sampler2D normal,
half4 tint,
half vertexTint,
half metallic,
half specularity,
half specularTint,
half roughness,
half occlusion,
half bumpScale)
{
ASplat sp = aNewSplat();
#ifdef A_TRIPLANAR_MAPPING_ON
aTriPlanarX(sp, sc, A_SAMPLER_2D_INPUT(base), material, normal, occlusion, bumpScale);
aTriPlanarY(sp, sc, A_SAMPLER_2D_INPUT(base), material, normal, occlusion, bumpScale);
aTriPlanarZ(sp, sc, A_SAMPLER_2D_INPUT(base), material, normal, occlusion, bumpScale);
#else
sp.baseUv = A_TEX_TRANSFORM_UV_SCROLL(sc, base);
sp.material0 = tex2D(base, sp.baseUv);
sp.normal = UnpackScaleNormal(tex2D(normal, sp.baseUv), bumpScale);
#ifndef A_ROUGHNESS_SOURCE_BASE_COLOR_ALPHA
sp.material1 = tex2D(material, sp.baseUv);
sp.A_AMBIENT_OCCLUSION = aOcclusionStrength(sp.A_AMBIENT_OCCLUSION, occlusion);
#else
sp.A_METALLIC = 1.0h;
sp.A_AMBIENT_OCCLUSION = 1.0h;
sp.A_SPECULARITY = 1.0h;
sp.A_ROUGHNESS = sp.A_OPACITY;
sp.A_OPACITY = 1.0h;
#endif
#endif
aSplatMaterial(sp, sc, tint, vertexTint, metallic, specularity, specularTint, roughness);
return sp;
}
void aApplyTerrainSplats(
inout ASurface s,
half3 weights,
ASplat sp0,
ASplat sp1,
ASplat sp2)
{
ASplat sp = aNewSplat();
sp.material0 = weights.r * sp0.material0 + weights.g * sp1.material0 + weights.b * sp2.material0;
sp.material1 = weights.r * sp0.material1 + weights.g * sp1.material1 + weights.b * sp2.material1;
sp.material2 = weights.r * sp0.material2 + weights.g * sp1.material2 + weights.b * sp2.material2;
sp.normal = weights.r * sp0.normal + weights.g * sp1.normal + weights.b * sp2.normal;
aApplySplat(s, sp);
}
void aApplyTerrainSplats(
inout ASurface s,
half4 weights,
ASplat sp0,
ASplat sp1,
ASplat sp2,
ASplat sp3)
{
ASplat sp = aNewSplat();
sp.material0 = weights.r * sp0.material0 + weights.g * sp1.material0 + weights.b * sp2.material0 + weights.a * sp3.material0;
sp.material1 = weights.r * sp0.material1 + weights.g * sp1.material1 + weights.b * sp2.material1 + weights.a * sp3.material1;
sp.material2 = weights.r * sp0.material2 + weights.g * sp1.material2 + weights.b * sp2.material2 + weights.a * sp3.material2;
sp.normal = weights.r * sp0.normal + weights.g * sp1.normal + weights.b * sp2.normal + weights.a * sp3.normal;
aApplySplat(s, sp);
}
half aOcclusionStrength(
half ao,
half weight)
{
return aLerpOneTo(aGammaToLinear(ao), weight);
}
void aBaseUvInit(
inout ASurface s)
{
s.baseUv = A_TEX_TRANSFORM_UV_SCROLL(s, _MainTex);
s.baseTiling = _MainTex_ST.xy;
// Initialize VirtualCoord here so subsequent calls can be cheaper updates.
#ifdef _VIRTUALTEXTURING_ON
s.baseVirtualCoord = VTComputeVirtualCoord(s.baseUv);
#endif
}
void aUpdateBaseUv(
inout ASurface s)
{
#ifdef _VIRTUALTEXTURING_ON
s.baseVirtualCoord = VTUpdateVirtualCoord(s.baseVirtualCoord, s.baseUv);
#endif
}
float2 aPickUv(
ASurface s,
float nameUv)
{
#ifdef A_TEX_UV_OFF
return s.uv01.xy;
#else
return nameUv < 0.5f ? s.uv01.xy : s.uv01.zw;
#endif
}
float2 aPickUv(
ASplatContext sc,
float nameUv)
{
#ifdef A_TEX_UV_OFF
return sc.uv01.xy;
#else
return nameUv < 0.5f ? sc.uv01.xy : sc.uv01.zw;
#endif
}
void aTwoSided(
inout ASurface s)
{
#ifdef A_TWO_SIDED_SHADER
s.normalTangent.xy = A_NT(s, s.facingSign > 0.0h || _TransInvertBackNormal < 0.5f ? s.normalTangent.xy : -s.normalTangent.xy);
#endif
}
void aCutout(
ASurface s)
{
#ifdef _ALPHATEST_ON
clip(s.opacity - _Cutoff);
#endif
}
half4 aSampleBase(
ASurface s)
{
half4 result = 0.0h;
#ifdef _VIRTUALTEXTURING_ON
result = VTSampleBase(s.baseVirtualCoord);
#else
result = tex2D(_MainTex, s.baseUv);
#endif
return result;
}
half4 aSampleMaterial(
ASurface s)
{
half4 result = 0.0h;
#ifndef A_EXPANDED_MATERIAL_MAPS
#ifndef _VIRTUALTEXTURING_ON
result = tex2D(_SpecTex, s.baseUv);
#else
result = VTSampleSpecular(s.baseVirtualCoord);
#endif
result.A_AO_CHANNEL = aGammaToLinear(result.A_AO_CHANNEL);
#else
half3 channels;
// Assuming sRGB texture sampling, undo it for all but AO.
channels.x = tex2D(_MetallicMap, s.baseUv).g;
channels.y = tex2D(_SpecularityMap, s.baseUv).g;
channels.z = tex2D(_RoughnessMap, s.baseUv).g;
channels = LinearToGammaSpace(channels);
result.A_METALLIC_CHANNEL = channels.x;
result.A_AO_CHANNEL = tex2D(_AoMap, s.baseUv).g;
result.A_SPECULARITY_CHANNEL = channels.y;
result.A_ROUGHNESS_CHANNEL = channels.z;
#endif
return result;
}
half3 aSampleBumpScale(
ASurface s,
half scale)
{
half4 result = 0.0h;
#ifdef _VIRTUALTEXTURING_ON
result = VTSampleNormal(s.baseVirtualCoord);
#else
result = tex2D(_BumpMap, s.baseUv);
#endif
return UnpackScaleNormal(result, scale);
}
half3 aSampleBump(
ASurface s)
{
return aSampleBumpScale(s, _BumpScale);
}
half3 aSampleBumpBias(
ASurface s,
float bias)
{
half4 result = 0.0h;
#ifdef _VIRTUALTEXTURING_ON
result = VTSampleNormal(VTComputeVirtualCoord(s.baseUv, bias));
#else
result = tex2Dbias(_BumpMap, float4(s.baseUv, 0.0h, bias));
#endif
return UnpackScaleNormal(result, _BumpScale);
}
half aSampleHeight(
ASurface s)
{
half result = 0.0h;
#ifdef _VIRTUALTEXTURING_ON
result = VTSampleNormal(s.baseVirtualCoord).b;
#else
result = tex2D(_ParallaxMap, s.baseUv).y;
#endif
return result;
}
half3 aVertexColorTint(
ASurface s,
half strength)
{
#ifdef A_VERTEX_COLOR_IS_DATA
return A_WHITE;
#else
return aLerpWhiteTo(s.vertexColor.rgb, strength);
#endif
}
half3 aBaseVertexColorTint(
ASurface s)
{
return aVertexColorTint(s, _BaseColorVertexTint);
}
half4 aBaseTint(
ASurface s)
{
half4 result = _Color;
#ifndef A_VERTEX_COLOR_IS_DATA
result.rgb *= aBaseVertexColorTint(s);
#endif
return result;
}
half4 aBase(
ASurface s)
{
return aBaseTint(s) * aSampleBase(s);
}
void aParallaxOffset(
inout ASurface s,
float2 offset)
{
#ifdef A_PARALLAX_MAPPED_PASS
offset *= s.mask;
// To apply the parallax offset to secondary textures without causing swimming,
// we must normalize it by removing the implicitly multiplied base map tiling.
s.uv01 += (offset / s.baseTiling).xyxy;
s.baseUv += A_BV(s, offset);
#endif
}
void aOffsetBumpMapping(
inout ASurface s)
{
// NOTE: Prevents NaN compiler errors in DX9 mode for shadow pass.
#if defined(A_TANGENT_TO_WORLD_ON) && defined(A_VIEW_DIR_TANGENT_ON)
half h = aSampleHeight(s) * _Parallax - _Parallax * 0.5h;
half3 v = s.viewDirTangent;
v.z += 0.42h;
aParallaxOffset(s, h * (v.xy / v.z));
#endif
}
void aParallaxOcclusionMapping(
inout ASurface s,
float minSamples,
float maxSamples)
{
// NOTE: Prevents NaN compiler errors in DX9 mode for shadow pass.
#if defined(A_TANGENT_TO_WORLD_ON) && defined(A_VIEW_DIR_TANGENT_ON)
// Parallax Occlusion Mapping
// Subject to GameDev.net Open License
// cf http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
float2 offset = float2(0.0f, 0.0f);
// Calculate the parallax offset vector max length.
// This is equivalent to the tangent of the angle between the
// viewer position and the fragment location.
float parallaxLimit = -length(s.viewDirTangent.xy) / s.viewDirTangent.z;
// Scale the parallax limit according to heightmap scale.
parallaxLimit *= _Parallax;
// Calculate the parallax offset vector direction and maximum offset.
float2 offsetDirTangent = normalize(s.viewDirTangent.xy);
float2 maxOffset = offsetDirTangent * parallaxLimit;
// Calculate how many samples should be taken along the view ray
// to find the surface intersection. This is based on the angle
// between the surface normal and the view vector.
int numSamples = (int)lerp(maxSamples, minSamples, s.NdotV);
int currentSample = 0;
// Specify the view ray step size. Each sample will shift the current
// view ray by this amount.
float stepSize = 1.0f / (float)numSamples;
// Initialize the starting view ray height and the texture offsets.
float currentRayHeight = 1.0f;
float2 lastOffset = float2(0.0f, 0.0f);
float lastSampledHeight = 1.0f;
float currentSampledHeight = 1.0f;
#ifdef _VIRTUALTEXTURING_ON
VirtualCoord vcoord = s.baseVirtualCoord;
#else
// Calculate the texture coordinate partial derivatives in screen
// space for the tex2Dgrad texture sampling instruction.
float2 dx = ddx(s.baseUv);
float2 dy = ddy(s.baseUv);
#endif
while (currentSample < numSamples) {
#ifdef _VIRTUALTEXTURING_ON
vcoord = VTUpdateVirtualCoord(vcoord, s.baseUv + offset);
currentSampledHeight = VTSampleNormal(vcoord).b;
#else
// Sample the heightmap at the current texcoord offset.
currentSampledHeight = tex2Dgrad(_ParallaxMap, s.baseUv + offset, dx, dy).y;
#endif
// Test if the view ray has intersected the surface.
UNITY_BRANCH
if (currentSampledHeight > currentRayHeight) {
// Find the relative height delta before and after the intersection.
// This provides a measure of how close the intersection is to
// the final sample location.
float delta1 = currentSampledHeight - currentRayHeight;
float delta2 = (currentRayHeight + stepSize) - lastSampledHeight;
float ratio = delta1 / (delta1 + delta2);
// Interpolate between the final two segments to
// find the true intersection point offset.
offset = lerp(offset, lastOffset, ratio);
// Force the exit of the while loop
currentSample = numSamples + 1;
}
else {
// The intersection was not found. Now set up the loop for the next
// iteration by incrementing the sample count,
currentSample++;
// take the next view ray height step,
currentRayHeight -= stepSize;
// save the current texture coordinate offset and increment
// to the next sample location,
lastOffset = offset;
offset += stepSize * maxOffset;
// and finally save the current heightmap height.
lastSampledHeight = currentSampledHeight;
}
}
aParallaxOffset(s, offset);
#endif
}
#endif // ALLOY_SHADERS_FRAMEWORK_FEATURE_IMPL_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1e933ac91f881374f8971a009670b12c
timeCreated: 1473016974
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,648 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Forward.cginc
/// @brief Forward passes uber-header.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_FORWARD_CGINC
#define ALLOY_SHADERS_FRAMEWORK_FORWARD_CGINC
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Framework/FeatureImpl.cginc"
#include "Assets/Alloy/Shaders/Framework/LightingImpl.cginc"
#include "Assets/Alloy/Shaders/Framework/TypeImpl.cginc"
#include "Assets/Alloy/Shaders/Framework/Unity.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "AutoLight.cginc"
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "UnityGlobalIllumination.cginc"
#include "UnityImageBasedLighting.cginc"
#include "UnityInstancing.cginc"
#include "UnityLightingCommon.cginc"
#include "UnityShaderUtilities.cginc"
#include "UnityShaderVariables.cginc"
#include "UnityShadowLibrary.cginc"
#include "UnityStandardUtils.cginc"
// Support for two-sided effects in a single pass.
#ifndef A_TWO_SIDED_SHADER
#define A_FACING_SIGN_PARAM
#define A_FACING_SIGN 1.0h
#else
#define A_FACING_SIGN_PARAM ,half facingSign : VFACE
#define A_FACING_SIGN facingSign
#endif
// Shadows.
#if defined(SHADOWS_SCREEN) && !defined(UNITY_NO_SCREENSPACE_SHADOWS)
#define A_SCREENSPACE_SHADOWS_ON
#endif
// Lightmaps.
#if !defined(A_UV2_ON) && defined(DYNAMICLIGHTMAP_ON) && defined(A_INDIRECT_ON)
#define A_UV2_ON
#endif
#if defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
#define A_LIGHTMAP_SHADOW_MIXING_ON
#endif
// Lighting vertex data.
#if defined(A_INDIRECT_ON) && defined(A_DIRECT_ON)
#define A_FORWARD_TEXCOORD0 half4 giData : TEXCOORD0;
#define A_FORWARD_TEXCOORD1 UNITY_SHADOW_COORDS(1)
#elif defined(A_INDIRECT_ON)
#define A_FORWARD_TEXCOORD0 half4 giData : TEXCOORD0;
#ifdef A_SHADOW_MASKS_BUFFER_ON
#define A_FORWARD_TEXCOORD1 UNITY_SHADOW_COORDS(1)
#endif
#elif defined(A_DIRECT_ON)
#define A_FORWARD_TEXCOORD0 UNITY_SHADOW_COORDS(0)
// Reduce v2f transfer cost for pure directional lights.
#if !defined(DIRECTIONAL) && !defined(A_LIGHTMAP_SHADOW_MIXING_ON)
#define A_FORWARD_TEXCOORD1 unityShadowCoord4 lightCoord : TEXCOORD1;
#ifndef USING_DIRECTIONAL_LIGHT
#define A_FORWARD_TEXCOORD2 float4 lightVectorRange : TEXCOORD2;
#endif
#endif
#endif
// Handle dependencies between vertex data.
#if !defined(A_TANGENT_ON) && defined(A_TANGENT_TO_WORLD_ON)
#define A_TANGENT_ON
#endif
#if !defined(A_NORMAL_WORLD_ON) && (defined(A_TANGENT_TO_WORLD_ON) || defined(A_REFLECTION_VECTOR_WORLD_ON))
#define A_NORMAL_WORLD_ON
#endif
#if !defined(A_VIEW_DIR_WORLD_ON) && (defined(A_VIEW_DIR_TANGENT_ON) || defined(A_REFLECTION_VECTOR_WORLD_ON))
#define A_VIEW_DIR_WORLD_ON
#endif
#if !defined(A_POSITION_WORLD_ON) && defined(A_VIEW_DIR_WORLD_ON)
#define A_POSITION_WORLD_ON
#endif
#if !defined(A_SCREEN_UV_ON) && defined(LOD_FADE_CROSSFADE)
#define A_SCREEN_UV_ON
#endif
// Enable specific packed texcoord channels.
#if !defined(A_POSITION_TEXCOORD_ON) && (defined(A_POSITION_WORLD_ON) || defined(A_VIEW_DEPTH_ON))
#define A_POSITION_TEXCOORD_ON
#endif
#if !defined(A_FOG_TEXCOORD_ON) && (defined(A_FOG_ON) || defined(A_SCREEN_UV_ON))
#define A_FOG_TEXCOORD_ON
#endif
#if !defined(A_TRANSFER_INSTANCE_ID_ON) && defined(A_WORLD_TO_OBJECT_ON) && defined(A_INSTANCING_PASS)
#define A_TRANSFER_INSTANCE_ID_ON
#endif
// Split vertex data conditions to reduce combinations.
// UV0-1, TBN, N.
#if defined(A_TANGENT_TO_WORLD_ON)
#define A_INNER_VERTEX_DATA2(A, B, C, D) \
float4 texcoords : TEXCOORD##A; \
half3 tangentWorld : TEXCOORD##B; \
half3 bitangentWorld : TEXCOORD##C; \
half3 normalWorld : TEXCOORD##D;
#elif defined(A_NORMAL_WORLD_ON)
#define A_INNER_VERTEX_DATA2(A, B, C, D) \
float4 texcoords : TEXCOORD##A; \
half3 normalWorld : TEXCOORD##B;
#else
#define A_INNER_VERTEX_DATA2(A, B, C, D) \
float4 texcoords : TEXCOORD##A;
#endif
// Vertex Color, Position, View Depth, Fog, and Screen UV.
#if defined(A_POSITION_TEXCOORD_ON) && defined(A_FOG_TEXCOORD_ON)
#define A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) \
half4 color : TEXCOORD##A; \
float4 positionWorldAndViewDepth : TEXCOORD##B; \
UNITY_FOG_COORDS_PACKED(C, half4) \
A_INNER_VERTEX_DATA2(D, E, F, G)
#elif defined(A_POSITION_TEXCOORD_ON)
#define A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) \
half4 color : TEXCOORD##A; \
float4 positionWorldAndViewDepth : TEXCOORD##B; \
A_INNER_VERTEX_DATA2(C, D, E, F)
#elif defined(A_FOG_TEXCOORD_ON)
#define A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) \
half4 color : TEXCOORD##A; \
UNITY_FOG_COORDS_PACKED(C, half4) \
A_INNER_VERTEX_DATA2(D, E, F, G)
#else
#define A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) \
half4 color : TEXCOORD##A; \
A_INNER_VERTEX_DATA2(B, C, D, E)
#endif
// Instancing.
#if defined(A_TRANSFER_INSTANCE_ID_ON) && defined(A_STEREO_INSTANCING_PASS)
#define A_INSTANCING_VERTEX_DATA(A, B, C, D, E, F, G) A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO
#elif defined(A_TRANSFER_INSTANCE_ID_ON)
#define A_INSTANCING_VERTEX_DATA(A, B, C, D, E, F, G) A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) UNITY_VERTEX_INPUT_INSTANCE_ID
#elif defined(A_STEREO_INSTANCING_PASS)
#define A_INSTANCING_VERTEX_DATA(A, B, C, D, E, F, G) A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G) UNITY_VERTEX_OUTPUT_STEREO
#else
#define A_INSTANCING_VERTEX_DATA(A, B, C, D, E, F, G) A_INNER_VERTEX_DATA1(A, B, C, D, E, F, G)
#endif
// Surface shader off.
#if defined(A_SURFACE_SHADER_OFF)
#define A_VERTEX_DATA(A, B, C, D, E, F, G)
#else
#define A_VERTEX_DATA(A, B, C, D, E, F, G) A_INSTANCING_VERTEX_DATA(A, B, C, D, E, F, G)
#endif
/// Configurable vertex input data from the application.
struct AVertexInput
{
float4 vertex : POSITION;
float4 uv0 : TEXCOORD0;
float4 uv1 : TEXCOORD1;
half3 normal : NORMAL;
#ifdef A_UV2_ON
float4 uv2 : TEXCOORD2;
#endif
#ifdef A_UV3_ON
float4 uv3 : TEXCOORD3;
#endif
#ifdef A_TANGENT_ON
half4 tangent : TANGENT;
#endif
half4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
/// Extensible fragment input data.
struct AFragmentInput {
#if defined(A_FORWARD_TEXCOORD0) && defined(A_FORWARD_TEXCOORD1) && defined(A_FORWARD_TEXCOORD2)
A_FORWARD_TEXCOORD0
A_FORWARD_TEXCOORD1
A_FORWARD_TEXCOORD2
A_VERTEX_DATA(3, 4, 5, 6, 7, 8, 9)
#elif defined(A_FORWARD_TEXCOORD0) && defined(A_FORWARD_TEXCOORD1)
A_FORWARD_TEXCOORD0
A_FORWARD_TEXCOORD1
A_VERTEX_DATA(2, 3, 4, 5, 6, 7, 8)
#elif defined(A_FORWARD_TEXCOORD0)
A_FORWARD_TEXCOORD0
A_VERTEX_DATA(1, 2, 3, 4, 5, 6, 7)
#else
A_VERTEX_DATA(0, 1, 2, 3, 4, 5, 6)
#endif
};
// TODO: Find a way to move this dependency!
#include "Assets/Alloy/Shaders/Framework/Tessellation.cginc"
/// Transfers the per-vertex lightmapping or SH data to the fragment shader.
/// @param[in,out] i Vertex to fragment transfer data.
/// @param[in] v Vertex input data.
void aVertexGi(
inout AFragmentInput i,
AVertexInput v)
{
#ifdef A_INDIRECT_ON
#ifdef LIGHTMAP_ON
i.giData.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
i.giData.zw = 0.0h;
#elif UNITY_SHOULD_SAMPLE_SH
// Add approximated illumination from non-important point lights
half3 normalWorld = i.normalWorld.xyz;
#ifdef VERTEXLIGHT_ON
i.giData.rgb = aShade4PointLights(i.positionWorldAndViewDepth.xyz, normalWorld);
#endif
i.giData.rgb = ShadeSHPerVertex(normalWorld, i.giData.rgb);
#endif
#ifdef DYNAMICLIGHTMAP_ON
i.giData.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#endif
#endif
}
/// Populates a UnityGI descriptor in the fragment shader.
/// @param i Vertex to fragment transfer data.
/// @param s Material surface data.
/// @param shadow Forward Base directional light shadow.
/// @return Initialized UnityGI descriptor.
UnityGI aFragmentGi(
AFragmentInput i,
ASurface s,
half shadow)
{
UnityGI gi;
UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
#ifdef A_INDIRECT_ON
UnityGIInput d;
UNITY_INITIALIZE_OUTPUT(UnityGIInput, d);
d.worldPos = s.positionWorld;
d.worldViewDir = s.viewDirWorld; // ???
d.atten = shadow;
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
d.ambient = 0;
d.lightmapUV = i.giData;
#else
d.ambient = i.giData.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
// So we can extract shadow with baked occlusion.
#ifdef HANDLE_SHADOWS_BLENDING_IN_GI
d.light.color = A_WHITE;
#endif
// Pass 1.0 for occlusion so we can apply it later in indirect().
gi = UnityGI_Base(d, 1.0h, s.ambientNormalWorld);
#ifdef A_REFLECTION_PROBES_ON
Unity_GlossyEnvironmentData g;
g.reflUVW = s.reflectionVectorWorld;
g.roughness = s.roughness;
gi.indirect.specular = UnityGI_IndirectSpecular(d, 1.0h, s.normalWorld, g);
#endif
#endif
return gi;
}
/// Transforms the vertex data before transferring it to the pixel shader.
/// @param[in,out] v Vertex input data.
/// @param[out] o Vertex to fragment transfer data.
/// @param[out] opos Clip space position.
void aForwardVertexShader(
inout AVertexInput v,
out AFragmentInput o,
out float4 opos)
{
#ifdef A_SURFACE_SHADER_OFF
opos = 0.0h;
#else
UNITY_INITIALIZE_OUTPUT(AFragmentInput, o);
#ifdef A_INSTANCING_PASS
UNITY_SETUP_INSTANCE_ID(v);
#ifdef A_TRANSFER_INSTANCE_ID_ON
UNITY_TRANSFER_INSTANCE_ID(v, o);
#endif
#ifdef A_STEREO_INSTANCING_PASS
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
#endif
#endif
// Copy vertex data, and let shader type modify it.
AVertex vs = aNewVertex();
vs.positionObject = v.vertex;
vs.uv0 = v.uv0;
vs.uv1 = v.uv1;
vs.normalObject = v.normal;
#ifdef A_UV2_ON
vs.uv2 = v.uv2;
#endif
#ifdef A_UV3_ON
vs.uv3 = v.uv3;
#endif
#ifdef A_TANGENT_ON
vs.tangentObject = v.tangent;
#endif
vs.color = v.color;
aVertexShader(vs);
// Copy data back into original, in case outer shader needs it.
v.vertex = vs.positionObject;
v.uv0 = vs.uv0;
v.uv1 = vs.uv1;
v.normal = vs.normalObject;
#ifdef A_UV2_ON
v.uv2 = vs.uv2;
#endif
#ifdef A_UV3_ON
v.uv3 = vs.uv3;
#endif
#ifdef A_TANGENT_ON
v.tangent = vs.tangentObject;
#endif
v.color = vs.color;
// Fill V2F.
o.color = v.color; // Gamma-space vertex color, unless modified.
o.texcoords.xy = v.uv0.xy;
o.texcoords.zw = v.uv1.xy;
opos = UnityObjectToClipPos(v.vertex.xyz);
#ifdef A_POSITION_TEXCOORD_ON
#ifdef A_POSITION_WORLD_ON
o.positionWorldAndViewDepth.xyz = mul(unity_ObjectToWorld, v.vertex).xyz;
#endif
#ifdef A_VIEW_DEPTH_ON
COMPUTE_EYEDEPTH(o.positionWorldAndViewDepth.w);
#endif
#endif
#ifdef A_NORMAL_WORLD_ON
float3 normalWorld = UnityObjectToWorldNormal(v.normal);
#endif
#ifndef A_TANGENT_TO_WORLD_ON
#ifdef A_NORMAL_WORLD_ON
o.normalWorld = normalWorld;
#endif
#else
float3 tangentWorld = UnityObjectToWorldDir(v.tangent.xyz);
float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld, v.tangent.w);
o.tangentWorld = tangentToWorld[0];
o.bitangentWorld = tangentToWorld[1];
o.normalWorld = tangentToWorld[2];
#endif
#if defined(A_SCREEN_UV_ON) || (defined(A_DIRECT_ON) && defined(A_SCREENSPACE_SHADOWS_ON))
float4 screenPos = ComputeScreenPos(opos);
#endif
// Fog and Screen UV.
#ifdef A_FOG_TEXCOORD_ON
#ifdef A_SCREEN_UV_ON
o.fogCoord.yzw = screenPos.xyw;
#else
o.fogCoord.yzw = A_AXIS_Z;
#endif
#ifdef A_FOG_ON
UNITY_TRANSFER_FOG(o, opos);
#endif
#endif
// Lighting data.
aVertexGi(o, v);
#ifdef A_DIRECT_ON
// NOTE: Custom macro to skip calculations and remove dependency on o.pos!
#ifdef A_SCREENSPACE_SHADOWS_ON
o._ShadowCoord = screenPos;
#else
UNITY_TRANSFER_SHADOW(o, v.uv1);
#endif
#if !defined(DIRECTIONAL) && !defined(A_LIGHTMAP_SHADOW_MIXING_ON)
o.lightCoord = mul(unity_WorldToLight, unityShadowCoord4(o.positionWorldAndViewDepth.xyz, 1.0f));
#ifndef USING_DIRECTIONAL_LIGHT
o.lightVectorRange = UnityWorldSpaceLightDir(o.positionWorldAndViewDepth.xyz).xyzz;
aLightRange(o.lightVectorRange, o.lightCoord);
#endif
#endif
#endif
#endif
}
/// Create a surface populated with material data.
/// @param i Vertex to fragment transfer data.
/// @param facingSign Sign of front/back facing direction.
/// @return Initialized surface data object.
ASurface aForwardSurface(
AFragmentInput i,
half facingSign)
{
ASurface s = aNewSurface();
#ifndef A_SURFACE_SHADER_OFF
#ifdef A_TRANSFER_INSTANCE_ID_ON
UNITY_SETUP_INSTANCE_ID(i);
#endif
s.uv01 = i.texcoords;
s.vertexColor = i.color;
s.facingSign = facingSign;
#ifdef A_POSITION_TEXCOORD_ON
#ifdef A_POSITION_WORLD_ON
s.positionWorld = i.positionWorldAndViewDepth.xyz;
#endif
#ifdef A_VIEW_DEPTH_ON
s.viewDepth = i.positionWorldAndViewDepth.w;
#endif
#endif
#ifdef A_NORMAL_WORLD_ON
#ifdef A_TWO_SIDED_SHADER
i.normalWorld.xyz *= facingSign;
#endif
// Give these sane defaults in case the surface shader doesn't set them.
s.vertexNormalWorld = normalize(i.normalWorld);
s.normalWorld = s.vertexNormalWorld;
s.ambientNormalWorld = s.vertexNormalWorld;
#endif
#ifdef A_VIEW_DIR_WORLD_ON
// Cheaper to calculate in PS than to unpack from vertex, while also
// preventing distortion in POM and area light specular highlights.
s.viewDirWorld = normalize(UnityWorldSpaceViewDir(s.positionWorld));
#endif
#ifdef A_TANGENT_TO_WORLD_ON
half3 t = i.tangentWorld;
half3 b = i.bitangentWorld;
half3 n = i.normalWorld;
#if UNITY_TANGENT_ORTHONORMALIZE
n = normalize(n);
// ortho-normalize Tangent
t = normalize (t - n * dot(t, n));
// recalculate Binormal
half3 newB = cross(n, t);
b = newB * sign (dot (newB, b));
#endif
s.tangentToWorld = half3x3(t, b, n);
#if defined(A_VIEW_DIR_WORLD_ON) && defined(A_VIEW_DIR_TANGENT_ON)
s.viewDirTangent = normalize(mul(s.tangentToWorld, s.viewDirWorld));
#endif
#endif
#ifdef A_FOG_TEXCOORD_ON
#ifdef A_FOG_ON
s.fogCoord = i.fogCoord;
#endif
#ifdef A_SCREEN_UV_ON
s.screenPosition.xyw = i.fogCoord.yzw;
s.screenPosition.z = 0.0h;
s.screenUv.xy = s.screenPosition.xy / s.screenPosition.w;
#ifdef LOD_FADE_CROSSFADE
half2 projUV = s.screenUv.xy * _ScreenParams.xy * 0.25h;
projUV.y = frac(projUV.y) * 0.0625h /* 1/16 */ + unity_LODFade.y; // quantized lod fade by 16 levels
clip(tex2D(_DitherMaskLOD2D, projUV).a - 0.5f);
#endif
#endif
#endif
// Runs the shader and lighting type's surface code.
aBaseUvInit(s);
aUpdateViewData(s);
aSurfaceShader(s);
aPreLighting(s);
#endif
return s;
}
/// Final processing of the forward color before output.
/// @param s Material surface data.
/// @param color Lighting + Emission + Fog + etc.
/// @return Final HDR output color with alpha opacity.
half4 aForwardColor(
ASurface s,
half3 color)
{
half4 output;
#if defined(A_ALPHA_BLENDING_PASS) && defined(A_ALPHA_BLENDING_ON)
output.a = s.opacity;
#else
UNITY_OPAQUE_ALPHA(output.a);
#endif
output.rgb = color;
aColorShader(output, s);
return aHdrClamp(output);
}
/// Calculates forward lighting from surface and vertex data.
/// @param i Vertex to fragment transfer data.
/// @param facingSign Sign of front/back facing direction.
/// @return Forward direct and indirect lighting.
half4 aForwardLitColorShader(
AFragmentInput i,
half facingSign)
{
half3 illum = 0.0h;
ASurface s = aForwardSurface(i, facingSign);
#ifdef A_LIGHTING_ON
half shadow = UNITY_SHADOW_ATTENUATION(i, s.positionWorld);
#ifdef A_INDIRECT_ON
UnityGI gi = aFragmentGi(i, s, shadow);
illum = aUnityIndirectLighting(gi, s);
// Extract shadow with combined baked occlusion.
#ifdef HANDLE_SHADOWS_BLENDING_IN_GI
shadow = gi.light.color.g;
#endif
#endif
// Do lightmap shadow mixing guard here, since we need direct vertex data.
#if defined(A_DIRECT_ON) && !defined(A_LIGHTMAP_SHADOW_MIXING_ON)
// Reduce v2f transfer cost for pure directional lights.
#if defined(DIRECTIONAL)
illum += aUnityDirectLighting(s, shadow, _WorldSpaceLightPos0, A_ZERO4);
#elif defined(DIRECTIONAL_COOKIE)
illum += aUnityDirectLighting(s, shadow, _WorldSpaceLightPos0, i.lightCoord);
#else
illum += aUnityDirectLighting(s, shadow, i.lightVectorRange, i.lightCoord);
#endif
#endif
#endif
#if defined(A_BASE_PASS) && defined(A_EMISSIVE_COLOR_ON)
illum += s.emissiveColor;
#endif
return aForwardColor(s, illum);
}
/// Creates a G-Buffer from the provided surface data.
/// @param i Vertex to fragment transfer data.
/// @param facingSign Sign of front/back facing direction.
/// @return G-buffer with surface data and ambient illumination.
AGbuffer aForwardLitGbufferShader(
AFragmentInput i,
half facingSign)
{
half3 illum = 0.0h;
AGbuffer gb = aNewGbuffer();
ASurface s = aForwardSurface(i, facingSign);
#ifdef A_INDIRECT_ON
illum += aUnityIndirectLighting(aFragmentGi(i, s, 1.0h), s);
// Baked direct lighting occlusion if any.
#ifdef A_SHADOW_MASKS_BUFFER_ON
gb.shadowMasks = UnityGetRawBakedOcclusions(i.giData.xy, s.positionWorld);
#endif
#endif
#ifdef A_EMISSIVE_COLOR_ON
illum += s.emissiveColor;
#endif
#if defined(A_INDIRECT_ON) || defined(A_EMISSIVE_COLOR_ON)
illum = aHdrClamp(illum);
#endif
#ifndef UNITY_HDR_ON
illum = exp2(-illum);
#endif
gb.diffuseOcclusion = half4(s.albedo, s.specularOcclusion);
gb.specularSmoothness = half4(s.f0, 1.0h - s.roughness);
gb.normalType = half4(s.normalWorld * 0.5h + 0.5h, s.materialType);
gb.emissionSubsurface = half4(illum, s.subsurface);
aGbufferShader(gb, s);
return gb;
}
#endif // ALLOY_SHADERS_FRAMEWORK_FORWARD_CGINC
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: d38ced127b82dbc4ba0d177f21160d88
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
@@ -0,0 +1,531 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file Lighting.cginc
/// @brief Lighting uber-header.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_LIGHTING_CGINC
#define ALLOY_SHADERS_FRAMEWORK_LIGHTING_CGINC
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "UnityLightingCommon.cginc"
#ifndef A_SURFACE_CUSTOM_FIELDS
#define A_SURFACE_CUSTOM_FIELDS
#endif
/// Tangent-space normal assignment and update of associated fields.
#define A_NT(s, n) n; aUpdateNormalTangent(s)
/// World-space normal assignment and update of associated fields.
#define A_NW(s, n) n; aUpdateNormalWorld(s)
/// Subsurface assignment and update of associated fields.
#define A_SS(s, ss) ss; aUpdateSubsurface(s)
/// Subsurface color assignment and update of associated fields.
#define A_SSC(s, ssc) ssc; aUpdateSubsurfaceColor(s)
// Use Unity's struct directly to avoid copying since the fields are the same.
#define AIndirect UnityIndirect
/// Collection of direct illumination data.
struct ADirect {
/////////////////////////////////////////////////////////////////////////////
// Material lighting.
/////////////////////////////////////////////////////////////////////////////
/// Light color, attenuation, and cookies.
/// Expects linear-space HDR color values.
half3 color;
/// Shadowing.
/// Expects values in the range [0,1].
half shadow;
/// Specular highlight intensity.
/// Expects values in the range [0,n].
half specularIntensity;
/// Light direction in world-space.
/// Expects normalized vectors.
half3 direction;
/// Direction halfway between the light and view vectors in world space.
/// Expects normalized vectors.
half3 halfAngleWorld;
/// Clamped L.H.
/// Expects values in the range [0,1].
half LdotH;
/// Clamped N.H.
/// Expects values in the range [0,1].
half NdotH;
/// Clamped N.L.
/// Expects values in the range [0,1].
half NdotL;
/// Unclamped N.L.
/// Expects values in the range [0,1].
half NdotLm;
/////////////////////////////////////////////////////////////////////////////
// Internal.
/////////////////////////////////////////////////////////////////////////////
/// Diffuse area light vector.
/// Expects a non-normalized vector.
float3 Ldiff;
/// Specular area light vector.
/// Expects a non-normalized vector.
float3 Lspec;
/// One over the distance to the center of the light volume.
/// Expects values in the range [0,n).
half centerDistInverse;
};
/// Contains ALL data and state for rendering a surface.
/// Can set state to control how features are combined into the surface data.
struct ASurface {
/////////////////////////////////////////////////////////////////////////////
// Vertex inputs.
/////////////////////////////////////////////////////////////////////////////
/// Screen-space position.
float4 screenPosition;
/// Screen-space texture coordinates.
float2 screenUv;
/// Position in world space.
float3 positionWorld;
/// View direction in world space.
/// Expects a normalized vector.
half3 viewDirWorld;
/// Distance from the camera to the given fragement.
/// Expects values in the range [0,n].
half viewDepth;
/// Unity's fog data.
float fogCoord;
/// Tangent space to World space rotation matrix.
half3x3 tangentToWorld;
/// View direction in tangent space.
/// Expects a normalized vector.
half3 viewDirTangent;
/// Vertex color.
/// Expects linear-space LDR color values.
half4 vertexColor;
/// Vertex normal in world space.
/// Expects normalized vectors.
half3 vertexNormalWorld;
/// Indicates via sign whether a triangle is front or back facing.
/// Positive is front-facing, negative is back-facing.
half facingSign;
/////////////////////////////////////////////////////////////////////////////
// Feature layering inputs.
/////////////////////////////////////////////////////////////////////////////
/// Masks where the next feature layer will be applied.
/// Expects values in the range [0,1].
half mask;
/// The base map's texture transform tiling amount.
float2 baseTiling;
/// Transformed texture coordinates for the base map.
float2 baseUv;
#ifdef _VIRTUALTEXTURING_ON
/// Transformed texture coordinates for the virtual base map.
VirtualCoord baseVirtualCoord;
#endif
/// The model's UV0 & UV1 texture coordinate data.
/// Be aware that it can have parallax precombined with it.
float4 uv01;
/////////////////////////////////////////////////////////////////////////////
// Surface inputs.
/////////////////////////////////////////////////////////////////////////////
/// Albedo and/or Metallic f0 based on settings. Used by Enlighten.
/// Expects linear-space LDR color values.
half3 baseColor;
/// Controls opacity or cutout regions.
/// Expects values in the range [0,1].
half opacity;
/// Interpolates material from dielectric to metal.
/// Expects values in the range [0,1].
half metallic;
/// Diffuse ambient occlusion.
/// Expects values in the range [0,1].
half ambientOcclusion;
/// Linear control of dielectric f0 from [0.00,0.08].
/// Expects values in the range [0,1].
half specularity;
/// Tints the dielectric specularity by the base color chromaticity.
/// Expects values in the range [0,1].
half specularTint;
/// Linear roughness value, where zero is smooth and one is rough.
/// Expects values in the range [0,1].
half roughness;
/// Light emission by the material.
/// Expects linear-space HDR color values.
half3 emissiveColor;
/// Color tint for transmission effect.
/// Expects linear-space LDR color values.
half3 subsurfaceColor;
/// Monochrome transmission thickness.
/// Expects gamma-space LDR values.
half subsurface;
/// Strength of clearcoat layer, used to apply masks.
/// Expects values in the range [0,1].
half clearCoat;
/// Roughness of clearcoat layer.
/// Expects values in the range [0,1].
half clearCoatRoughness;
/// Normal in world space.
/// Expects a normalized vector.
half3 normalWorld;
/// Normal in tangent space.
/// Expects a normalized vector.
half3 normalTangent;
/// Blurred normal in tangent space.
/// Expects a normalized vector.
half3 blurredNormalTangent;
/////////////////////////////////////////////////////////////////////////////
// BRDF inputs.
/////////////////////////////////////////////////////////////////////////////
/// Diffuse albedo.
/// Expects linear-space LDR color values.
half3 albedo;
/// Fresnel reflectance at incidence zero.
/// Expects linear-space LDR color values.
half3 f0;
/// Beckmann roughness.
/// Expects values in the range [0,1].
half beckmannRoughness;
/// Specular occlusion.
/// Expects values in the range [0,1].
half specularOcclusion;
/// Ambient diffuse normal in world space.
/// Expects normalized vectors.
half3 ambientNormalWorld;
/// View reflection vector in world space.
/// Expects a non-normalized vector.
half3 reflectionVectorWorld;
/// Clamped N.V.
/// Expects values in the range [0,1].
half NdotV;
/// Fresnel weight of N.V.
/// Expects values in the range [0,1].
half FV;
/// Deferred material lighting type.
/// Expects the values 0, 1/3, 2/3, or 1.
half materialType;
A_SURFACE_CUSTOM_FIELDS
half _skinScatteringMask;
half _skinScattering;
half _subsurfaceShadowWeight;
};
/// Maximum linear-space non-metal specular reflectivity.
static const half A_MAX_DIELECTRIC_F0 = 0.08h;
/// Minimum roughness that won't cause specular artifacts.
static const half A_MIN_AREA_ROUGHNESS = 0.05h;
/// Front-faces cull mode.
static const half A_CULL_MODE_FRONT = 1.0h;
/// Opaque shading type.
static const half A_MATERIAL_TYPE_OPAQUE = 1.0h;
/// Shadowed subsurface transmission shading type.
static const half A_MATERIAL_TYPE_SHADOWED_SUBSURFACE = 2.0h / 3.0h;
/// Unshadowed subsurface transmission shading type.
static const half A_MATERIAL_TYPE_UNSHADOWED_SUBSURFACE = 1.0h / 3.0h;
/// Subsurface scattering shading type.
static const half A_MATERIAL_TYPE_SUBSURFACE_SCATTERING = 0.0h;
#ifdef A_DEFERRED_PASS
/// RGB=Blurred normals, A=Subsurface thickness.
/// Expects value in the buffer alpha.
sampler2D _DeferredPlusBuffer;
#endif
#ifdef A_FORWARD_ONLY_SHADER
/// Pre-Integrated scattering LUT.
sampler2D _SssBrdfTex;
/// Weight of the scattering effect.
/// Expects values in the range [0,1].
half _SssWeight;
/// Cutoff value used to convert tranmission data to scattering mask.
/// Expects values in the range [0.01,1].
half _SssMaskCutoff;
/// Biases the thickness value used to look up in the skin LUT.
/// Expects values in the range [0,1].
half _SssBias;
/// Scales the thickness value used to look up in the skin LUT.
/// Expects values in the range [0,1].
half _SssScale;
/// Increases the bluriness of the normal map for diffuse lighting.
/// Expects values in the range [0,1].
half _SssBumpBlur;
/// Per-channel weights for thickness-based subsurface color absorption.
half3 _SssTransmissionAbsorption;
/// Per-channel RGB gamma weights for colored AO.
/// Expects a vector of non-zero values.
half3 _SssColorBleedAoWeights;
/// Weight of the subsurface effect.
/// Expects linear-space values in the range [0,1].
half _TransWeight;
#else
/// Pre-Integrated scattering LUT.
sampler2D _DeferredSkinLut;
/// X=Scattering Weight, Y=1/Mask Cutoff, Z=Blur Weight.
/// Expects a vector of non-zero values.
half3 _DeferredSkinParams;
/// Per-channel weights for thickness-based subsurface color absorption.
/// LUT Bias in alpha.
half4 _DeferredSkinTransmissionAbsorption;
/// Per-channel RGB gamma weights for colored AO. LUT Scale in alpha.
/// Expects a vector of non-zero values.
half4 _DeferredSkinColorBleedAoWeights;
#endif
/// The current culling mode for transmission shadows.
float _ShadowCullMode;
#ifdef A_FORWARD_ONLY_SHADER
/// Shadow influence on the subsurface effect.
/// Expects values in the range [0,1].
half _TransShadowWeight;
/// Amount that the subsurface is distorted by surface normals.
/// Expects values in the range [0,1].
half _TransDistortion;
/// Falloff of the subsurface effect.
/// Expects values in the range [1,n).
half _TransPower;
#else
/// X=Linear Weight, Y=Falloff, Z=Bump Distortion, W=Shadow Weight.
/// Expects a vector of non-zero values.
half4 _DeferredTransmissionParams;
#endif
/// Abstract declaration for user-defined pre-lighting callback.
void aPreLighting(inout ASurface s);
/// Abstract declaration for user-defined direct lighting callback.
half3 aDirectLighting(ADirect d, ASurface s);
/// Abstract declaration for user-defined indirect lighting callback.
half3 aIndirectLighting(AIndirect i, ASurface s);
/// Indirect lighting data constructor.
AIndirect aNewIndirect();
/// Direct lighting data constructor.
ADirect aNewDirect();
/// Applies light cookie to description.
/// @param[in,out] d Direct lighting data.
/// @param[in] cookie Cookie map sample.
void aLightCookie(inout ADirect d, half4 cookie);
/// Light range limit falloff.
/// @param[in,out] d Direct lighting data.
/// @param[in] range Light volume radius.
void aSetLightRangeLimit(inout ADirect d, half range);
/// Populates light with brdf dot products, except N.L.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
void aUpdateLightingInputs(inout ADirect d, ASurface s);
/// Populates specular lighting data for an area light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
/// @param[in] radius Area light radius.
void aSetAreaSpecularInputs(inout ADirect d, ASurface s, half radius);
/// Populates material lighting data for an area light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
/// @param[in] radius Area light radius.
/// @return One over area diffuse light vector length.
half aSetAreaLightingInputs(inout ADirect d, ASurface s, half radius);
/// Populates data for a directional light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
void aDirectionalLight(inout ADirect d, ASurface s);
/// Populates data for a directional light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
/// @param[in] direction Light normalized direction.
/// @param[in] radius Disc light radius.
void aDirectionalDiscLight(inout ADirect d, ASurface s, half3 direction, half radius);
/// Populates data for a sphere area light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
/// @param[in] L Vector to light center.
/// @param[in] radius Sphere light radius.
void aSphereLight(inout ADirect d, ASurface s, float3 L, half radius);
/// Populates data for a sphere area light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
/// @param[in] L Vector to light center.
/// @param[in] axis Tube light normalized axis direction.
/// @param[in] radius Tube light radius.
/// @param[in] halfLength Half the length of the tube light.
void aTubeLight(inout ADirect d, ASurface s, float3 L, half3 axis, half radius, half halfLength);
/// Populates data for an area light.
/// @param[in,out] d Direct lighting data.
/// @param[in] s Material surface data.
/// @param[in] color Light color, size weight in alpha. +/- sign.
/// @param[in] axis Tube light normalized axis direction.
/// @param[in] L Vector to light center.
/// @param[in] range Light bounding volume range.
void aAreaLight(inout ADirect d, ASurface s, half4 color, half3 axis, float3 L, half range);
/// Surface data constructor.
ASurface aNewSurface();
/// Sets the feature mask by using a gradient input mask.
/// @param[in,out] s Material surface data.
/// @param[in] mask Gradient where effect goes from black to white.
/// @param[in] weight Weight of the effect.
/// @param[in] cutoff Value below which the gradient becomes a mask.
/// @param[in] blendRange Range of smooth blend above cutoff.
/// @param[in] vertexTint Weight of vertex color alpha cutoff override.
void aBlendRangeMask(inout ASurface s, half mask, half weight, half cutoff, half blendRange, half vertexTint);
/// Transforms a normal from tangent-space to world-space.
half3 aTangentToWorld(ASurface s, half3 normalTangent);
/// Transforms a normal from world-space to tangent-space.
half3 aWorldToTangent(ASurface s, half3 normalWorld);
/// Calculates and sets normal and view-dependent data.
void aUpdateViewData(inout ASurface s);
/// Update values dependent on tangent-space normal.
void aUpdateNormalTangent(inout ASurface s);
/// Update values dependent on world-space normal.
void aUpdateNormalWorld(inout ASurface s);
/// Update values dependent on subsurface.
void aUpdateSubsurface(inout ASurface s);
/// Update values dependent on subsurface color.
void aUpdateSubsurfaceColor(inout ASurface s);
/// Calculates the fresnel at incidence zero from a normalized specularity.
/// @param specularity Normalized specularity [0,1].
/// @return F0 [0,0.08].
half3 aSpecularityToF0(half specularity);
/// Convert linear roughness to Beckmann roughness.
/// @param roughness Linear roughness [0,1].
/// @return Beckmann Roughness.
half aLinearToBeckmannRoughness(half roughness);
/// Blend weight portion of Schlick fresnel equation.
/// @param w Clamped dot product of two normalized vectors.
/// @return Fresnel blend weight.
half aFresnel(half w);
/// Switches off specular lighting per-pixel where surface f0 is black.
half3 aSpecularLightingToggle(ASurface s, half3 specular);
/// Calculates specular occlusion.
/// @param ao Linear ambient occlusion.
/// @param NdotV Normal and eye vector dot product [0,1].
/// @return Specular occlusion.
half aSpecularOcclusion(half ao, half NdotV);
/// Pre-calculate material data shared between direct & indirect lighting.
void aStandardPreLighting(inout ASurface s);
/// Calculate direct illumination from a light and a surface.
/// @param d Direct lighting data.
/// @param s Material surface data.
/// @return Direct illumination.
half3 aStandardDirectLighting(ADirect d, ASurface s);
/// Calculate indirect illumination from a light and a surface.
/// @param i Indirect lighting data.
/// @param s Material surface data.
/// @return Indirect illumination.
half3 aStandardIndirectLighting(AIndirect i, ASurface s);
#endif // ALLOY_SHADERS_FRAMEWORK_LIGHTING_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 315a77a44673cd540ad1ecad6d2f47be
timeCreated: 1437938893
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,761 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file LightingImpl.cginc
/// @brief Lighting method implementations to allow disabling of features.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_LIGHTING_IMPL_CGINC
#define ALLOY_SHADERS_FRAMEWORK_LIGHTING_IMPL_CGINC
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/Lighting.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "UnityShaderVariables.cginc"
#if !A_USE_UNITY_ATTENUATION || defined(USING_DIRECTIONAL_LIGHT)
#define A_UNITY_ATTENUATION(d, tex, lightCoord, scale)
#else
#define A_UNITY_ATTENUATION(d, tex, lightCoord, scale) d.color *= tex2D(tex, (dot(lightCoord, lightCoord) * scale).rr).UNITY_ATTEN_CHANNEL;
#endif
#if !defined(A_REFLECTION_PROBES_ON) && (!defined(A_GBUFFER_PASS) || !UNITY_ENABLE_REFLECTION_BUFFERS)
#define A_REFLECTION_PROBES_ON
#endif
// Lighting required vertex data flags.
#ifndef A_UNLIT_MODE
#ifdef A_DIRECT_LIGHTING_PASS
#define A_DIRECT_ON
#endif
#ifdef A_INDIRECT_LIGHTING_PASS
#define A_INDIRECT_ON
#endif
#if defined(A_DIRECT_ON) || defined(A_INDIRECT_ON)
#define A_LIGHTING_ON
#endif
#endif
#ifndef A_LIGHTING_ON
#if !defined(A_NORMAL_WORLD_ON) && defined(A_GBUFFER_PASS)
#define A_NORMAL_WORLD_ON
#endif
#else
#ifndef A_NORMAL_WORLD_ON
#define A_NORMAL_WORLD_ON
#endif
#ifndef A_VIEW_DIR_WORLD_ON
#define A_VIEW_DIR_WORLD_ON
#endif
#ifndef A_POSITION_WORLD_ON
#define A_POSITION_WORLD_ON
#endif
#if !defined(A_REFLECTION_VECTOR_WORLD_ON) && (defined(A_DIRECT_ON) || defined(A_REFLECTION_PROBES_ON))
#define A_REFLECTION_VECTOR_WORLD_ON
#endif
#endif
#if !defined(A_TANGENT_TO_WORLD_ON) && defined(A_NORMAL_MAPPED_PASS) && (defined(A_VIEW_DIR_TANGENT_ON) || defined(A_NORMAL_MAPPING_ON))
#define A_TANGENT_TO_WORLD_ON
#endif
#ifndef A_SCATTERING_ON
#define A_SKIN_SUBSURFACE_WEIGHT 1.0h
#else
#define A_SKIN_SUBSURFACE_WEIGHT _TransWeight
#ifdef A_FORWARD_ONLY_SHADER
#define A_SCATTERING_LUT _SssBrdfTex
#define A_SCATTERING_WEIGHT _SssWeight
#define A_SCATTERING_INV_MASK_CUTOFF 1.0h / _SssMaskCutoff
#define A_SCATTERING_BIAS _SssBias
#define A_SCATTERING_SCALE _SssScale
#define A_SCATTERING_NORMAL_BLUR _SssBumpBlur
#define A_SCATTERING_ABSORPTION _SssTransmissionAbsorption
#define A_SCATTERING_AO_COLOR_BLEED _SssColorBleedAoWeights
#else
#define A_SCATTERING_LUT _DeferredSkinLut
#define A_SCATTERING_WEIGHT _DeferredSkinParams.x
#define A_SCATTERING_INV_MASK_CUTOFF _DeferredSkinParams.y
#define A_SCATTERING_BIAS _DeferredSkinTransmissionAbsorption.w
#define A_SCATTERING_SCALE _DeferredSkinColorBleedAoWeights.w
#define A_SCATTERING_NORMAL_BLUR _DeferredSkinParams.z
#define A_SCATTERING_ABSORPTION _DeferredSkinTransmissionAbsorption.xyz
#define A_SCATTERING_AO_COLOR_BLEED _DeferredSkinColorBleedAoWeights.xyz
#endif
#endif
#ifdef A_SUBSURFACE_ON
#ifdef A_FORWARD_ONLY_SHADER
#define A_SUBSURFACE_WEIGHT A_SKIN_SUBSURFACE_WEIGHT
#define A_SUBSURFACE_FALLOFF _TransPower
#define A_SUBSURFACE_DISTORTION _TransDistortion
#define A_SUBSURFACE_SHADOW _TransShadowWeight
#else
#define A_SUBSURFACE_WEIGHT _DeferredTransmissionParams.x
#define A_SUBSURFACE_FALLOFF _DeferredTransmissionParams.y
#define A_SUBSURFACE_DISTORTION _DeferredTransmissionParams.z
#define A_SUBSURFACE_SHADOW _DeferredTransmissionParams.w
#endif
#endif
#if !A_USE_DEFERRED_MATERIAL_TYPE_BRANCHING || !defined(A_DEFERRED_PASS)
#define A_DEFERRED_BRANCH(CONDITION)
#else
#define A_DEFERRED_BRANCH(CONDITION) \
UNITY_BRANCH \
if (CONDITION)
#endif
AIndirect aNewIndirect() {
AIndirect i;
UNITY_INITIALIZE_OUTPUT(AIndirect, i);
i.diffuse = 0.0h;
i.specular = 0.0h;
return i;
}
ADirect aNewDirect()
{
ADirect d;
UNITY_INITIALIZE_OUTPUT(ADirect, d);
d.color = 0.0h;
d.shadow = 1.0h;
d.specularIntensity = 1.0h;
d.direction = A_AXIS_Y;
return d;
}
void aLightCookie(
inout ADirect d,
half4 cookie)
{
#if defined(UNITY_PASS_FORWARDBASE) || A_USE_UNITY_LIGHT_COOKIES
d.color *= cookie.a;
#else
d.color *= cookie.rgb * cookie.a;
#endif
}
void aSetLightRangeLimit(
inout ADirect d,
half range)
{
#if !A_USE_UNITY_ATTENUATION
// Light Range Limit Falloff.
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p12-13
half ratio = 1.0h / (range * d.centerDistInverse);
half ratio2 = ratio * ratio;
half num = saturate(1.0h - (ratio2 * ratio2));
d.color *= num * num;
#endif
}
void aUpdateLightingInputs(
inout ADirect d,
ASurface s)
{
d.halfAngleWorld = normalize(d.direction + s.viewDirWorld);
d.LdotH = aDotClamp(d.direction, d.halfAngleWorld);
d.NdotH = aDotClamp(s.normalWorld, d.halfAngleWorld);
}
void aSetAreaSpecularInputs(
inout ADirect d,
ASurface s,
half radius)
{
// Representative Point Area Lights.
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p14-16
#ifdef A_AREA_SPECULAR_OFF
d.direction = d.Ldiff;
#else
float3 R = s.reflectionVectorWorld;
float3 centerToRay = dot(d.Lspec, R) * R - d.Lspec;
float3 closestPoint = d.Lspec + centerToRay * saturate(radius * rsqrt(dot(centerToRay, centerToRay)));
half LspecLengthInverse = rsqrt(dot(closestPoint, closestPoint));
half a = s.beckmannRoughness;
half normalizationFactor = a / saturate(a + (radius * 0.5h * LspecLengthInverse));
d.direction = closestPoint * LspecLengthInverse;
d.specularIntensity = normalizationFactor * normalizationFactor;
#endif
aUpdateLightingInputs(d, s);
}
half aSetAreaLightingInputs(
inout ADirect d,
ASurface s,
half radius)
{
// Specular.
aSetAreaSpecularInputs(d, s, radius);
// Diffuse.
// Set diffuse light direction last to fix transmission & hair.
half LdiffLengthSquared = dot(d.Ldiff, d.Ldiff);
half LdiffLengthInverse = rsqrt(LdiffLengthSquared);
d.direction = d.Ldiff * LdiffLengthInverse;
d.NdotLm = dot(s.normalWorld, d.direction);
d.NdotL = saturate(d.NdotLm);
#if !A_USE_UNITY_ATTENUATION
d.color /= (LdiffLengthSquared + 1.0h); // Attenuation.
#endif
return LdiffLengthInverse;
}
void aDirectionalLight(
inout ADirect d,
ASurface s)
{
d.NdotLm = dot(s.normalWorld, d.direction);
d.NdotL = saturate(d.NdotLm);
aUpdateLightingInputs(d, s);
}
void aDirectionalDiscLight(
inout ADirect d,
ASurface s,
half3 direction,
half radius)
{
d.Ldiff = direction;
d.Lspec = direction;
// Specular.
aSetAreaSpecularInputs(d, s, radius);
// Diffuse.
// Set diffuse light direction last to fix transmission & hair.
d.direction = d.Ldiff;
d.NdotLm = dot(s.normalWorld, d.direction);
d.NdotL = saturate(d.NdotLm);
}
void aSphereLight(
inout ADirect d,
ASurface s,
float3 L,
half radius)
{
// Sphere Area Light.
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p15-16
d.Ldiff = L;
d.Lspec = L;
d.centerDistInverse = aSetAreaLightingInputs(d, s, radius);
}
void aTubeLight(
inout ADirect d,
ASurface s,
float3 L,
half3 axis,
half radius,
half halfLength)
{
// Tube Area Light.
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p16-18
float3 R = s.reflectionVectorWorld;
float3 tubeLightDir = axis * halfLength;
float3 L0 = L + tubeLightDir;
float3 L1 = L - tubeLightDir;
float3 Ld = tubeLightDir * -2.0f;
float RdotL0 = dot(R, L0);
float RdotLd = dot(R, Ld);
float L0dotLd = dot(L0, Ld);
float t = (RdotL0 * RdotLd - L0dotLd) / (dot(Ld, Ld) - RdotLd * RdotLd);
// Modified diffuse term for true tube diffuse lighting.
d.Ldiff = L - clamp(dot(L, axis), -halfLength, halfLength) * axis;
d.Lspec = L0 + Ld * saturate(t);
d.centerDistInverse = rsqrt(dot(L, L));
// Attentuation normalization.
d.color /= 1.0h + (0.25h * halfLength * aSetAreaLightingInputs(d, s, radius));
}
void aAreaLight(
inout ADirect d,
ASurface s,
half4 color,
half3 axis,
float3 L,
half range)
{
// Packed float light configuration.
// +/- llll.rrrr: l=length, r=radius, and sign as specular toggle.
// Radius externally clamped to .999 max to simplify math.
half lightParams = abs(color.a);
#ifdef USING_DIRECTIONAL_LIGHT
// 0.1 needed to make material inspector look okay.
aDirectionalDiscLight(d, s, L, lightParams * 0.1h);
#else
#if !defined(SPOT) && A_USE_TUBE_LIGHTS
// Enable when length is non-zero, and specular is enabled.
UNITY_BRANCH
if (color.a >= 1) {
half dec = frac(lightParams);
half radius = dec * range;
half halfLength = (lightParams - dec) * 0.001f * range;
aTubeLight(d, s, L, axis, radius, halfLength);
}
else
#endif
{
aSphereLight(d, s, L, lightParams * range);
}
aSetLightRangeLimit(d, range);
#endif
// Specular highlight toggle.
d.specularIntensity = color.a > 0.0h ? d.specularIntensity : 0.0h;
}
ASurface aNewSurface() {
ASurface s;
UNITY_INITIALIZE_OUTPUT(ASurface, s);
s.vertexNormalWorld = A_FLAT_NORMAL;
s.normalWorld = A_FLAT_NORMAL;
s.viewDirWorld = A_AXIS_X;
s.viewDirTangent = A_AXIS_X;
s.reflectionVectorWorld = A_AXIS_X;
s.tangentToWorld = 0.0h;
s.normalTangent = A_FLAT_NORMAL;
s.blurredNormalTangent = A_FLAT_NORMAL;
s.facingSign = 1.0h;
s.fogCoord = 0.0f;
s.NdotV = 0.0h;
s.FV = 0.0h;
s.materialType = 1.0h;
s.mask = 1.0h;
s.baseColor = 0.0h;
s.opacity = 1.0h;
s.metallic = 0.0h;
s.ambientOcclusion = 1.0h;
s.specularity = 0.5h;
s.specularTint = 0.0h;
s.roughness = 0.0h;
s.emissiveColor = 0.0h;
s.subsurfaceColor = 0.0h;
s.subsurface = 0.0h;
s.clearCoat = 0.0h;
s.clearCoatRoughness = 0.0h;
return s;
}
void aBlendRangeMask(
inout ASurface s,
half mask,
half weight,
half cutoff,
half blendRange,
half vertexTint)
{
cutoff = lerp(cutoff, 1.0h, s.vertexColor.a * vertexTint);
mask = 1.0h - saturate((mask - cutoff) / blendRange);
s.mask *= weight * mask;
}
half3 aTangentToWorld(
ASurface s,
half3 normalTangent)
{
#ifndef A_TANGENT_TO_WORLD_ON
return s.vertexNormalWorld;
#else
return normalize(mul(normalTangent, s.tangentToWorld));
#endif
}
half3 aWorldToTangent(
ASurface s,
half3 normalWorld)
{
#ifndef A_TANGENT_TO_WORLD_ON
return A_FLAT_NORMAL;
#else
return normalize(mul(s.tangentToWorld, normalWorld));
#endif
}
void aUpdateViewData(
inout ASurface s)
{
#if defined(A_NORMAL_WORLD_ON) && defined(A_VIEW_DIR_WORLD_ON)
// Area lights need this to be per-pixel.
#ifdef A_REFLECTION_VECTOR_WORLD_ON
s.reflectionVectorWorld = reflect(-s.viewDirWorld, s.normalWorld);
#endif
// Skip re-calculating world normals in some cases.
#ifndef A_VIEW_DIR_TANGENT_ON
s.NdotV = aDotClamp(s.normalWorld, s.viewDirWorld);
#else
s.NdotV = aDotClamp(s.normalTangent, s.viewDirTangent);
#endif
s.FV = aFresnel(s.NdotV);
#endif
}
void aUpdateNormalTangent(
inout ASurface s)
{
#ifndef A_TANGENT_TO_WORLD_ON
s.normalTangent = A_FLAT_NORMAL;
#else
s.normalWorld = aTangentToWorld(s, s.normalTangent);
s.ambientNormalWorld = s.normalWorld;
aUpdateViewData(s);
#endif
}
void aUpdateNormalWorld(
inout ASurface s)
{
#ifndef A_TANGENT_TO_WORLD_ON
s.normalWorld = s.vertexNormalWorld;
#else
s.normalTangent = aWorldToTangent(s, s.normalWorld);
s.ambientNormalWorld = s.normalWorld;
aUpdateViewData(s);
#endif
}
void aUpdateSubsurface(
inout ASurface s)
{
s.subsurfaceColor = aGammaToLinear(s.subsurface).rrr;
}
void aUpdateSubsurfaceColor(
inout ASurface s)
{
s.subsurface = LinearToGammaSpace(s.subsurfaceColor).g;
}
half3 aSpecularityToF0(
half specularity)
{
return (specularity * A_MAX_DIELECTRIC_F0).rrr;
}
half aLinearToBeckmannRoughness(
half roughness)
{
// Remap roughness to prevent specular artifacts.
roughness = lerp(A_MIN_AREA_ROUGHNESS, 1.0h, roughness);
return roughness * roughness;
}
half aFresnel(
half w)
{
// Sebastien Lagarde's spherical gaussian approximation of Schlick fresnel.
// cf http://seblagarde.wordpress.com/2011/08/17/hello-world/
return exp2((-5.55473h * w - 6.98316h) * w);
}
half3 aSpecularLightingToggle(
ASurface s,
half3 specular)
{
#if !A_USE_BLACK_SPECULAR_COLOR_TOGGLE
return specular;
#else
return any(s.f0) ? specular : A_BLACK;
#endif
}
half aSpecularOcclusion(
half ao,
half NdotV)
{
// Yoshiharu Gotanda's specular occlusion approximation:
// cf http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx pg59
half d = NdotV + ao;
return saturate((d * d) - 1.0h + ao);
}
void aStandardPreLighting(
inout ASurface s)
{
// In Forward mode, set material type.
#ifndef A_DEFERRED_PASS
s.baseColor = saturate(s.baseColor);
s.albedo = s.baseColor;
s.f0 = aSpecularityToF0(s.specularity);
#ifndef A_SPECULAR_TINT_ON
s.specularTint = 0.0h;
#else
s.f0 *= aLerpWhiteTo(aChromaticity(s.baseColor), s.specularTint);
#endif
#ifndef A_METALLIC_ON
s.metallic = 0.0h;
#else
half metallicInv = 1.0h - s.metallic;
s.albedo *= metallicInv; // Affects transmission through albedo.
s.f0 = lerp(s.f0, s.baseColor, s.metallic);
#ifdef _ALPHAPREMULTIPLY_ON
// Interpolate from a translucent dielectric to an opaque metal.
s.opacity = s.metallic + metallicInv * s.opacity;
#endif
#endif
#ifndef A_CLEARCOAT_ON
s.clearCoat = 0.0h;
s.clearCoatRoughness = 0.0h;
#else
// f0 of 0.04 gives us a polyurethane-like coating.
half clearCoat = s.clearCoat * lerp(0.04h, 1.0h, s.FV);
s.albedo *= aLerpOneTo(0.0h, clearCoat);
s.f0 = lerp(s.f0, A_WHITE, clearCoat);
s.roughness = lerp(s.roughness, s.clearCoatRoughness, clearCoat);
#endif
#ifdef _ALPHAPREMULTIPLY_ON
// Premultiply opacity with albedo for translucent shaders.
s.albedo *= s.opacity;
#endif
s.beckmannRoughness = aLinearToBeckmannRoughness(s.roughness);
#ifndef A_AMBIENT_OCCLUSION_ON
s.ambientOcclusion = 1.0h;
s.specularOcclusion = 1.0h;
#else
s.specularOcclusion = aSpecularOcclusion(s.ambientOcclusion, s.NdotV);
#endif
#if defined(A_SCATTERING_ON)
s.materialType = A_MATERIAL_TYPE_SUBSURFACE_SCATTERING;
s._subsurfaceShadowWeight = 0.0h;
s._skinScatteringMask = 1.0h;
s.ambientNormalWorld = aTangentToWorld(s, s.blurredNormalTangent);
#elif defined(A_SUBSURFACE_ON)
#ifdef A_TWO_SIDED_SHADER
s.materialType = A_MATERIAL_TYPE_SHADOWED_SUBSURFACE;
s._subsurfaceShadowWeight = A_SUBSURFACE_SHADOW;
#else
s.materialType = _ShadowCullMode == A_CULL_MODE_FRONT ? A_MATERIAL_TYPE_SHADOWED_SUBSURFACE : A_MATERIAL_TYPE_UNSHADOWED_SUBSURFACE;
s._subsurfaceShadowWeight = _ShadowCullMode == A_CULL_MODE_FRONT ? A_SUBSURFACE_SHADOW : 0.0h;
#endif
#else
s.materialType = A_MATERIAL_TYPE_OPAQUE;
#endif
#endif
#if defined(A_SCATTERING_ON) || defined(A_SUBSURFACE_ON)
A_DEFERRED_BRANCH(s.materialType != A_MATERIAL_TYPE_OPAQUE)
{
// In Deferred mode, determine material type and sample extra G-buffer data.
#if defined(A_DEFERRED_PASS)
half4 buffer = tex2Dlod(_DeferredPlusBuffer, float4(s.screenUv, 0.0f, 0.0f));
s.subsurface = buffer.a;
s._subsurfaceShadowWeight = s.materialType == A_MATERIAL_TYPE_SHADOWED_SUBSURFACE ? A_SUBSURFACE_SHADOW : 0.0h;
#if defined(A_SCATTERING_ON)
s._skinScatteringMask = s.materialType == A_MATERIAL_TYPE_SUBSURFACE_SCATTERING ? 1.0h : 0.0h;
s.ambientNormalWorld = normalize(buffer.xyz * 2.0h - 1.0h);
#endif
#endif
// Subsurface color calculation.
#ifdef A_SUBSURFACE_ON
#ifdef A_FORWARD_ONLY_SHADER
s.subsurfaceColor *= s.albedo;
#else
s.subsurfaceColor = s.albedo * aGammaToLinear(s.subsurface);
#endif
#endif
// Scattering input data.
#ifdef A_SCATTERING_ON
A_DEFERRED_BRANCH(s.materialType == A_MATERIAL_TYPE_SUBSURFACE_SCATTERING)
{
// Scattering mask.
s._skinScatteringMask *= A_SCATTERING_WEIGHT * saturate(A_SCATTERING_INV_MASK_CUTOFF * s.subsurface);
s._skinScattering = saturate(s.subsurface * A_SCATTERING_SCALE + A_SCATTERING_BIAS);
// Skin subsurface depth absorption tint.
// cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
half3 absorption = exp((1.0h - s.subsurface) * A_SCATTERING_ABSORPTION);
// Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
absorption *= saturate(s.albedo * unity_ColorSpaceDouble.rgb);
s.subsurfaceColor = lerp(s.subsurfaceColor, absorption, s._skinScatteringMask);
// Blurred normals for indirect diffuse and direct scattering.
s.ambientNormalWorld = normalize(lerp(s.normalWorld, s.ambientNormalWorld, A_SCATTERING_NORMAL_BLUR * s._skinScatteringMask));
}
#endif
// Subsurface color weight.
#ifdef A_SUBSURFACE_ON
s.subsurfaceColor *= A_SUBSURFACE_WEIGHT;
#endif
}
#endif
}
half3 aStandardDirectLighting(
ADirect d,
ASurface s)
{
half3 illum = A_BLACK;
half3 specular = A_BLACK;
#if defined(A_SCATTERING_ON) || defined(A_SUBSURFACE_ON)
A_DEFERRED_BRANCH(s.materialType != A_MATERIAL_TYPE_OPAQUE)
{
#ifdef A_SUBSURFACE_ON
// Subsurface transmission.
// cf http://www.farfarer.com/blog/2012/09/11/translucent-shader-unity3d/
half3 transLightDir = d.direction + s.normalWorld * A_SUBSURFACE_DISTORTION;
half transLight = pow(aDotClamp(s.viewDirWorld, -transLightDir), A_SUBSURFACE_FALLOFF);
half shadow = aLerpOneTo(d.shadow, s._subsurfaceShadowWeight);
illum += s.subsurfaceColor * (shadow * transLight);
#endif
#ifdef A_SCATTERING_ON
A_DEFERRED_BRANCH(s.materialType == A_MATERIAL_TYPE_SUBSURFACE_SCATTERING)
{
// Pre-Integrated Skin Shading.
// cf http://www.farfarer.com/blog/2013/02/11/pre-integrated-skin-shader-unity-3d/
float ndlBlur = dot(s.ambientNormalWorld, d.direction) * 0.5h + 0.5h;
float4 sssLookupUv = float4(ndlBlur, s._skinScattering * aLuminance(d.color), 0.0f, 0.0f);
half3 sss = (s._skinScatteringMask * d.shadow) * tex2Dlod(A_SCATTERING_LUT, sssLookupUv).rgb;
illum += s.albedo * sss;
s.albedo *= 1.0h - s._skinScatteringMask;
}
#endif
}
#endif
// Cook-Torrance microfacet model.
// cf http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
half LdotH2 = d.LdotH * d.LdotH;
// Brent Burley diffuse BRDF.
// cf https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf pg14
half FL = aFresnel(d.NdotL);
half Fd90 = 0.5h + (2.0h * LdotH2 * s.roughness);
half Fd = aLerpOneTo(Fd90, FL) * aLerpOneTo(Fd90, s.FV);
half3 diffuse = s.albedo * Fd;
#ifndef _SPECULARHIGHLIGHTS_OFF
// Schlick's Fresnel approximation.
half3 F = lerp(s.f0, A_WHITE, aFresnel(d.LdotH));
// John Hable's Visibility function.
// cf http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
half a2 = s.beckmannRoughness * s.beckmannRoughness;
half k2 = a2 * 0.25h; // k = a/2; k*k = (a*a)/(2*2) = (a^2)/4.
half invV = lerp(k2, 1.0h, LdotH2);
// GGX (Trowbridge-Reitz) NDF.
// cf http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
half denom = aLerpOneTo(a2, d.NdotH * d.NdotH);
half mDV = k2 / (invV * denom * denom); // k2 is GGX a^2 and microfacet 1/4.
specular = aSpecularLightingToggle(s, F * (mDV * s.specularOcclusion * d.specularIntensity));
#endif
// Punctual lighting equation.
// cf http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
illum += (d.shadow * d.NdotL) * (diffuse + specular);
return d.color * illum;
}
half3 aStandardIndirectLighting(
AIndirect i,
ASurface s)
{
half3 illum = A_BLACK;
#if defined(A_DEFERRED_PASS) || defined(A_REFLECTION_PROBES_ON)
// Brian Karis' modification of Dimitar Lazarov's Environment BRDF.
// cf https://www.unrealengine.com/blog/physically-based-shading-on-mobile
const half4 c0 = half4(-1.0h, -0.0275h, -0.572h, 0.022h);
const half4 c1 = half4(1.0h, 0.0425h, 1.04h, -0.04h);
half4 r = s.roughness * c0 + c1;
half a004 = min(r.x * r.x, exp2(-9.28h * s.NdotV)) * r.x + r.y;
half2 AB = half2(-1.04h, 1.04h) * a004 + r.zw;
half3 specular = i.specular * (s.f0 * AB.x + AB.yyy);
#endif
#ifdef A_DEFERRED_PASS
illum = aSpecularLightingToggle(s, specular * s.specularOcclusion);
#else
#ifndef A_AMBIENT_OCCLUSION_ON
half3 diffuse = s.albedo * i.diffuse;
#ifndef A_REFLECTION_PROBES_ON
illum = diffuse;
#else
illum = diffuse + aSpecularLightingToggle(s, specular);
#endif
#else
#ifndef A_SCATTERING_ON
half ao = s.ambientOcclusion;
#else
// Color Bleed AO.
// cf http://www.iryoku.com/downloads/Next-Generation-Character-Rendering-v6.pptx pg113
half3 ao = pow(s.ambientOcclusion.rrr, A_ONE - (A_SCATTERING_AO_COLOR_BLEED * s._skinScatteringMask));
#endif
// Yoshiharu Gotanda's fake interreflection for specular occlusion.
// Modified to better account for surface f0.
// cf http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx pg65
half3 ambient = i.diffuse * ao;
#ifndef A_REFLECTION_PROBES_ON
// Diffuse and fake interreflection only.
illum = ambient * (s.albedo + aSpecularLightingToggle(s, s.f0 * (1.0h - s.specularOcclusion)));
#else
// Full equation.
illum = ambient * s.albedo
+ aSpecularLightingToggle(s, lerp(ambient * s.f0, specular, s.specularOcclusion));
#endif
#endif
#endif
return illum;
}
#endif // ALLOY_SHADERS_FRAMEWORK_LIGHTING_IMPL_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 793f250168f085a4a8ff1459943a8cca
timeCreated: 1492114566
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,247 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file Particle.cginc
/// @brief Particles uber-header.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_PARTICLE_CGINC
#define ALLOY_SHADERS_FRAMEWORK_PARTICLE_CGINC
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "UnityInstancing.cginc"
#include "UnityLightingCommon.cginc"
#include "UnityStandardUtils.cginc"
#include "UnityShaderVariables.cginc"
struct AVertexInput {
float4 vertex : POSITION;
float4 color : COLOR;
float4 texcoords : TEXCOORD0;
#ifdef A_PARTICLE_TEXTURE_BLEND_ON
float texcoordBlend : TEXCOORD1;
#endif
#if defined(_RIM_FADE_ON) || defined(A_PARTICLE_LIGHTING_ON)
half3 normal : NORMAL;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct AFragmentInput {
float4 vertex : SV_POSITION;
float4 color : COLOR;
float4 texcoords : TEXCOORD0;
#ifdef _PARTICLE_EFFECTS_ON
float2 uv_ParticleEffectMask1 : TEXCOORD1;
float2 uv_ParticleEffectMask2 : TEXCOORD2;
#endif
UNITY_FOG_COORDS(3)
#if defined(SOFTPARTICLES_ON) || defined(_DISTANCE_FADE_ON) || defined(VTRANSPARENCY_ON)
float4 projPos : TEXCOORD4;
#endif
#if defined(_RIM_FADE_ON) || defined(A_PARTICLE_LIGHTING_ON)
half3 normalWorld : TEXCOORD5;
half4 viewDirWorld : TEXCOORD6;
#endif
#if defined(A_PARTICLE_LIGHTING_ON) || defined(VAPOR_TRANSLUCENT_FOG_ON)
float4 positionWorld : TEXCOORD7;
#endif
#if defined(A_PARTICLE_LIGHTING_ON)
half3 ambient : TEXCOORD8;
#endif
#ifdef A_PARTICLE_TEXTURE_BLEND_ON
float blend : TEXCOORD9;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
half4 _TintColor;
A_SAMPLER_2D(_MainTex);
half _TintWeight;
float _InvFade;
#ifdef _PARTICLE_EFFECTS_ON
A_SAMPLER_2D(_ParticleEffectMask1);
A_SAMPLER_2D(_ParticleEffectMask2);
#endif
#ifdef _RIM_FADE_ON
half _RimFadeWeight; // Expects linear-space values
half _RimFadePower;
#endif
float _DistanceFadeNearFadeCutoff;
float _DistanceFadeRange;
AFragmentInput aMainVertexShader(
AVertexInput v)
{
AFragmentInput o;
UNITY_INITIALIZE_OUTPUT(AFragmentInput, o);
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
o.vertex = UnityObjectToClipPos(v.vertex.xyz);
#if defined(SOFTPARTICLES_ON) || defined(_DISTANCE_FADE_ON) || defined(VTRANSPARENCY_ON)
o.projPos = ComputeScreenPos (o.vertex);
COMPUTE_EYEDEPTH(o.projPos.z);
#endif
o.color = v.color;
#ifndef A_VERTEX_COLOR_DEGAMMA_OFF
o.color.rgb = aGammaToLinear(o.color.rgb);
#endif
o.texcoords.xy = A_TEX_TRANSFORM_SCROLL_SPIN(_MainTex, v.texcoords.xy);
#ifdef _PARTICLE_EFFECTS_ON
o.uv_ParticleEffectMask1 = A_TEX_TRANSFORM_SCROLL_SPIN(_ParticleEffectMask1, v.texcoords.xy);
o.uv_ParticleEffectMask2 = A_TEX_TRANSFORM_SCROLL_SPIN(_ParticleEffectMask2, v.texcoords.xy);
#endif
#if defined(_RIM_FADE_ON) || defined(A_PARTICLE_LIGHTING_ON) || defined(VAPOR_TRANSLUCENT_FOG_ON)
float4 positionWorld = mul(unity_ObjectToWorld, v.vertex);
#endif
#if defined(_RIM_FADE_ON) || defined(A_PARTICLE_LIGHTING_ON)
o.normalWorld = UnityObjectToWorldNormal(v.normal);
o.viewDirWorld.xyz = UnityWorldSpaceViewDir(positionWorld.xyz);
#endif
#if defined(A_PARTICLE_LIGHTING_ON) || defined(VAPOR_TRANSLUCENT_FOG_ON)
o.positionWorld = positionWorld;
#endif
#ifdef A_PARTICLE_LIGHTING_ON
// 1 Directional, 4 Point lights, and Light probes.
o.ambient = _LightColor0.rgb * aDotClamp(_WorldSpaceLightPos0.xyz, o.normalWorld);
o.ambient += aShade4PointLights(o.positionWorld.xyz, o.normalWorld);
o.ambient += ShadeSHPerVertex(o.normalWorld, o.ambient);
#endif
#ifdef A_PARTICLE_TEXTURE_BLEND_ON
o.texcoords.zw = A_TEX_TRANSFORM_SCROLL_SPIN(_MainTex, v.texcoords.zw);
o.blend = v.texcoordBlend;
#endif
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
/// Controls how the particle is faded out based on scene intersection, rim,
/// and camera distance.
half aFadeParticle(
AFragmentInput i)
{
half fade = 1.0h;
UNITY_SETUP_INSTANCE_ID(i);
#ifdef SOFTPARTICLES_ON
float sceneZ = DECODE_EYEDEPTH(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
float partZ = i.projPos.z;
fade = saturate(_InvFade * (sceneZ - partZ));
#endif
#ifdef _DISTANCE_FADE_ON
// Alpha clip.
// cf http://wiki.unity3d.com/index.php?title=AlphaClipsafe
fade *= saturate((i.projPos.z - _DistanceFadeNearFadeCutoff) / _DistanceFadeRange);
#endif
#ifdef _RIM_FADE_ON
half3 normal = normalize(i.normalWorld);
half3 viewDir = normalize(i.viewDirWorld.xyz);
half NdotV = abs(dot(normal, viewDir));
half bias = 1.0h - _RimFadeWeight;
fade = aRimLight(fade, bias, _RimFadePower, 1.0h - NdotV);
#endif
return fade;
}
/// Applies transforming effects mask textures to the particle.
half4 aParticleEffects(
AFragmentInput i)
{
half4 color = tex2D(_MainTex, i.texcoords.xy);
#ifdef A_PARTICLE_TEXTURE_BLEND_ON
half4 color2 = tex2D(_MainTex, i.texcoords.zw);
color = lerp(color, color2, i.blend);
#endif
color.rgb *= _TintWeight;
#ifdef _PARTICLE_EFFECTS_ON
color *= tex2D(_ParticleEffectMask1, i.uv_ParticleEffectMask1);
color *= tex2D(_ParticleEffectMask2, i.uv_ParticleEffectMask2);
#endif
#ifdef A_PARTICLE_LIGHTING_ON
color.rgb *= ShadeSHPerPixel(i.normalWorld, i.ambient, i.positionWorld);
#endif
return color;
}
half4 aParticleOutputBase(
AFragmentInput i,
half4 color)
{
UNITY_APPLY_FOG_COLOR(i.fogCoord, color, unity_FogColor);
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
color = VaporApplyFog(i.positionWorld, color);
#elif defined(VTRANSPARENCY_ON)
color = VolumetricTransparencyBase(color, i.projPos);
#endif
color.rgb = aHdrClamp(color.rgb);
return color;
}
half4 aParticleOutputAdd(
AFragmentInput i,
half4 color)
{
UNITY_APPLY_FOG_COLOR(i.fogCoord, color, A_BLACK4);
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
color = VaporApplyFogAdd(i.positionWorld, color);
#elif defined(VTRANSPARENCY_ON)
color = VolumetricTransparencyAdd(color, i.projPos);
#endif
color.rgb = aHdrClamp(color.rgb);
return color;
}
half4 aParticleOutputMultiply(
AFragmentInput i,
half4 color)
{
UNITY_APPLY_FOG_COLOR(i.fogCoord, color, A_WHITE4);
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
color = VaporApplyFogFade(i.positionWorld, color, A_WHITE);
#elif defined(VTRANSPARENCY_ON)
// color = VolumetricTransparencyAdd(color, i.projPos);
#endif
color.rgb = aHdrClamp(color.rgb);
return color;
}
#endif // ALLOY_SHADERS_FRAMEWORK_PARTICLE_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c51b783c68589c242820eed366e80062
timeCreated: 1424470451
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,256 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Tessellation.cginc
/// @brief Callbacks and data structures for tessellation.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_TESSELLATION_CGINC
#define ALLOY_SHADERS_FRAMEWORK_TESSELLATION_CGINC
#include "Assets/Alloy/Shaders/Config.cginc"
#include "HLSLSupport.cginc"
//#include "Lighting.cginc"
//#include "Tessellation.cginc"
#include "UnityCG.cginc"
#if defined(A_TESSELLATION_SHADER) && defined(A_TESSELLATION_PASS) && defined(UNITY_CAN_COMPILE_TESSELLATION)
struct UnityTessellationFactors {
float edge[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
#include "UnityShaderVariables.cginc"
float UnityCalcEdgeTessFactor(float3 wpos0, float3 wpos1, float edgeLen)
{
// distance to edge center
float dist = distance(0.5 * (wpos0 + wpos1), _WorldSpaceCameraPos);
// length of the edge
float len = distance(wpos0, wpos1);
// edgeLen is approximate desired size in pixels
float f = max(len * _ScreenParams.y / (edgeLen * dist), 1.0);
return f;
}
float UnityDistanceFromPlane(float3 pos, float4 plane)
{
float d = dot(float4(pos, 1.0f), plane);
return d;
}
// Returns true if triangle with given 3 world positions is outside of camera's view frustum.
// cullEps is distance outside of frustum that is still considered to be inside (i.e. max displacement)
bool UnityWorldViewFrustumCull(float3 wpos0, float3 wpos1, float3 wpos2, float cullEps)
{
float4 planeTest;
// left
planeTest.x = ((UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f);
// right
planeTest.y = ((UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f);
// top
planeTest.z = ((UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f);
// bottom
planeTest.w = ((UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f) +
((UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f);
// has to pass all 4 plane tests to be visible
return !all(planeTest);
}
// Same as UnityEdgeLengthBasedTess, but also does patch frustum culling:
// patches outside of camera's view are culled before GPU tessellation. Saves some wasted work.
float4 UnityEdgeLengthBasedTessCull(float4 v0, float4 v1, float4 v2, float edgeLength, float maxDisplacement)
{
float3 pos0 = mul(unity_ObjectToWorld, v0).xyz;
float3 pos1 = mul(unity_ObjectToWorld, v1).xyz;
float3 pos2 = mul(unity_ObjectToWorld, v2).xyz;
float4 tess;
if (UnityWorldViewFrustumCull(pos0, pos1, pos2, maxDisplacement))
{
tess = 0.0f;
}
else
{
tess.x = UnityCalcEdgeTessFactor(pos1, pos2, edgeLength);
tess.y = UnityCalcEdgeTessFactor(pos2, pos0, edgeLength);
tess.z = UnityCalcEdgeTessFactor(pos0, pos1, edgeLength);
tess.w = (tess.x + tess.y + tess.z) / 3.0f;
}
return tess;
}
struct ATessellationInput {
float4 vertex : INTERNALTESSPOS;
half3 normal : NORMAL;
float4 uv0 : TEXCOORD0;
float4 uv1 : TEXCOORD1;
#ifdef A_UV2_ON
float4 uv2 : TEXCOORD2;
#endif
#ifdef A_TANGENT_ON
half4 tangent : TANGENT;
#endif
half4 color : COLOR;
};
float _EdgeLength;
#if A_USE_TESSELLATION_MIN_EDGE_LENGTH
float _MinEdgeLength;
#endif
#ifdef _TESSELLATIONMODE_DISPLACEMENT
A_SAMPLER_2D(_DispTex);
float _Displacement;
#endif
#ifdef _TESSELLATIONMODE_PHONG
float _Phong;
#endif
// NOTE: Forward-declared here so we can share Domain shader.
void aMainVertexShader(AVertexInput v,
#ifndef A_VERTEX_TO_FRAGMENT_OFF
out AFragmentInput o,
#endif
out float4 opos : SV_POSITION);
// tessellation hull constant shader
UnityTessellationFactors aHullConstantTessellation(
InputPatch<ATessellationInput, 3> v)
{
float4 tf = 0.0f;
float maxDisplacement = 0.0f;
UnityTessellationFactors o;
#ifdef _TESSELLATIONMODE_DISPLACEMENT
maxDisplacement = 1.5f * _Displacement;
#endif
float edgeLength = _EdgeLength;
#if A_USE_TESSELLATION_MIN_EDGE_LENGTH
edgeLength = max(_MinEdgeLength, edgeLength);
#endif
tf = UnityEdgeLengthBasedTessCull(v[0].vertex, v[1].vertex, v[2].vertex, edgeLength, maxDisplacement);
o.edge[0] = tf.x;
o.edge[1] = tf.y;
o.edge[2] = tf.z;
o.inside = tf.w;
return o;
}
ATessellationInput aMainTessellationVertexShader(
AVertexInput v)
{
ATessellationInput o;
UNITY_INITIALIZE_OUTPUT(ATessellationInput, o);
o.vertex = v.vertex;
o.normal = v.normal;
o.uv0 = v.uv0;
o.uv1 = v.uv1;
#ifdef A_UV2_ON
o.uv2 = v.uv2;
#endif
#ifdef A_TANGENT_ON
o.tangent = v.tangent;
#endif
o.color = v.color;
return o;
}
// tessellation hull shader
[UNITY_domain("tri")]
[UNITY_partitioning("fractional_odd")]
[UNITY_outputtopology("triangle_cw")]
[UNITY_patchconstantfunc("aHullConstantTessellation")]
[UNITY_outputcontrolpoints(3)]
ATessellationInput aMainHullShader(
InputPatch<ATessellationInput, 3> v,
uint id : SV_OutputControlPointID)
{
return v[id];
}
[UNITY_domain("tri")]
void aMainDomainShader(
UnityTessellationFactors tessFactors,
const OutputPatch<ATessellationInput, 3> vi,
float3 bary : SV_DomainLocation,
#ifndef A_VERTEX_TO_FRAGMENT_OFF
out AFragmentInput o,
#endif
out float4 opos : SV_POSITION)
{
AVertexInput v;
UNITY_INITIALIZE_OUTPUT(AVertexInput, v);
v.vertex = vi[0].vertex * bary.x + vi[1].vertex * bary.y + vi[2].vertex * bary.z;
v.normal = vi[0].normal * bary.x + vi[1].normal * bary.y + vi[2].normal * bary.z;
v.uv0 = vi[0].uv0 * bary.x + vi[1].uv0 * bary.y + vi[2].uv0 * bary.z;
v.uv1 = vi[0].uv1 * bary.x + vi[1].uv1 * bary.y + vi[2].uv1 * bary.z;
#ifdef A_UV2_ON
v.uv2 = vi[0].uv2 * bary.x + vi[1].uv2 * bary.y + vi[2].uv2 * bary.z;
#endif
#ifdef A_TANGENT_ON
v.tangent = vi[0].tangent * bary.x + vi[1].tangent * bary.y + vi[2].tangent * bary.z;
#endif
v.color = vi[0].color * bary.x + vi[1].color * bary.y + vi[2].color * bary.z;
#ifdef _TESSELLATIONMODE_PHONG
float3 pp[3];
for (int i = 0; i < 3; ++i)
pp[i] = v.vertex.xyz - vi[i].normal * (dot(v.vertex.xyz, vi[i].normal) - dot(vi[i].vertex.xyz, vi[i].normal));
float3 displacedPosition = pp[0] * bary.x + pp[1] * bary.y + pp[2] * bary.z;
v.vertex.xyz = lerp(v.vertex.xyz, displacedPosition, _Phong);
#endif
// NOTE: This has to come second, since the Phong mode references the
// unmodified vertices in order to work!
#ifdef _TESSELLATIONMODE_DISPLACEMENT
float d = _Displacement;
float oscillation = _Time.y;
float2 tessUv = TRANSFORM_TEX(v.uv0.xy, _DispTex) + (_DispTexVelocity * oscillation);
#ifdef _VIRTUALTEXTURING_ON
d *= VTVertexSampleDisplacement(tessUv);
#else
d *= tex2Dlod(_DispTex, float4(tessUv, 0.0f, 0.0f)).g;
#endif
v.vertex.xyz += v.normal * d;
#endif
aMainVertexShader(
v,
#ifndef A_VERTEX_TO_FRAGMENT_OFF
o,
#endif
opos);
}
#endif
#endif // ALLOY_SHADERS_FRAMEWORK_TESSELLATION_CGINC
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: a789d7820ee8bd8468cb19d1a820a515
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
+147
View File
@@ -0,0 +1,147 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Type.cginc
/// @brief Shader type uber-header.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_TYPE_CGINC
#define ALLOY_SHADERS_FRAMEWORK_TYPE_CGINC
#define A_VOLUMETRIC_DATA ASurface
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/Feature.cginc"
#include "Assets/Alloy/Shaders/Framework/Lighting.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "Assets/Alloy/Shaders/Framework/Volumetric.cginc"
#include "UnityCG.cginc"
#include "UnityInstancing.cginc"
#if !defined(A_VERTEX_COLOR_IS_DATA) && defined(A_PROJECTIVE_DECAL_SHADER)
#define A_VERTEX_COLOR_IS_DATA
#endif
#if !defined(A_SHADOW_MASKS_BUFFER_ON) && (defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4))
#define A_SHADOW_MASKS_BUFFER_ON
#endif
#if !defined(A_ALPHA_BLENDING_ON) && (defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON))
#define A_ALPHA_BLENDING_ON
#endif
#if !defined(A_ROUGHNESS_SOURCE_BASE_COLOR_ALPHA) && defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A)
#define A_ROUGHNESS_SOURCE_BASE_COLOR_ALPHA
#endif
#if !defined(A_NORMAL_MAPPING_ON) && (defined(EFFECT_BUMP) || defined(_TERRAIN_NORMAL_MAP))
#define A_NORMAL_MAPPING_ON
#endif
// Features
#include "Assets/Alloy/Shaders/Feature/AO2.cginc"
#include "Assets/Alloy/Shaders/Feature/CarPaint.cginc"
#include "Assets/Alloy/Shaders/Feature/Decal.cginc"
#include "Assets/Alloy/Shaders/Feature/Detail.cginc"
#include "Assets/Alloy/Shaders/Feature/DirectionalBlend.cginc"
#include "Assets/Alloy/Shaders/Feature/Dissolve.cginc"
#include "Assets/Alloy/Shaders/Feature/Emission.cginc"
#include "Assets/Alloy/Shaders/Feature/Emission2.cginc"
#include "Assets/Alloy/Shaders/Feature/Eye.cginc"
#include "Assets/Alloy/Shaders/Feature/MainTextures.cginc"
#include "Assets/Alloy/Shaders/Feature/OrientedTextures.cginc"
#include "Assets/Alloy/Shaders/Feature/Parallax.cginc"
#include "Assets/Alloy/Shaders/Feature/Puddles.cginc"
#include "Assets/Alloy/Shaders/Feature/Rim.cginc"
#include "Assets/Alloy/Shaders/Feature/Rim2.cginc"
#include "Assets/Alloy/Shaders/Feature/SecondaryTextures.cginc"
#include "Assets/Alloy/Shaders/Feature/SkinTextures.cginc"
#include "Assets/Alloy/Shaders/Feature/SpeedTree.cginc"
#include "Assets/Alloy/Shaders/Feature/TeamColor.cginc"
#include "Assets/Alloy/Shaders/Feature/Terrain.cginc"
#include "Assets/Alloy/Shaders/Feature/TransitionBlend.cginc"
#include "Assets/Alloy/Shaders/Feature/Transmission.cginc"
#include "Assets/Alloy/Shaders/Feature/TriPlanar.cginc"
#include "Assets/Alloy/Shaders/Feature/VertexBlend.cginc"
#include "Assets/Alloy/Shaders/Feature/WeightedBlend.cginc"
#include "Assets/Alloy/Shaders/Feature/Wetness.cginc"
/// Vertex data to be modified for specific shader type.
struct AVertex {
/// Vertex position in object space.
float4 positionObject;
/// Vertex normal in object space.
/// Expects normalized vectors.
half3 normalObject;
/// Vertex tangent in object space and bitangent sign.
/// XYZ: Normalized tangent, W: Bitangent sign.
half4 tangentObject;
/// UV0 texture coordinates.
float4 uv0;
/// UV1 texture coordinates.
float4 uv1;
/// UV2 texture coordinates.
float4 uv2;
/// UV3 texture coordinates.
float4 uv3;
/// Vertex color.
/// Expects linear-space LDR color values.
half4 color;
};
/// Deferred geometry buffer representation of surface data.
struct AGbuffer {
/// RGB: Albedo, A: Specular occlusion.
half4 diffuseOcclusion : SV_Target0;
/// RGB: f0, A: 1-Roughness.
half4 specularSmoothness : SV_Target1;
/// RGB: Packed world-space normal, A: Material type.
half4 normalType : SV_Target2;
/// RGB: Emission, A: 1-Subsurface.
half4 emissionSubsurface : SV_Target3;
#ifdef A_SHADOW_MASKS_BUFFER_ON
/// RGBA: Shadow Masks.
half4 shadowMasks : SV_Target4;
#endif
};
/// Abstract declaration for user-defined vertex shader.
void aVertexShader(inout AVertex v);
/// Abstract declaration for user-defined color shader.
void aColorShader(inout half4 color, ASurface s);
/// Abstract declaration for user-defined G-Buffer shader.
void aGbufferShader(inout AGbuffer gb, ASurface s);
/// Abstract declaration for user-defined surface shader.
void aSurfaceShader(inout ASurface s);
/// Vertex output data constructor.
AVertex aNewVertex();
/// Gbuffer output data constructor.
AGbuffer aNewGbuffer();
/// Applies standard vertex transformations.
void aStandardVertexShader(inout AVertex v);
/// Applies standard color transformations.
void aStandardColorShader(inout half4 color, ASurface s);
#endif // ALLOY_SHADERS_FRAMEWORK_TYPE_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d0bcdda46674d1746bdd3bee79fa475a
timeCreated: 1437771795
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,63 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Type.cginc
/// @brief Shader type method implementations to allow disabling of features.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_TYPE_IMPL_CGINC
#define ALLOY_SHADERS_FRAMEWORK_TYPE_IMPL_CGINC
#if !defined(A_VERTEX_COLOR_IS_DATA) && defined(A_USE_VERTEX_MOTION)
#define A_VERTEX_COLOR_IS_DATA
#endif
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/LightingImpl.cginc"
#include "Assets/Alloy/Shaders/Framework/Type.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "Assets/Alloy/Shaders/Framework/VolumetricImpl.cginc"
AVertex aNewVertex() {
AVertex v;
UNITY_INITIALIZE_OUTPUT(AVertex, v);
return v;
}
AGbuffer aNewGbuffer() {
AGbuffer gb;
UNITY_INITIALIZE_OUTPUT(AGbuffer, gb);
#ifdef A_SHADOW_MASKS_BUFFER_ON
gb.shadowMasks = A_ZERO4;
#endif
return gb;
}
void aStandardVertexShader(
inout AVertex v)
{
#ifdef A_USE_VERTEX_MOTION
v.positionObject = VertExmotion(v.positionObject, v.color);
#elif !defined(A_VERTEX_COLOR_IS_DATA)
/// Convert in vertex shader to interpolate in linear space.
v.color.rgb = aGammaToLinear(v.color.rgb);
#endif
}
void aStandardColorShader(
inout half4 color,
ASurface s)
{
#ifdef A_BASE_PASS
aVolumetricBase(color, s);
#else
aVolumetricAdd(color, s);
#endif
}
#endif // ALLOY_SHADERS_FRAMEWORK_TYPE_IMPL_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 240c6e998db732a4899614464dcba05a
timeCreated: 1473016735
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
+193
View File
@@ -0,0 +1,193 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Unity.cginc
/// @brief Code shared between Alloy shaders and Unity override headers.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_UNITY_CGINC
#define ALLOY_SHADERS_FRAMEWORK_UNITY_CGINC
// Headers both for this file, and for all Definition and Feature modules.
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/LightingImpl.cginc"
#include "Assets/Alloy/Shaders/Framework/Utility.cginc"
#include "AutoLight.cginc"
#include "UnityCG.cginc"
#include "UnityGlobalIllumination.cginc"
#include "UnityLightingCommon.cginc"
#include "UnityShaderVariables.cginc"
/// Sets light range in light vector range ".w" component.
/// @param[in,out] lightVectorRange XYZ: Vector to light center, W: Light volume range.
/// @param[out] lightCoord Projection coordinates in light space.
void aLightRange(
inout float4 lightVectorRange,
unityShadowCoord4 lightCoord)
{
// Light range = |light-space light vector| / |world-space light vector|
// This works because the light vector's length is the same in both world
// and light space, but it's scaled by the light range in light space.
// cf http://forum.unity3d.com/threads/get-the-range-of-a-point-light-in-forward-add-mode.213430/#post-1433291
lightVectorRange.w = length(lightVectorRange.xyz) * rsqrt(dot(lightCoord.xyz, lightCoord.xyz));
}
/// Calculates forward indirect illumination.
/// @param gi UnityGI populated with data.
/// @param s Material surface data.
/// @return Indirect illumination.
half3 aUnityIndirectLighting(
UnityGI gi,
ASurface s)
{
return aIndirectLighting(gi.indirect, s);
}
/// Calculates forward direct illumination.
/// @param s Material surface data.
/// @param shadow Shadow attenuation.
/// @param lightVectorRange XYZ: Vector to light center, W: Light volume range.
/// @param lightCoord Light projection texture coordinates.
/// @return Direct illumination.
half3 aUnityDirectLighting(
ASurface s,
half shadow,
float4 lightVectorRange,
unityShadowCoord4 lightCoord)
{
half3 lightAxis = A_ZERO;
ADirect d = aNewDirect();
d.color = _LightColor0.rgb;
d.shadow = shadow;
#if !defined(ALLOY_SUPPORT_REDLIGHTS) && defined(DIRECTIONAL_COOKIE)
aLightCookie(d, tex2D(_LightTexture0, lightCoord.xy));
#elif defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
lightAxis = normalize(unity_WorldToLight[1].xyz);
#if defined(POINT)
A_UNITY_ATTENUATION(d, _LightTexture0, lightCoord.xyz, 1.0f)
#elif defined(POINT_COOKIE)
aLightCookie(d, texCUBE(_LightTexture0, lightCoord.xyz));
A_UNITY_ATTENUATION(d, _LightTextureB0, lightCoord.xyz, 1.0f)
#elif defined(SPOT)
half4 cookie = tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5);
cookie.a *= (lightCoord.z > 0);
aLightCookie(d, cookie);
A_UNITY_ATTENUATION(d, _LightTextureB0, lightCoord.xyz, 1.0f)
#endif
#endif
#if !defined(ALLOY_SUPPORT_REDLIGHTS) || !defined(DIRECTIONAL_COOKIE)
aAreaLight(d, s, _LightColor0, lightAxis, lightVectorRange.xyz, lightVectorRange.w);
#else
d.direction = lightVectorRange.xyz;
d.color *= redLightCalculateForward(_LightTexture0, s.positionWorld, s.normalWorld, s.viewDirWorld, d.direction);
aDirectionalLight(d, s);
#endif
return aDirectLighting(d, s);
}
/// Post-processing of Unity surface data into correct format.
/// @param[in,out] s Material surface data.
void aUnitySurface(
inout ASurface s)
{
s.beckmannRoughness = aLinearToBeckmannRoughness(s.roughness);
s.specularOcclusion = aSpecularOcclusion(s.ambientOcclusion, s.NdotV);
}
/// Forward illumination with Unity inputs.
/// @param s Material surface data.
/// @param gi Unity GI descriptor.
/// @param shadow Shadow for the given direct light.
/// @return Combined lighting, emission, etc.
half4 aUnityLighting(
ASurface s,
UnityGI gi,
half shadow)
{
half4 c = 0.0h;
unityShadowCoord4 lightCoord = 0.0f;
float4 lightVectorRange = UnityWorldSpaceLightDir(s.positionWorld).xyzz;
#ifdef DIRECTIONAL
lightCoord = 0.0h;
#else
lightCoord = mul(unity_WorldToLight, unityShadowCoord4(s.positionWorld, 1.0f));
#ifndef USING_DIRECTIONAL_LIGHT
aLightRange(lightVectorRange, lightCoord);
#endif
#endif
#ifdef UNITY_PASS_FORWARDBASE
c.rgb = aUnityIndirectLighting(gi, s);
// Extract shadow with combined baked occlusion.
#ifdef HANDLE_SHADOWS_BLENDING_IN_GI
shadow = gi.light.color.g;
#endif
#endif
c.rgb += aUnityDirectLighting(s, shadow, lightVectorRange, lightCoord);
c.rgb = aHdrClamp(c.rgb);
c.a = s.opacity;
return c;
}
/// Fills the G-buffer with Unity-compatible material data.
/// @param[in] s Material surface data.
/// @param[in] gi Unity GI descriptor.
/// @param[out] outGBuffer0 RGB: albedo, A: specular occlusion.
/// @param[out] outGBuffer1 RGB: f0, A: 1-roughness.
/// @param[out] outGBuffer2 RGB: packed normal, A: 1-scattering mask.
/// @return RGB: emission, A: 1-transmission.
half4 aUnityLightingDeferred(
ASurface s,
UnityGI gi,
out half4 outGBuffer0,
out half4 outGBuffer1,
out half4 outGBuffer2)
{
half3 illum = aHdrClamp(s.emissiveColor + aUnityIndirectLighting(gi, s));
outGBuffer0 = half4(s.albedo, s.specularOcclusion);
outGBuffer1 = half4(s.f0, 1.0h - s.roughness);
outGBuffer2 = half4(s.normalWorld * 0.5h + 0.5h, s.materialType);
return half4(illum, s.subsurface);
}
/// Forward global illumination with Unity inputs.
/// @param[in,out] gi Unity GI descriptor.
/// @param[in] data GI input data.
/// @param[in] normals World-space normals.
/// @param[in] smoothness Surface smoothness.
/// @param[in] specular Surface f0.
void aUnityLightingGi(
inout UnityGI gi,
UnityGIInput data,
half3 normals,
half smoothness,
half3 specular)
{
// So we can extract shadow with baked occlusion.
#if defined(UNITY_PASS_FORWARDBASE) && defined(HANDLE_SHADOWS_BLENDING_IN_GI)
data.light.color = A_WHITE;
#endif
// Pass 1 for occlusion so we can manage that later.
#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
gi = UnityGlobalIllumination(data, 1.0h, normals);
#else
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(smoothness, data.worldViewDir, normals, specular);
gi = UnityGlobalIllumination(data, 1.0h, normals, g);
#endif
}
#endif // ALLOY_SHADERS_FRAMEWORK_UNITY_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1bd87f4acb9d203409163c16855b14ae
timeCreated: 1448830649
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,348 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
/////////////////////////////////////////////////////////////////////////////////
/// @file Utility.cginc
/// @brief Minimum functions and constants common to surfaces and particles.
/////////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_UTILITY_CGINC
#define ALLOY_SHADERS_FRAMEWORK_UTILITY_CGINC
#include "Assets/Alloy/Shaders/Config.cginc"
#include "UnityShaderVariables.cginc"
/// Defines all texture transform uniform variables, inlcuding additional transforms.
/// Spin is in radians.
#define A_SAMPLER_2D(name) \
sampler2D name; \
float4 name##_ST; \
float2 name##Velocity; \
float name##Spin; \
float name##UV;
/// Allows passing all of a texture's transform uniforms into a function.
#define A_SAMPLER_2D_INPUT(name) name, name##_ST, name##Velocity, name##UV
/// Allows accessing all of a texture's transform uniforms inside a function.
#define A_SAMPLER_PARAM(name) sampler2D name, float4 name##_ST, float2 name##Velocity, float name##UV
// NOTE: To make it rotate around a "center" point, the order of operations
// needs to be offset, rotate, scale. So that means that we have to apply
// offset & scroll first divided by tiling. Then when we apply tiling later
// it will cancel.
/// Applies our scrolling effect.
#ifdef A_TEX_SCROLL_OFF
#define A_TEX_SCROLL(name, tex) (tex)
#else
#define A_TEX_SCROLL(name, tex) (tex + ((name##Velocity * _Time.y + name##_ST.zw) / name##_ST.xy))
#endif
/// Applies our spinning effect.
#define A_TEX_SPIN(name, tex) (aRotateTextureCoordinates(name##Spin * _Time.y, tex.xy))
/// Applies Unity texture transforms plus our spinning effect.
#define A_TEX_TRANSFORM_SPIN(name, tex) (A_TEX_SPIN(name, tex + (name##_ST.zw / name##_ST.xy)) * name##_ST.xy)
/// Applies Unity texture transforms plus our spinning and scrolling effects.
#define A_TEX_TRANSFORM_SCROLL(name, tex) (A_TEX_SCROLL(name, tex) * name##_ST.xy)
/// Applies Unity texture transforms plus our spinning and scrolling effects.
#define A_TEX_TRANSFORM_SCROLL_SPIN(name, tex) (A_TEX_SPIN(name, A_TEX_SCROLL(name, tex)) * name##_ST.xy)
/// A value close to zero.
/// This is used for preventing NaNs in cases where you can divide by zero.
static const float A_EPSILON = 1e-6f;
/// Multi-component zero.
static const half3 A_ZERO = half3(0.0h, 0.0h, 0.0h);
/// Multi-component zero.
static const half4 A_ZERO4 = half4(0.0h, 0.0h, 0.0h, 0.0h);
/// Multi-component one.
static const half3 A_ONE = half3(1.0h, 1.0h, 1.0h);
/// Multi-component one.
static const half4 A_ONE4 = half4(1.0h, 1.0h, 1.0h, 1.0h);
/// Color Black.
static const half3 A_BLACK = A_ZERO;
/// Multi-component zero.
static const half4 A_BLACK4 = A_ZERO4;
/// Color White.
static const half3 A_WHITE = A_ONE;
/// Multi-component one.
static const half4 A_WHITE4 = A_ONE4;
/// X-Axis normal.
static const half3 A_AXIS_X = half3(1.0h, 0.0h, 0.0h);
/// Y-Axis normal.
static const half3 A_AXIS_Y = half3(0.0h, 1.0h, 0.0h);
/// Z-Axis normal.
static const half3 A_AXIS_Z = half3(0.0h, 0.0h, 1.0h);
/// Flat normal in tangent space.
static const half3 A_FLAT_NORMAL = A_AXIS_Z;
/// Applies 2D texture rotation around the point (0.5,0.5) in UV-space.
/// @param rotation Rotation in radians.
/// @param texcoords Texture coordinates to be rotated.
/// @return Rotated texture coordinates.
float2 aRotateTextureCoordinates(
float rotation,
float2 texcoords)
{
// Texture Rotation
// cf http://forum.unity3d.com/threads/rotation-of-texture-uvs-directly-from-a-shader.150482/#post-1031763
float2 centerOffset = float2(0.5f, 0.5f);
float sinTheta = sin(rotation);
float cosTheta = cos(rotation);
float2x2 rotationMatrix = float2x2(cosTheta, -sinTheta, sinTheta, cosTheta);
return mul(texcoords - centerOffset, rotationMatrix) + centerOffset;
}
/// Dot product of two vectors, clamped to range [0,1].
half aDotClamp(
half2 x,
half2 y)
{
return saturate(dot(x, y));
}
/// Dot product of two vectors, clamped to range [0,1].
half aDotClamp(
half3 x,
half3 y)
{
return saturate(dot(x, y));
}
/// Dot product of two vectors, clamped to range [0,1].
half aDotClamp(
half4 x,
half4 y)
{
return saturate(dot(x, y));
}
/// Screen Blends two colors.
half3 aScreenBlend(
half3 a,
half3 b)
{
return A_ONE - ((A_ONE - a) * (A_ONE - b));
}
/// Converts an LDR color from gamma-space to linear-space.
half3 aGammaToLinear(
half3 sRGB)
{
// sRGB curve approximation.
// cf http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
}
/// Converts an LDR value from gamma-space to linear-space.
half aGammaToLinear(
half sRGB)
{
return aGammaToLinear(sRGB.rrr).r;
}
/// Interpolate from one to another value.
half aLerpOneTo(
half b,
half alpha)
{
// Use lerp intrinsic for better optimization.
return lerp(1.0h, b, alpha);
}
/// Interpolate from the color white to another color.
half3 aLerpWhiteTo(
half3 b,
half alpha)
{
// Use lerp intrinsic for better optimization.
return lerp(A_WHITE, b, alpha);
}
/// Calculates a linear color's luminance.
/// @param color Linear LDR color.
/// @return Color's chromaticity.
half aLuminance(
half3 color)
{
// Linear-space luminance coefficients.
// cf https://en.wikipedia.org/wiki/Luma_(video)
return dot(color, half3(0.2126h, 0.7152h, 0.0722h));
}
/// Calculates a linear color's chromaticity.
/// @param color Linear LDR color.
/// @return Color's chromaticity.
half3 aChromaticity(
half3 color)
{
return color / max(aLuminance(color), A_EPSILON).rrr;
}
/// Clamp HDR output to avoid excess bloom and blending errors.
/// @param value Linear HDR value.
/// @return Range-limited HDR color [0,32].
half aHdrClamp(
half value)
{
#if A_USE_HDR_CLAMP
value = min(value, A_HDR_CLAMP_MAX_INTENSITY);
#endif
return value;
}
/// Clamp HDR output to avoid excess bloom and blending errors.
/// @param color Linear HDR color.
/// @return Range-limited HDR color [0,32].
half3 aHdrClamp(
half3 color)
{
#if A_USE_HDR_CLAMP
color = min(color, (A_HDR_CLAMP_MAX_INTENSITY).rrr);
#endif
return color;
}
/// Clamp HDR output to avoid excess bloom and blending errors.
/// @param color Linear HDR color.
/// @return Range-limited HDR color [0,32].
half4 aHdrClamp(
half4 color)
{
#if A_USE_HDR_CLAMP
color = min(color, (A_HDR_CLAMP_MAX_INTENSITY).rrrr);
#endif
return color;
}
/// Used to calculate a rim light effect.
/// @param weight Scales the intensity of the effect.
/// @param bias Bias rim towards constant emission.
/// @param power Rim falloff.
/// @param NdotV Normal and view vector dot product.
/// @return Rim lighting.
half aRimLight(
half weight,
half bias,
half power,
half NdotV)
{
return weight * lerp(bias, 1.0h, pow(1.0h - NdotV, power));
}
/// Gets distance from a point to an Axis-Aligned Bounding Box.
/// @param p Starting point.
/// @param aabbMin AABB min extents.
/// @param aabbMax AABB max extents.
/// @return Per-axis distance from AABB extents.
half3 aDistanceFromAabb(
half3 p,
half3 aabbMin,
half3 aabbMax)
{
return max(max(p - aabbMax, aabbMin - p), half3(0.0h, 0.0h, 0.0h));
}
/// Applies four closest lights per-vertex using Alloy's attenuation.
/// @param lightPosX Four lights' position X in world-space.
/// @param lightPosY Four lights' position Y in world-space.
/// @param lightPosZ Four lights' position Z in world-space.
/// @param lightColor0 First light color.
/// @param lightColor1 Second light color.
/// @param lightColor2 Third light color.
/// @param lightColor3 Fourth light color.
/// @param lightAttenSq Four lights' Unity attenuation.
/// @param positionWorld Position in world-space.
/// @param normalWorld Normal in world-space.
/// @return Per-vertex direct lighting.
float3 aShade4PointLights(
float4 lightPosX,
float4 lightPosY,
float4 lightPosZ,
float3 lightColor0,
float3 lightColor1,
float3 lightColor2,
float3 lightColor3,
float4 lightAttenSq,
float3 positionWorld,
float3 normalWorld)
{
// to light vectors
float4 toLightX = lightPosX - positionWorld.x;
float4 toLightY = lightPosY - positionWorld.y;
float4 toLightZ = lightPosZ - positionWorld.z;
// squared lengths
float4 lengthSq = 0;
lengthSq += toLightX * toLightX;
lengthSq += toLightY * toLightY;
lengthSq += toLightZ * toLightZ;
// NdotL
float4 ndotl = 0;
ndotl += toLightX * normalWorld.x;
ndotl += toLightY * normalWorld.y;
ndotl += toLightZ * normalWorld.z;
// correct NdotL
float4 corr = rsqrt(lengthSq);
ndotl = max (float4(0.0f, 0.0f, 0.0f, 0.0f), ndotl * corr);
// attenuation
#if A_USE_UNITY_ATTENUATION
float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
#else
// NOTE: Get something close to Alloy attenuation by undoing Unity's calculations.
// http://forum.unity3d.com/threads/easiest-way-to-change-point-light-attenuation-with-deferred-path.254337/#post-1681835
float4 invRangeSqr = lightAttenSq / 25.0f;
// Inverse Square attenuation, with light range falloff.
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p12
float4 ratio2 = lengthSq * invRangeSqr;
float4 num = saturate(float4(1.0f, 1.0f, 1.0f, 1.0f) - (ratio2 * ratio2));
float4 atten = (num * num) / (lengthSq + float4(1.0f, 1.0f, 1.0f, 1.0f));
#endif
float4 diff = ndotl * atten;
// final color
float3 col = 0;
col += lightColor0 * diff.x;
col += lightColor1 * diff.y;
col += lightColor2 * diff.z;
col += lightColor3 * diff.w;
return col;
}
/// Applies four closest lights per-vertex using Alloy's attenuation.
/// @param positionWorld Position in world-space.
/// @param normalWorld Normal in world-space.
/// @return Per-vertex direct lighting.
float3 aShade4PointLights(
float3 positionWorld,
float3 normalWorld)
{
return aShade4PointLights(
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, positionWorld, normalWorld);
}
#endif // ALLOY_SHADERS_FRAMEWORK_UTILITY_CGINC
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 9bb275497f031324c95a6fd416e6d726
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
@@ -0,0 +1,22 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Volumetric.cginc
/// @brief Volumetric fog, light shafts, etc interfaces.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_VOLUMETRIC_CGINC
#define ALLOY_SHADERS_FRAMEWORK_VOLUMETRIC_CGINC
/// Volumetric effects for base passes.
void aVolumetricBase(inout half4 color, ASurface s);
/// Volumetric effects for additive passes.
void aVolumetricAdd(inout half4 color, ASurface s);
/// Volumetric effects for multiplicative passes.
void aVolumetricMultiply(inout half4 color, ASurface s);
#endif // ALLOY_SHADERS_FRAMEWORK_VOLUMETRIC_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0a3f6e1010e5ea94b9c9d8852f08fd1f
timeCreated: 1496489792
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,92 @@
// Alloy Physical Shader Framework
// Copyright 2013-2017 RUST LLC.
// http://www.alloy.rustltd.com/
///////////////////////////////////////////////////////////////////////////////
/// @file Volumetric.cginc
/// @brief Volumetric fog, light shafts, etc implementations.
///////////////////////////////////////////////////////////////////////////////
#ifndef ALLOY_SHADERS_FRAMEWORK_VOLUMETRIC_IMPL_CGINC
#define ALLOY_SHADERS_FRAMEWORK_VOLUMETRIC_IMPL_CGINC
#include "Assets/Alloy/Shaders/Config.cginc"
#include "Assets/Alloy/Shaders/Framework/Volumetric.cginc"
#include "UnityShaderVariables.cginc"
#ifdef A_VOLUMETRIC_PASS
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
#ifndef A_POSITION_WORLD_ON
#define A_POSITION_WORLD_ON
#endif
#elif defined(VTRANSPARENCY_ON)
#ifndef A_SCREEN_UV_ON
#define A_SCREEN_UV_ON
#endif
#ifndef A_VIEW_DEPTH_ON
#define A_VIEW_DEPTH_ON
#endif
#endif
#if !defined(A_FOG_ON) && (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
#define A_FOG_ON
#endif
#endif
void aVolumetricBase(
inout half4 color,
ASurface s)
{
#ifdef A_VOLUMETRIC_PASS
UNITY_APPLY_FOG_COLOR(s.fogCoord, color, unity_FogColor);
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
color = VaporApplyFog(s.positionWorld, color);
#elif defined(VTRANSPARENCY_ON)
float4 data = s.screenPosition;
data.z = s.viewDepth;
color = VolumetricTransparencyBase(color, data);
#endif
#endif
}
void aVolumetricAdd(
inout half4 color,
ASurface s)
{
#ifdef A_VOLUMETRIC_PASS
UNITY_APPLY_FOG_COLOR(s.fogCoord, color, A_BLACK4);
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
color = VaporApplyFogAdd(s.positionWorld, color);
#elif defined(VTRANSPARENCY_ON)
float4 data = s.screenPosition;
data.z = s.viewDepth;
color = VolumetricTransparencyAdd(color, data);
#endif
#endif
}
void aVolumetricMultiply(
inout half4 color,
ASurface s)
{
#ifdef A_VOLUMETRIC_PASS
UNITY_APPLY_FOG_COLOR(s.fogCoord, color, A_WHITE4);
#if defined(VAPOR_TRANSLUCENT_FOG_ON)
color = VaporApplyFogFade(s.positionWorld, color, A_WHITE);
#elif defined(VTRANSPARENCY_ON)
// float4 data = s.screenPosition;
//
// data.z = s.viewDepth;
// color = VolumetricTransparencyAdd(color, data);
#endif
#endif
}
#endif // ALLOY_SHADERS_FRAMEWORK_VOLUMETRIC_IMPL_CGINC
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 185744146fc75a8458c2dc17f105132c
timeCreated: 1496490406
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant: