433 lines
13 KiB
Plaintext
433 lines
13 KiB
Plaintext
// Upgrade NOTE: upgraded instancing buffer 'MyProperties' to new syntax.
|
|
|
|
Shader "UVFree/StandardMetallic/Top-Bottom-Texture Non-Batched" {
|
|
Properties {
|
|
// Triplanar space, for UI
|
|
[HideInInspector] _TriplanarSpace("Triplanar Space", Float) = 0.0
|
|
|
|
_TexPower("Texture Power", Range(0, 20)) = 10.0
|
|
_TopMultiplier ("Top Multiplier", Range(0,8)) = 1.0
|
|
_BottomMultiplier ("Bottom Multiplier", Range(0,8)) = 0.0
|
|
_VertexColorStrength("Vertex Color Strength", Range(0,1)) = 1.0
|
|
|
|
// FRONT
|
|
|
|
_Color ("Color", Color) = (1,1,1,1)
|
|
_MainTex ("Albedo (RGB)", 2D) = "white" {}
|
|
|
|
_Glossiness ("Smoothness", Range(0,1)) = 0.0
|
|
[Gamma] _Metallic ("Metallic", Range(0,1)) = 0.0
|
|
_MetallicGlossMap("Metallic", 2D) = "black" {}
|
|
_UsingMetallicGlossMap("Using Metallic Gloss Map", float) = 0.0
|
|
|
|
_BumpScale("Bump Scale", Float) = 1.0
|
|
_BumpMap("Normal Map", 2D) = "bump" {}
|
|
|
|
_EmissionColor("Emission Color", Color) = (0,0,0)
|
|
_EmissionMap("Emission", 2D) = "white" {}
|
|
|
|
[HideInInspector] _EmissionScaleUI("Scale", Float) = 0.0
|
|
[HideInInspector] _EmissionColorUI("Color", Color) = (1,1,1)
|
|
|
|
// TOP
|
|
|
|
_TopColor ("Color", Color) = (1,1,1,1)
|
|
_TopMainTex ("Albedo (RGB)", 2D) = "white" {}
|
|
|
|
_TopGlossiness ("Smoothness", Range(0,1)) = 0.0
|
|
[Gamma] _TopMetallic ("Metallic", Range(0,1)) = 0.0
|
|
_TopMetallicGlossMap("Metallic", 2D) = "black" {}
|
|
_TopUsingMetallicGlossMap("Using Metallic Gloss Map", float) = 0.0
|
|
|
|
_TopBumpScale("Bump Scale", Float) = 1.0
|
|
_TopBumpMap("Normal Map", 2D) = "bump" {}
|
|
|
|
_TopEmissionColor("Emission Color", Color) = (0,0,0)
|
|
_TopEmissionMap("Emission", 2D) = "white" {}
|
|
|
|
[HideInInspector] _TopEmissionScaleUI("Scale", Float) = 0.0
|
|
[HideInInspector] _TopEmissionColorUI("Color", Color) = (1,1,1)
|
|
|
|
// BOTTOM
|
|
// bottom is ignored unless _UVFREE_BOTTOM shader feature is turned on
|
|
|
|
_BottomColor ("Color", Color) = (1,1,1,1)
|
|
_BottomMainTex ("Albedo (RGB)", 2D) = "white" {}
|
|
|
|
_BottomGlossiness ("Smoothness", Range(0,1)) = 0.5
|
|
[Gamma] _BottomMetallic ("Metallic", Range(0,1)) = 0.0
|
|
_BottomMetallicGlossMap("Metallic", 2D) = "black" {}
|
|
_BottomUsingMetallicGlossMap("Using Metallic Gloss Map", float) = 0.0
|
|
|
|
_BottomBumpScale("Bump Scale", Float) = 1.0
|
|
_BottomBumpMap("Normal Map", 2D) = "bump" {}
|
|
|
|
_BottomEmissionColor("Emission Color", Color) = (0,0,0)
|
|
_BottomEmissionMap("Emission", 2D) = "white" {}
|
|
|
|
[HideInInspector] _BottomEmissionScaleUI("Scale", Float) = 0.0
|
|
[HideInInspector] _BottomEmissionColorUI("Color", Color) = (1,1,1)
|
|
}
|
|
SubShader {
|
|
Tags {
|
|
"RenderType"="Opaque"
|
|
"PerformanceChecks"="False"
|
|
"DisableBatching"="True"
|
|
}
|
|
|
|
LOD 300
|
|
|
|
CGPROGRAM
|
|
#pragma target 3.0
|
|
|
|
// Physically based Standard lighting model, and enable shadows on all light types
|
|
#pragma surface surf Standard vertex:vert fullforwardshadows
|
|
#pragma shader_feature _UVFREE_LOCAL
|
|
#pragma shader_feature _EMISSION
|
|
#pragma shader_feature _METALLICGLOSSMAP
|
|
#pragma shader_feature _UVFREE_BOTTOM
|
|
#include "UnityCG.cginc"
|
|
|
|
// Uncomment to enable experimental feature which flips
|
|
// backward textures. Note: Causes some normals to be flipped.
|
|
// #define _UVFREE_FLIP_BACKWARD_TEXTURES
|
|
|
|
// Comment out following line to omit vertex colors
|
|
#define _UVFREE_VERTEX_COLOR
|
|
|
|
// Instanced Properties
|
|
// https://docs.unity3d.com/Manual/GPUInstancing.html
|
|
UNITY_INSTANCING_BUFFER_START (MyProperties)
|
|
UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
|
|
#define _Color_arr MyProperties
|
|
UNITY_INSTANCING_BUFFER_END(MyProperties)
|
|
|
|
half _TexPower;
|
|
|
|
// FRONT
|
|
sampler2D _MainTex;
|
|
float4 _MainTex_ST;
|
|
sampler2D _BumpMap;
|
|
half _BumpScale;
|
|
fixed _Metallic;
|
|
fixed _Glossiness;
|
|
|
|
|
|
fixed _UsingMetallicGlossMap;
|
|
#ifdef _METALLICGLOSSMAP
|
|
sampler2D _MetallicGlossMap;
|
|
#endif
|
|
|
|
#ifdef _EMISSION
|
|
sampler2D _EmissionMap;
|
|
sampler2D _TopEmissionMap;
|
|
half4 _EmissionColor;
|
|
half4 _TopEmissionColor;
|
|
|
|
#endif
|
|
|
|
// TOP
|
|
half _TopMultiplier;
|
|
fixed4 _TopColor;
|
|
sampler2D _TopMainTex;
|
|
float4 _TopMainTex_ST;
|
|
sampler2D _TopBumpMap;
|
|
half _TopBumpScale;
|
|
fixed _TopMetallic;
|
|
fixed _TopGlossiness;
|
|
|
|
#ifdef _METALLICGLOSSMAP
|
|
sampler2D _TopMetallicGlossMap;
|
|
fixed _TopUsingMetallicGlossMap;
|
|
#endif
|
|
|
|
// BOTTOM
|
|
#ifdef _UVFREE_BOTTOM
|
|
half _BottomMultiplier;
|
|
fixed4 _BottomColor;
|
|
sampler2D _BottomMainTex;
|
|
float4 _BottomMainTex_ST;
|
|
sampler2D _BottomBumpMap;
|
|
half _BottomBumpScale;
|
|
|
|
fixed _BottomUsingMetallicGlossMap;
|
|
#ifdef _METALLICGLOSSMAP
|
|
sampler2D _BottomMetallicGlossMap;
|
|
#endif
|
|
|
|
fixed _BottomMetallic;
|
|
fixed _BottomGlossiness;
|
|
|
|
#ifdef _EMISSION
|
|
sampler2D _BottomEmissionMap;
|
|
half4 _BottomEmissionColor;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef _UVFREE_VERTEX_COLOR
|
|
fixed _VertexColorStrength;
|
|
#endif
|
|
|
|
struct Input {
|
|
fixed3 powerNormal;
|
|
fixed3 normal;
|
|
|
|
float3 worldPos;
|
|
|
|
#ifdef _UVFREE_VERTEX_COLOR
|
|
fixed4 color:COLOR;
|
|
#endif
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
void vert (inout appdata_full v, out Input o) {
|
|
|
|
UNITY_INITIALIZE_OUTPUT(Input,o);
|
|
|
|
#ifdef _UVFREE_LOCAL
|
|
o.normal = v.normal;
|
|
fixed3 powerNormal = v.normal;
|
|
fixed3 weightedPowerNormal = v.normal;
|
|
#else
|
|
fixed3 worldNormal = normalize(mul(unity_ObjectToWorld, fixed4(v.normal, 0)).xyz);
|
|
o.normal = worldNormal;
|
|
fixed3 powerNormal = worldNormal;
|
|
fixed3 weightedPowerNormal = worldNormal;
|
|
|
|
#endif
|
|
|
|
// texpower sets the sharpness
|
|
powerNormal = pow(abs(powerNormal), _TexPower);
|
|
powerNormal = max(powerNormal, 0.0001);
|
|
powerNormal /= dot(powerNormal, 1.0);
|
|
o.powerNormal = powerNormal;
|
|
|
|
#if _UVFREE_BOTTOM
|
|
weightedPowerNormal.y = max(0.0, weightedPowerNormal.y)*_TopMultiplier + min(0.0, weightedPowerNormal.y)*_BottomMultiplier;
|
|
#else
|
|
weightedPowerNormal.y = max(0.0, weightedPowerNormal.y)*_TopMultiplier + min(0.0, weightedPowerNormal.y);
|
|
#endif
|
|
|
|
weightedPowerNormal = pow(abs(weightedPowerNormal), _TexPower);
|
|
weightedPowerNormal = max(weightedPowerNormal, 0.0001);
|
|
weightedPowerNormal /= dot(weightedPowerNormal, 1.0);
|
|
|
|
fixed3 lerpedPowerNormal = lerp(powerNormal, weightedPowerNormal, weightedPowerNormal.y);
|
|
|
|
#ifdef _UVFREE_LOCAL
|
|
|
|
v.tangent.xyz =
|
|
cross(v.normal, fixed3(0.0,sign(v.normal.x),0.0)) * (lerpedPowerNormal.x)
|
|
+ cross(v.normal, fixed3(0.0,0.0,sign(v.normal.y))) * (lerpedPowerNormal.y)
|
|
+ cross(v.normal, fixed3(0.0,sign(v.normal.z),0.0)) * (lerpedPowerNormal.z)
|
|
;
|
|
|
|
v.tangent.w = dot(-v.normal, lerpedPowerNormal);
|
|
|
|
#else
|
|
|
|
v.tangent.xyz =
|
|
cross(v.normal, mul(unity_WorldToObject,fixed4(0.0,sign(worldNormal.x),0.0,0.0)).xyz * (lerpedPowerNormal.x))
|
|
+ cross(v.normal, mul(unity_WorldToObject,fixed4(0.0,0.0,sign(worldNormal.y),0.0)).xyz * (lerpedPowerNormal.y))
|
|
+ cross(v.normal, mul(unity_WorldToObject,fixed4(0.0,sign(worldNormal.z),0.0,0.0)).xyz * (lerpedPowerNormal.z))
|
|
;
|
|
|
|
v.tangent.w = dot(-worldNormal, lerpedPowerNormal);
|
|
|
|
#endif
|
|
}
|
|
|
|
void surf (Input IN, inout SurfaceOutputStandard o) {
|
|
|
|
fixed topLerp = smoothstep(0.0, 1.0, _TopMultiplier);
|
|
|
|
#if _UVFREE_BOTTOM
|
|
fixed bottomLerp = smoothstep(0.0, 1.0, _BottomMultiplier);
|
|
#endif
|
|
|
|
fixed3 weightedPowerNormal = IN.normal;
|
|
#if _UVFREE_BOTTOM
|
|
weightedPowerNormal.y = max(0.0, weightedPowerNormal.y)*_TopMultiplier + min(0.0, weightedPowerNormal.y)*_BottomMultiplier;
|
|
#else
|
|
weightedPowerNormal.y = max(0.0, weightedPowerNormal.y)*_TopMultiplier + min(0.0, weightedPowerNormal.y);
|
|
#endif
|
|
|
|
weightedPowerNormal = pow(abs(weightedPowerNormal), _TexPower);
|
|
weightedPowerNormal = max(weightedPowerNormal, 0.0001);
|
|
weightedPowerNormal /= dot(weightedPowerNormal, 1.0);
|
|
|
|
fixed topBottomLerp = sign(IN.normal.y)*0.5 + 0.5;
|
|
fixed yLerp = weightedPowerNormal.y;
|
|
|
|
// TRIPLANAR UVs BASED ON WORLD OR LOCAL POSITION
|
|
//
|
|
|
|
#ifdef _UVFREE_LOCAL
|
|
float3 pos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz;
|
|
|
|
float2 posX = pos.zy;
|
|
float2 posY = pos.xz;
|
|
float2 posZ = float2(-pos.x, pos.y);
|
|
#else
|
|
float2 posX = IN.worldPos.zy;
|
|
float2 posY = IN.worldPos.xz;
|
|
float2 posZ = float2(-IN.worldPos.x, IN.worldPos.y);
|
|
#endif
|
|
|
|
float2 xUV = posX * _MainTex_ST.xy + _MainTex_ST.zw;
|
|
|
|
float2 yUVTop = posY * _TopMainTex_ST.xy + _TopMainTex_ST.zw;
|
|
|
|
#ifdef _UVFREE_BOTTOM
|
|
float2 yUVBottom = posY * _BottomMainTex_ST.xy + _BottomMainTex_ST.zw;
|
|
#endif
|
|
|
|
float2 yUV = posY * _MainTex_ST.xy + _MainTex_ST.zw;
|
|
float2 zUV = posZ * _MainTex_ST.xy + _MainTex_ST.zw;
|
|
|
|
#ifdef _UVFREE_FLIP_BACKWARD_TEXTURES
|
|
fixed3 powerSign = sign(IN.normal);
|
|
xUV.x *= powerSign.x;
|
|
zUV.x *= powerSign.z;
|
|
yUV.y *= powerSign.y;
|
|
yUVTop.y *= powerSign.y;
|
|
#ifdef _UVFREE_BOTTOM
|
|
yUVBottom.y *= powerSign.y;
|
|
#endif
|
|
#endif
|
|
|
|
// DIFFUSE
|
|
//
|
|
fixed4 tint = UNITY_ACCESS_INSTANCED_PROP(_Color_arr, _Color);
|
|
fixed4 texX = tex2D(_MainTex, xUV) * tint;
|
|
fixed4 texY = tex2D(_MainTex, yUV) * tint;
|
|
fixed4 texZ = tex2D(_MainTex, zUV) * tint;
|
|
|
|
fixed4 texTop = tex2D(_TopMainTex, yUVTop) * _TopColor;
|
|
texTop = lerp(texY, texTop, topLerp);
|
|
|
|
#if _UVFREE_BOTTOM
|
|
fixed4 texBottom = tex2D(_BottomMainTex, yUVBottom) * _BottomColor;
|
|
texBottom = lerp(texY, texBottom, bottomLerp);
|
|
texTop = lerp(texBottom, texTop, topBottomLerp);
|
|
#else
|
|
texTop = lerp(texY, texTop, topBottomLerp);
|
|
#endif
|
|
|
|
fixed4 tex =
|
|
lerp(texX * IN.powerNormal.x, texTop * weightedPowerNormal.x, yLerp)
|
|
+ lerp(texY * IN.powerNormal.y, texTop * weightedPowerNormal.y, yLerp)
|
|
+ lerp(texZ * IN.powerNormal.z, texTop * weightedPowerNormal.z, yLerp)
|
|
;
|
|
|
|
#ifdef _UVFREE_VERTEX_COLOR
|
|
tex *= lerp(fixed4(1.0,1.0,1.0,1.0), IN.color, _VertexColorStrength);
|
|
#endif
|
|
|
|
o.Albedo = max(fixed3(0.0, 0.0, 0.0), tex.rgb);
|
|
o.Alpha = tex.a;
|
|
|
|
// NORMAL
|
|
//
|
|
fixed3 bumpX = UnpackScaleNormal(tex2D(_BumpMap, xUV), _BumpScale);
|
|
fixed3 bumpY = UnpackScaleNormal(tex2D(_BumpMap, yUV), _BumpScale);
|
|
fixed3 bumpZ = UnpackScaleNormal(tex2D(_BumpMap, zUV), _BumpScale);
|
|
|
|
fixed3 bumpTop = UnpackScaleNormal(tex2D(_TopBumpMap, yUVTop), _TopBumpScale);
|
|
bumpTop = lerp(bumpY, bumpTop, topLerp);
|
|
|
|
#if _UVFREE_BOTTOM
|
|
fixed3 bumpBottom = UnpackScaleNormal(tex2D(_BottomBumpMap, yUVBottom), _BottomBumpScale);
|
|
bumpBottom = lerp(bumpY, bumpBottom, bottomLerp);
|
|
bumpTop = lerp(bumpBottom, bumpTop, topBottomLerp);
|
|
#else
|
|
bumpTop = lerp(bumpY, bumpTop, topBottomLerp);
|
|
#endif
|
|
|
|
o.Normal = normalize(
|
|
lerp(bumpX * IN.powerNormal.x, bumpTop * weightedPowerNormal.x, yLerp)
|
|
+ lerp(bumpY * IN.powerNormal.y, bumpTop * weightedPowerNormal.y, yLerp)
|
|
+ lerp(bumpZ * IN.powerNormal.z, bumpTop * weightedPowerNormal.z, yLerp)
|
|
);
|
|
|
|
// METALLIC/GLOSS
|
|
//
|
|
|
|
fixed2 mgX = fixed2(_Metallic, _Glossiness);
|
|
fixed2 mgY = mgX;
|
|
fixed2 mgZ = mgX;
|
|
fixed2 mgTop = fixed2(_TopMetallic, _TopGlossiness);
|
|
|
|
#ifdef _UVFREE_BOTTOM
|
|
fixed2 mgBottom = fixed2(_BottomMetallic, _BottomGlossiness);
|
|
#endif
|
|
|
|
#ifdef _METALLICGLOSSMAP
|
|
#if SHADER_API_D3D9 && _EMISSION
|
|
// skip for top and bottom, because there are not enough samplers
|
|
#else
|
|
mgX = lerp(mgX, tex2D(_MetallicGlossMap, xUV).ra, _UsingMetallicGlossMap);
|
|
mgY = lerp(mgY, tex2D(_MetallicGlossMap, yUV).ra, _UsingMetallicGlossMap);
|
|
mgZ = lerp(mgZ, tex2D(_MetallicGlossMap, zUV).ra, _UsingMetallicGlossMap);
|
|
|
|
mgTop = lerp(mgTop, tex2D(_TopMetallicGlossMap, yUVTop).ra, _TopUsingMetallicGlossMap);
|
|
#ifdef _UVFREE_BOTTOM
|
|
mgBottom = lerp(mgBottom, tex2D(_BottomMetallicGlossMap, yUVBottom).ra, _BottomUsingMetallicGlossMap);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
mgTop = lerp(mgY, mgTop, topLerp);
|
|
|
|
#ifdef _UVFREE_BOTTOM
|
|
mgBottom = lerp(mgY, mgBottom, bottomLerp);
|
|
mgTop = lerp(mgBottom, mgTop, topBottomLerp);
|
|
#else
|
|
mgTop = lerp(mgY, mgTop, topBottomLerp);
|
|
#endif
|
|
|
|
fixed2 mg =
|
|
lerp(mgX * IN.powerNormal.x, mgTop * weightedPowerNormal.x, yLerp)
|
|
+ lerp(mgY * IN.powerNormal.y, mgTop * weightedPowerNormal.y, yLerp)
|
|
+ lerp(mgZ * IN.powerNormal.z, mgTop * weightedPowerNormal.z, yLerp)
|
|
;
|
|
|
|
o.Metallic = mg.x;
|
|
o.Smoothness = mg.y;
|
|
|
|
// EMISSION
|
|
//
|
|
|
|
#ifdef _EMISSION
|
|
half3 emissionX = tex2D(_EmissionMap, xUV).rgb * _EmissionColor.rgb;
|
|
half3 emissionY = tex2D(_EmissionMap, yUV).rgb * _EmissionColor.rgb;
|
|
|
|
half3 emissionYTop = tex2D(_TopEmissionMap, yUVTop).rgb * _TopEmissionColor.rgb;
|
|
emissionYTop = lerp(emissionY, emissionYTop, topLerp);
|
|
|
|
#ifdef _UVFREE_BOTTOM
|
|
half3 emissionYBottom = tex2D(_BottomEmissionMap, yUVBottom).rgb * _BottomEmissionColor.rgb;
|
|
emissionYBottom = lerp(emissionY, emissionYBottom, bottomLerp);
|
|
emissionYTop = lerp(emissionYBottom, emissionYTop, topBottomLerp);
|
|
#else
|
|
emissionYTop = lerp(emissionY, emissionYTop, topBottomLerp);
|
|
#endif
|
|
|
|
half3 emissionZ = tex2D(_EmissionMap, zUV).rgb * _EmissionColor.rgb;
|
|
|
|
o.Emission +=
|
|
lerp(emissionX * IN.powerNormal.x, emissionYTop * weightedPowerNormal.x, yLerp)
|
|
+ lerp(emissionY * IN.powerNormal.y, emissionYTop * weightedPowerNormal.y, yLerp)
|
|
+ lerp(emissionZ * IN.powerNormal.z, emissionYTop * weightedPowerNormal.z, yLerp)
|
|
;
|
|
#endif
|
|
|
|
}
|
|
ENDCG
|
|
}
|
|
FallBack "Diffuse"
|
|
CustomEditor "UVFreePBRShaderTopBottomGUI"
|
|
}
|
|
|