336 lines
14 KiB
Plaintext
336 lines
14 KiB
Plaintext
Shader "Fishing3D/Fish/Opaque Bump Gold" {
|
|
Properties {
|
|
_Color ("主色调", Vector) = (1,1,1,1)
|
|
_SpecColor ("高光颜色", Vector) = (1,1,1,1)
|
|
_FlowColor ("流动颜色", Vector) = (1,1,1,1)
|
|
_GrayValue ("GrayValue", Range(0, 1)) = 0
|
|
_HitColorValue ("击中颜色显示", Range(0, 1)) = 0
|
|
_HitSaturation ("击中颜色饱和", Range(-10, 10)) = 0.2
|
|
_HitColor ("击中最终颜色", Vector) = (1,0,0,1)
|
|
_PreHitColor ("pre hit color", Vector) = (1,0,0,1)
|
|
_TestGrayFlag ("gray flag", Range(0, 1)) = 1
|
|
_TestGrayColor ("gray color", Vector) = (0.1,0.1,0.1,0.1)
|
|
_HitAniValue ("击中动画渐变", Range(0, 1)) = 0
|
|
_FrozenColorValue ("冰冻颜色显示", Range(0, 1)) = 0
|
|
_FrozenSaturation ("冰冻颜色饱和", Range(-10, 10)) = 0.2
|
|
_FrozenColor ("冰冻颜色", Vector) = (0.564,1,1,1)
|
|
_Alpha ("透明度", Float) = 1
|
|
_MainTex ("主贴图(RGB)", 2D) = "White" {}
|
|
_AlphaTex ("Alpha贴图(RA)", 2D) = "White" {}
|
|
_AlphaA_Strength ("Alpha A Strength", Range(0, 2)) = 1
|
|
_AlphaB_Strength ("Alpha B Strength", Range(0, 2)) = 1
|
|
_BumpMap ("法线贴图", 2D) = "Bump" {}
|
|
_Cube ("反射Cubemap", Cube) = "Black" {}
|
|
_NoiseTex ("噪声贴图", 2D) = "White" {}
|
|
_Albedo ("环境光强度", Range(0, 1)) = 0.5
|
|
_Shininess ("亮度", Range(0.01, 3)) = 1.5
|
|
_Gloss ("光泽度", Range(0, 1)) = 0.5
|
|
_Reflection ("反射值", Range(0, 1)) = 0.5
|
|
_FrezFalloff ("高光边缘衰减", Range(0, 10)) = 4
|
|
_FlowStrenth ("流动强度", Float) = 1
|
|
_FlowTime ("流动增量时间", Float) = 0
|
|
_Scale ("阴影缩放", Float) = 1
|
|
}
|
|
//DummyShaderTextExporter
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"RenderType" = "Opaque"
|
|
"RenderPipeline" = "UniversalPipeline"
|
|
"Queue" = "Geometry"
|
|
}
|
|
LOD 200
|
|
|
|
Pass
|
|
{
|
|
Name "ForwardLit"
|
|
Tags { "LightMode" = "UniversalForward" }
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
|
|
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
|
#pragma multi_compile_fog
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
|
|
|
CBUFFER_START(UnityPerMaterial)
|
|
float4 _Color;
|
|
float4 _SpecColor;
|
|
float4 _FlowColor;
|
|
float _GrayValue;
|
|
float _HitColorValue;
|
|
float _HitSaturation;
|
|
float4 _HitColor;
|
|
float4 _PreHitColor;
|
|
float _TestGrayFlag;
|
|
float4 _TestGrayColor;
|
|
float _HitAniValue;
|
|
float _FrozenColorValue;
|
|
float _FrozenSaturation;
|
|
float4 _FrozenColor;
|
|
float _Alpha;
|
|
float4 _MainTex_ST;
|
|
float4 _AlphaTex_ST;
|
|
float _AlphaA_Strength;
|
|
float _AlphaB_Strength;
|
|
float4 _BumpMap_ST;
|
|
float4 _NoiseTex_ST;
|
|
float _Albedo;
|
|
half _Shininess;
|
|
float _Gloss;
|
|
float _Reflection;
|
|
float _FrezFalloff;
|
|
float _FlowStrenth;
|
|
float _FlowTime;
|
|
float _Scale;
|
|
CBUFFER_END
|
|
|
|
TEXTURE2D(_MainTex);
|
|
SAMPLER(sampler_MainTex);
|
|
TEXTURE2D(_AlphaTex);
|
|
SAMPLER(sampler_AlphaTex);
|
|
TEXTURE2D(_BumpMap);
|
|
SAMPLER(sampler_BumpMap);
|
|
TEXTURECUBE(_Cube);
|
|
SAMPLER(sampler_Cube);
|
|
TEXTURE2D(_NoiseTex);
|
|
SAMPLER(sampler_NoiseTex);
|
|
|
|
struct Attributes
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
float4 tangentOS : TANGENT;
|
|
float4 texcoord : TEXCOORD0;
|
|
float4 texcoord1 : TEXCOORD1;
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float2 uv2 : TEXCOORD1;
|
|
float2 uv_bump : TEXCOORD2;
|
|
float3 positionWS : TEXCOORD3;
|
|
float3 normalWS : TEXCOORD4;
|
|
float3 viewDirWS : TEXCOORD5;
|
|
float3 reflectWS : TEXCOORD6;
|
|
float3 tangentWS : TEXCOORD7;
|
|
float3 binormalWS : TEXCOORD8;
|
|
float fogCoord : TEXCOORD9;
|
|
float4 shadowCoord : TEXCOORD10;
|
|
};
|
|
|
|
Varyings vert(Attributes input)
|
|
{
|
|
Varyings output;
|
|
|
|
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
|
|
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
|
|
|
|
output.positionCS = vertexInput.positionCS;
|
|
output.uv = TRANSFORM_TEX(input.texcoord, _MainTex);
|
|
output.uv2 = TRANSFORM_TEX(input.texcoord1, _AlphaTex);
|
|
output.uv_bump = TRANSFORM_TEX(input.texcoord, _BumpMap);
|
|
output.positionWS = vertexInput.positionWS;
|
|
output.normalWS = normalInput.normalWS;
|
|
output.viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
|
|
output.tangentWS = normalInput.tangentWS;
|
|
output.binormalWS = cross(output.normalWS, output.tangentWS) * input.tangentOS.w;
|
|
|
|
// 计算反射向量
|
|
float3 viewDirWS = normalize(output.viewDirWS);
|
|
float3 normalWS = normalize(output.normalWS);
|
|
output.reflectWS = reflect(-viewDirWS, normalWS);
|
|
|
|
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
|
|
output.shadowCoord = GetShadowCoord(vertexInput);
|
|
|
|
return output;
|
|
}
|
|
|
|
half4 frag(Varyings input) : SV_Target
|
|
{
|
|
// 采样主贴图
|
|
half4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
|
|
half4 albedo = mainTex * _Color*3;
|
|
|
|
// 法线贴图采样和转换
|
|
half4 bumpTex = SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, input.uv_bump);
|
|
half3 tangentNormal = UnpackNormal(bumpTex);
|
|
|
|
// 切线空间转世界空间
|
|
half3 worldTangent = normalize(input.tangentWS);
|
|
half3 worldBinormal = normalize(input.binormalWS);
|
|
half3 worldNormalRaw = normalize(input.normalWS);
|
|
half3 worldNormal = normalize(tangentNormal.x * worldTangent +
|
|
tangentNormal.y * worldBinormal +
|
|
tangentNormal.z * worldNormalRaw);
|
|
|
|
// 流动效果
|
|
float2 flowUV = input.uv + float2(_FlowTime * _FlowStrenth, 0);
|
|
half noise = SAMPLE_TEXTURE2D(_NoiseTex, sampler_NoiseTex, flowUV).r;
|
|
|
|
// 获取光照信息
|
|
InputData lightingInput = (InputData)0;
|
|
lightingInput.positionWS = input.positionWS;
|
|
lightingInput.normalWS = worldNormal;
|
|
lightingInput.viewDirectionWS = normalize(input.viewDirWS);
|
|
lightingInput.shadowCoord = input.shadowCoord;
|
|
lightingInput.fogCoord = input.fogCoord;
|
|
|
|
// 获取主光源
|
|
Light mainLight = GetMainLight(lightingInput.shadowCoord);
|
|
float3 lightDir = mainLight.direction;
|
|
float3 lightColor = mainLight.color;
|
|
float shadowAttenuation = mainLight.shadowAttenuation;
|
|
|
|
// 漫反射
|
|
float diff = saturate(dot(worldNormal, lightDir));
|
|
float3 diffuse = diff * lightColor * albedo.rgb * _Albedo;
|
|
|
|
// 高光(金色增强)
|
|
float3 halfDir = normalize(lightDir + lightingInput.viewDirectionWS);
|
|
float spec = pow(saturate(dot(worldNormal, halfDir)), _Shininess * 128) * _Gloss;
|
|
float3 specular = spec * _SpecColor.rgb * lightColor * 1.5; // 增强金色高光
|
|
|
|
// 反射
|
|
float3 reflectDir = reflect(-lightingInput.viewDirectionWS, worldNormal);
|
|
half3 reflection = SAMPLE_TEXTURECUBE(_Cube, sampler_Cube, reflectDir).rgb * _Reflection;
|
|
|
|
// Alpha计算
|
|
half4 alphaTex = SAMPLE_TEXTURE2D(_AlphaTex, sampler_AlphaTex, input.uv2);
|
|
half alpha = (alphaTex.r * _AlphaA_Strength + alphaTex.a * _AlphaB_Strength) * _Alpha;
|
|
|
|
// 颜色组合
|
|
half3 finalColor = diffuse + specular + reflection;
|
|
finalColor += _FlowColor.rgb * noise * _FlowStrenth * 0.1;
|
|
|
|
// 金色色调增强
|
|
finalColor = lerp(finalColor, finalColor * half3(1.3, 0.95, 0.5), 0.4);
|
|
|
|
// 灰度值
|
|
if (_GrayValue > 0)
|
|
{
|
|
half gray = dot(finalColor, half3(0.3, 0.59, 0.11));
|
|
finalColor = lerp(finalColor, half3(gray, gray, gray), _GrayValue);
|
|
}
|
|
|
|
// 击中效果
|
|
half hitLerp = saturate(_HitColorValue + _HitAniValue);
|
|
half3 hitColor = lerp(0, _HitColor.rgb, hitLerp);
|
|
half grayHit = dot(hitColor, half3(0.3, 0.59, 0.11));
|
|
hitColor = lerp(hitColor, half3(grayHit, grayHit, grayHit), _HitSaturation);
|
|
finalColor += hitColor;
|
|
|
|
// 冰冻效果
|
|
half3 frozenLerp = lerp(hitColor, _FrozenColor.rgb, _FrozenColorValue);
|
|
half grayFrozen = dot(frozenLerp, half3(0.3, 0.59, 0.11));
|
|
frozenLerp = lerp(frozenLerp, half3(grayFrozen, grayFrozen, grayFrozen), _FrozenSaturation);
|
|
finalColor += frozenLerp;
|
|
|
|
// 灰度测试标志
|
|
finalColor += lerp(frozenLerp, _TestGrayColor.rgb, 1 - _TestGrayFlag);
|
|
|
|
// 阴影
|
|
finalColor = finalColor * shadowAttenuation * _Scale;
|
|
|
|
// 菲涅尔边缘光
|
|
float fresnel = pow(1.0 - abs(dot(worldNormal, lightingInput.viewDirectionWS)), 10 - _FrezFalloff);
|
|
finalColor += albedo.rgb * half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) * fresnel;
|
|
|
|
// 雾效
|
|
finalColor = MixFog(finalColor, input.fogCoord);
|
|
|
|
return half4(finalColor, alpha);
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
|
|
// 阴影投射Pass
|
|
Pass
|
|
{
|
|
Name "ShadowCaster"
|
|
Tags { "LightMode" = "ShadowCaster" }
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex ShadowPassVertex
|
|
#pragma fragment ShadowPassFragment
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
// Shadows.hlsl 里用到了 LerpWhiteTo,它定义在 core 包的 CommonMaterial.hlsl 中。
|
|
// URP 自带的 Lit 是先 include 了 LitInput.hlsl(里面含 CommonMaterial.hlsl)才没问题,
|
|
// 这个自定义 shader 缺这一步,编译就会报 "undeclared identifier 'LerpWhiteTo'",这里补上。
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
|
|
|
|
struct Attributes
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
};
|
|
|
|
Varyings ShadowPassVertex(Attributes input)
|
|
{
|
|
Varyings output;
|
|
float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
output.positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, input.normalOS, float3(0,0,0)));
|
|
return output;
|
|
}
|
|
|
|
half4 ShadowPassFragment(Varyings input) : SV_TARGET
|
|
{
|
|
return 0;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
// 深度写入Pass
|
|
Pass
|
|
{
|
|
Name "DepthOnly"
|
|
Tags { "LightMode" = "DepthOnly" }
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex DepthOnlyVertex
|
|
#pragma fragment DepthOnlyFragment
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
|
|
struct Attributes
|
|
{
|
|
float4 positionOS : POSITION;
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
};
|
|
|
|
Varyings DepthOnlyVertex(Attributes input)
|
|
{
|
|
Varyings output;
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
return output;
|
|
}
|
|
|
|
half4 DepthOnlyFragment(Varyings input) : SV_TARGET
|
|
{
|
|
return 0;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
FallBack "Universal Render Pipeline/Lit"
|
|
} |