补齐备份工程打开依赖
This commit is contained in:
@@ -0,0 +1,522 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
Shader "Hidden/WaterCausticsModules/Effect" {
|
||||
Properties {
|
||||
// --- Scope
|
||||
_WCE_ClipOutside ("Clip Outside Volume", Int) = 1
|
||||
_WCE_UseImageMask ("Use Image Mask", Int) = 0
|
||||
[NoScaleOffset]_WCE_ImageMaskTex ("Texture", 2D) = "white" { }
|
||||
[Enum(UnityEngine.Rendering.CullMode)] _CullMode ("Cull Mode", Int) = 2
|
||||
// --- Texture
|
||||
[NoScaleOffset]_WCE_CausticsTex ("Caustics Texture", 2D) = "black" { }
|
||||
_WCE_TexChannels ("Channel", Vector) = (0, 1, 2, 0)
|
||||
_WCE_TexRotateSinCos ("Rotation Sin and Cos", Vector) = (0, 1, 0, 0)
|
||||
_WCE_TilingSeed ("Tiling Seed", Int) = -1
|
||||
_WCE_TilingRot ("Tiling Rot", Float) = 0.02
|
||||
_WCE_TilingHard ("Tiling Hard", Float) = 0.85
|
||||
// --- Dimension
|
||||
_WCE_Density ("Density", Float) = 0.2
|
||||
_WCE_SurfaceY ("Water Surface Y", Float) = 2
|
||||
_WCE_SurfFadeCoef ("Surface Fade Coef", Float) = 2
|
||||
_WCE_SurfFadeStart ("Surface Fade Start", Float) = 0
|
||||
_WCE_DepthFadeStart ("Depth Fade Start", Float) = 0
|
||||
_WCE_DepthFadeCoef ("Depth Fade Coef", Float) = 0.01
|
||||
_WCE_DistanceFadeStart ("Distance Fade Start", Float) = 0
|
||||
_WCE_DistanceFadeCoef ("Distance Fade Coef", Float) = 0.01
|
||||
// --- Effect
|
||||
_WCE_IntensityMainLit ("Main Light Intensity", Range(0, 50)) = 1
|
||||
_WCE_IntensityAddLit ("Additional Lights Intensity", Range(0, 50)) = 1
|
||||
[ToggleOff(_RECEIVE_SHADOWS_OFF)] _RECEIVE_SHADOWS_OFF ("Receive Shadow", Float) = 1
|
||||
_WCE_ShadowIntensity ("Shadow Intensity", Range(0, 1)) = 1
|
||||
_WCE_ColorShift ("ColorShift", Vector) = (0.004, -0.001, 0, 0)
|
||||
_WCE_LitSaturation ("Light Saturation", Range(0, 2)) = 0.2
|
||||
_WCE_MultiplyByTex ("Multiply Color", Range(0, 1)) = 1
|
||||
// --- Normal Atten
|
||||
_WCE_NormalAtten ("Normal Atten Intensity", Range(0, 1)) = 1
|
||||
_WCE_NormalAttenRate ("Normal Atten Rate", Range(1, 8)) = 2
|
||||
_WCE_TransparentBack ("Transparent Backside", Range(0, 1)) = 0
|
||||
_WCE_BacksideShadow ("Backside Shadow", Range(0, 1)) = 0
|
||||
// --- Depth Buffer
|
||||
_ZWrite ("ZWrite", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Int) = 4
|
||||
_OffsetFactor ("Offset Factor", float) = 0
|
||||
_OffsetUnits ("Offset Units", float) = 0
|
||||
// --- Stencil Buffer
|
||||
_StencilRef ("Ref [0-255]", Range(0, 255)) = 0
|
||||
_StencilReadMask ("Read Mask [0-255]", Range(0, 255)) = 255
|
||||
_StencilWriteMask ("Write Mask [0-255]", Range(0, 255)) = 255
|
||||
[Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Comp", Int) = 8
|
||||
[Enum(UnityEngine.Rendering.StencilOp)] _StencilPass ("Pass", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.StencilOp)] _StencilFail ("ZFail", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.StencilOp)] _StencilZFail ("ZFail", Int) = 0
|
||||
// --- Blend
|
||||
[Enum(UnityEngine.Rendering.BlendMode)] _BlendSrcFactor ("SrcFactor", Int) = 1
|
||||
[Enum(UnityEngine.Rendering.BlendMode)] _BlendDstFactor ("DstFactor", Int) = 1
|
||||
// ※ Properties は SRPBatcher に必須
|
||||
|
||||
}
|
||||
|
||||
SubShader {
|
||||
LOD 0
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Transparent" "Queue" = "Transparent" "DisableBatching" = "True" "IgnoreProjector" = "True" }
|
||||
|
||||
Pass {
|
||||
Name "WCE_EffectPass"
|
||||
Tags { "LightMode" = "WCE_EffectPass" }
|
||||
|
||||
Blend [_BlendSrcFactor] [_BlendDstFactor]
|
||||
ZWrite [_ZWrite]
|
||||
ZTest [_ZTest]
|
||||
Offset [_OffsetFactor], [_OffsetUnits]
|
||||
Cull [_CullMode]
|
||||
Stencil {
|
||||
Ref [_StencilRef]
|
||||
ReadMask [_StencilReadMask]
|
||||
WriteMask [_StencilWriteMask]
|
||||
Comp [_StencilComp]
|
||||
Pass [_StencilPass]
|
||||
Fail [_StencilFail]
|
||||
ZFail [_StencilZFail]
|
||||
}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma exclude_renderers d3d11_9x
|
||||
#pragma target 3.5
|
||||
|
||||
#define WCE_EFFECT_SHADER
|
||||
#define REQUIRE_OPAQUE_TEXTURE
|
||||
|
||||
#pragma multi_compile_local _ _WCE_ONE_PASS_NORMAL _WCE_ONE_PASS_DEPTH
|
||||
#pragma multi_compile_local_fragment _ WCE_DEBUG_NORMAL WCE_DEBUG_DEPTH WCE_DEBUG_FACING WCE_DEBUG_CAUSTICS WCE_DEBUG_AREA
|
||||
#if defined(_WCE_ONE_PASS_NORMAL) || defined(_WCE_ONE_PASS_DEPTH)
|
||||
#define REQUIRE_DEPTH_TEXTURE
|
||||
#if defined(_WCE_ONE_PASS_NORMAL)
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
|
||||
#endif
|
||||
#else
|
||||
#define WCE_EACH_MESH
|
||||
#endif
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
|
||||
#if VERSION_GREATER_EQUAL(11, 0)
|
||||
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#else
|
||||
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS
|
||||
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#endif
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS
|
||||
|
||||
// ---- ※ URP14のDeferredで影が現れない問題応急処置
|
||||
// ※ TODO URP14のバージョンが上がったら修正されたか要確認
|
||||
#if UNITY_VERSION >= 202220 // Unity2022.2.0 URP14.0 以上
|
||||
#if !defined(_RECEIVE_SHADOWS_OFF)
|
||||
#define _ADDITIONAL_LIGHT_SHADOWS
|
||||
#endif
|
||||
#else
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#endif
|
||||
// ----
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
||||
|
||||
// ---- 使用しない
|
||||
// #pragma multi_compile_fragment _ LIGHTMAP_ON
|
||||
// #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING
|
||||
// #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK
|
||||
// #pragma multi_compile_fragment _ _MIXED_LIGHTING_SUBTRACTIVE
|
||||
// ----
|
||||
|
||||
#if UNITY_VERSION >= 202120 // Unity2021.2.0 URP12.0 以上
|
||||
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
|
||||
#pragma multi_compile_fragment _ _LIGHT_LAYERS
|
||||
#pragma multi_compile_fragment _ _LIGHT_COOKIES
|
||||
#endif
|
||||
#if UNITY_VERSION >= 202220 // Unity2022.2.0 URP14.0 以上
|
||||
#pragma multi_compile_fragment _ _FORWARD_PLUS
|
||||
#endif
|
||||
|
||||
#pragma multi_compile_fog
|
||||
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
|
||||
#define _USE_FOG
|
||||
#endif
|
||||
|
||||
#include "WaterCausticsEffectCommon.hlsl"
|
||||
#pragma multi_compile_local_fragment _ _RECEIVE_SHADOWS_OFF
|
||||
|
||||
struct appdata {
|
||||
float4 vertex : POSITION;
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float3 normal : NORMAL;
|
||||
#else
|
||||
uint vID : SV_VertexID;
|
||||
#endif
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 posClip : SV_POSITION;
|
||||
float4 posScrn : TEXCOORD0;
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float3 posWld : TEXCOORD1;
|
||||
float3 posEffect : TEXCOORD2;
|
||||
float3 normalWS : TEXCOORD3;
|
||||
#if defined(_USE_FOG)
|
||||
float viewDepth : TEXCOORD4;
|
||||
#endif
|
||||
#endif
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float _WCE_Density;
|
||||
int3 _WCE_TexChannels;
|
||||
float2 _WCE_TexRotateSinCos;
|
||||
int _WCE_TilingSeed;
|
||||
float _WCE_TilingRot;
|
||||
float _WCE_TilingHard;
|
||||
float _WCE_SurfaceY;
|
||||
float _WCE_SurfFadeStart;
|
||||
float _WCE_SurfFadeCoef;
|
||||
float _WCE_DepthFadeStart;
|
||||
float _WCE_DepthFadeCoef;
|
||||
float _WCE_DistanceFadeStart;
|
||||
float _WCE_DistanceFadeCoef;
|
||||
half _WCE_IntensityMainLit;
|
||||
half _WCE_IntensityAddLit;
|
||||
float2 _WCE_ColorShift;
|
||||
half _WCE_LitSaturation;
|
||||
half _WCE_MultiplyByTex;
|
||||
half _WCE_NormalAtten;
|
||||
half _WCE_NormalAttenRate;
|
||||
half _WCE_TransparentBack;
|
||||
half _WCE_BacksideShadow;
|
||||
half _WCE_ShadowIntensity;
|
||||
int _WCE_ClipOutside;
|
||||
int _WCE_UseImageMask;
|
||||
CBUFFER_END
|
||||
|
||||
#if defined(WCE_EACH_MESH)
|
||||
CBUFFER_START(FrequentlyUpdateVariables)
|
||||
float4x4 _WCE_WorldToObjMatrix;
|
||||
CBUFFER_END
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ Fill Clipped Hole
|
||||
bool WCE_intersectPlaneAndLine(float3 ptA, float3 ptB, float3 planeP, float3 planeN, bool isAllowEndOnPlane, out float3 PT) {
|
||||
float dotPA = dot(ptA - planeP, planeN);
|
||||
float dotPB = dot(ptB - planeP, planeN);
|
||||
bool isCross = (sign(dotPA) != sign(dotPB));
|
||||
bool isPtOnPlane = (dotPA == 0 || dotPB == 0);
|
||||
[branch] if (isCross && (isAllowEndOnPlane || !isPtOnPlane)) {
|
||||
float3 AB = ptB - ptA;
|
||||
float dif = abs(dotPA) + abs(dotPB);
|
||||
float rate = abs(dotPA) / dif;
|
||||
PT = ptA + AB * rate;
|
||||
return true;
|
||||
} else {
|
||||
PT = float3(0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float3 WCE_camDirWS() {
|
||||
return -UNITY_MATRIX_V[2].xyz;
|
||||
}
|
||||
|
||||
float3 WCE_viewDirWS(float3 posWS) {
|
||||
return (unity_OrthoParams.w == 0) ? normalize(posWS - _WorldSpaceCameraPos) : WCE_camDirWS();
|
||||
}
|
||||
float3 WCE_viewDirRawWS(float3 posWS) {
|
||||
return (unity_OrthoParams.w == 0) ? posWS - _WorldSpaceCameraPos : WCE_camDirWS();
|
||||
}
|
||||
|
||||
float4 WCE_fillClippedHole(uint vID) {
|
||||
const float3 pts[8] = {
|
||||
float3(-0.5, -0.5, -0.5), float3(0.5, -0.5, -0.5), float3(-0.5, 0.5, -0.5), float3(0.5, 0.5, -0.5),
|
||||
float3(-0.5, -0.5, 0.5), float3(0.5, -0.5, 0.5), float3(-0.5, 0.5, 0.5), float3(0.5, 0.5, 0.5),
|
||||
};
|
||||
const uint2 idxs [12] = {
|
||||
uint2(0, 4), uint2(1, 5), uint2(2, 6), uint2(3, 7), uint2(0, 2), uint2(1, 3), uint2(4, 6), uint2(5, 7), uint2(0, 1), uint2(4, 5), uint2(2, 3), uint2(6, 7),
|
||||
};
|
||||
// ObliqueMatrix対応のためClipSpaceの端点からNearClipPlaneを得る
|
||||
float near = UNITY_NEAR_CLIP_VALUE; // ← D3D11/Metal/Vulkan/Switch:1, GLCore/GLES:-1
|
||||
float3 p0 = ComputeWorldSpacePosition(float4(0, 0, near, 1), UNITY_MATRIX_I_VP);
|
||||
float3 p1 = ComputeWorldSpacePosition(float4(1, 0, near, 1), UNITY_MATRIX_I_VP);
|
||||
float3 p2 = ComputeWorldSpacePosition(float4(0, 1, near, 1), UNITY_MATRIX_I_VP);
|
||||
float3 planeN_WS = cross(p1 - p0, p2 - p0);
|
||||
planeN_WS *= sign(dot(planeN_WS, -WCE_camDirWS()));
|
||||
|
||||
float3 planeN = TransformWorldToObjectNormal(planeN_WS, true);
|
||||
float3 planeP = TransformWorldToObject(p0);
|
||||
float3 rightV = TransformWorldToObjectDir(p1 - p0, true);
|
||||
|
||||
uint cnt = 0u;
|
||||
float3 center = float3(0, 0, 0);
|
||||
float4 intersectPts[6];
|
||||
[unroll(12)] for (uint i = 0u; i < 12u; i++) {
|
||||
float3 ptA = pts [idxs [i].x];
|
||||
float3 ptB = pts [idxs [i].y];
|
||||
float3 PT;
|
||||
bool isIntersect = WCE_intersectPlaneAndLine(ptA, ptB, planeP, planeN, (i < 4), PT);
|
||||
[branch] if (isIntersect) {
|
||||
intersectPts [cnt].xyz = PT;
|
||||
center += PT;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
center /= cnt;
|
||||
|
||||
float3 outputPt = center;
|
||||
[branch] if (cnt >= 3u && vID <= cnt) {
|
||||
[unroll(6)] for (uint k = 0u; k < cnt; k++) {
|
||||
// 時計回りにwを設定 -2~+2
|
||||
float3 v = normalize(intersectPts [k].xyz - center);
|
||||
intersectPts [k].w = - (dot(v, rightV) - 1.0) * sign(dot(cross(v, rightV), planeN));
|
||||
}
|
||||
// ソート
|
||||
[unroll(5)] for (uint m = 0u; m < cnt - 1u; m++) {
|
||||
[unroll(5)] for (uint o = m + 1u; o < cnt; o++) {
|
||||
[branch] if (intersectPts[m].w < intersectPts[o].w) {
|
||||
float4 swap = intersectPts[m];
|
||||
intersectPts[m] = intersectPts[o];
|
||||
intersectPts[o] = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
outputPt = intersectPts[vID % cnt].xyz;
|
||||
}
|
||||
float4 posClip = TransformObjectToHClip(outputPt);
|
||||
posClip.z = UNITY_NEAR_CLIP_VALUE * posClip.w;
|
||||
return posClip;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ Vertex Shader
|
||||
v2f vert(appdata v) {
|
||||
v2f o = (v2f)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
#if defined(WCE_EACH_MESH)
|
||||
// [Each Mesh]
|
||||
float4 posClip = TransformObjectToHClip(v.vertex.xyz);
|
||||
float3 posWld = TransformObjectToWorld(v.vertex.xyz);
|
||||
float4 posScrn = ComputeScreenPos(posClip);
|
||||
o.posClip = posClip;
|
||||
o.posWld = posWld;
|
||||
o.posScrn = posScrn;
|
||||
o.posEffect = mul(_WCE_WorldToObjMatrix, float4(posWld, 1)).xyz;
|
||||
o.normalWS = TransformObjectToWorldNormal(v.normal, true);
|
||||
#if defined(_USE_FOG)
|
||||
o.viewDepth = -TransformWorldToView(posWld).z;
|
||||
#endif
|
||||
#else
|
||||
// [At Once]
|
||||
float4 posClip;
|
||||
[branch]if (v.vID < 8u) {
|
||||
posClip = TransformObjectToHClip(v.vertex.xyz);
|
||||
} else {
|
||||
posClip = WCE_fillClippedHole(v.vID - 8u);
|
||||
}
|
||||
float4 posScrn = ComputeScreenPos(posClip);
|
||||
o.posClip = posClip;
|
||||
o.posScrn = posScrn;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ Reconstruct World Pos and Normal
|
||||
float WCE_fixReversedZ(float Depth) {
|
||||
#if UNITY_REVERSED_Z
|
||||
return 1 - Depth;
|
||||
#else
|
||||
return Depth;
|
||||
#endif
|
||||
}
|
||||
|
||||
float3 WCE_reconstructPosWS(float2 screenUV, float rawDepth) {
|
||||
#if !UNITY_REVERSED_Z
|
||||
rawDepth = lerp(UNITY_NEAR_CLIP_VALUE, 1, rawDepth);
|
||||
#endif
|
||||
return ComputeWorldSpacePosition(screenUV, rawDepth, UNITY_MATRIX_I_VP);
|
||||
}
|
||||
|
||||
bool WCE_checkOutside(float3 posES) {
|
||||
return (abs(posES.x) > 0.5 || abs(posES.y) > 0.5 || abs(posES.z) > 0.5);
|
||||
}
|
||||
|
||||
#if !defined(WCE_EACH_MESH)
|
||||
#define RECONSTRUCT_NORMAL_HQ 1
|
||||
half3 WCE_reconstructNormalWS(float2 screenUV, float3 posWS, float rdC) {
|
||||
#if (!RECONSTRUCT_NORMAL_HQ)
|
||||
return normalize(cross(ddy(posWS), ddx(posWS)));
|
||||
#else
|
||||
float2 offsetU = float2(_ScreenParams.z - 1, 0);
|
||||
float2 offsetV = float2(0, _ScreenParams.w - 1);
|
||||
float2 uvN = screenUV + offsetV;
|
||||
float2 uvS = screenUV - offsetV;
|
||||
float2 uvE = screenUV + offsetU;
|
||||
float2 uvW = screenUV - offsetU;
|
||||
float rdN = SampleSceneDepth(uvN);
|
||||
float rdS = SampleSceneDepth(uvS);
|
||||
float rdE = SampleSceneDepth(uvE);
|
||||
float rdW = SampleSceneDepth(uvW);
|
||||
float3 vV = abs(rdN - rdC) < abs(rdS - rdC) ? WCE_reconstructPosWS(uvN, rdN) - posWS : posWS - WCE_reconstructPosWS(uvS, rdS);
|
||||
float3 vU = abs(rdE - rdC) < abs(rdW - rdC) ? WCE_reconstructPosWS(uvE, rdE) - posWS : posWS - WCE_reconstructPosWS(uvW, rdW);
|
||||
return normalize(cross(vV, vU));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
half3 WCE_getNormal(v2f IN, float2 screenUV, float3 posWS, float rawDepth) {
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float3 normal = IN.normalWS; // VFACEセマンティクスでの向きの取得はメッシュのデータに不具合があると正しくないことがあるので廃止
|
||||
normal *= -sign(dot(normal, WCE_viewDirRawWS(posWS)));
|
||||
return normal;
|
||||
#elif defined(_WCE_ONE_PASS_NORMAL)
|
||||
float3 normal = SampleSceneNormals(screenUV);
|
||||
#if VERSION_LOWER(10, 9) || (VERSION_GREATER_EQUAL(11, 0) && VERSION_LOWER(12, 0))
|
||||
// ViewSpaceで保存されているURPのバージョン対応
|
||||
normal.z *= -1;
|
||||
normal = mul((float3x3)UNITY_MATRIX_I_V, normal).xyz;
|
||||
normal = normalize(normal);
|
||||
#endif
|
||||
// normal *= -sign(dot(normal, WCE_viewDirWS(posWS))+0.07 );
|
||||
normal *= -sign(dot(normal, WCE_viewDirRawWS(posWS)));
|
||||
return normal;
|
||||
#else
|
||||
return WCE_reconstructNormalWS(screenUV, posWS, rawDepth);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ Fog (Oblique Projection Supported)
|
||||
#if defined(_USE_FOG)
|
||||
float WCE_computeFogFactorZ0ToFar(float z) {
|
||||
#if defined(FOG_LINEAR)
|
||||
return saturate(z * unity_FogParams.z + unity_FogParams.w);
|
||||
#elif defined(FOG_EXP) || defined(FOG_EXP2)
|
||||
return unity_FogParams.x * z;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
float WCE_calcFog(float viewDepth) {
|
||||
float nearToFarZ = max(viewDepth - _ProjectionParams.y, 0);
|
||||
return ComputeFogIntensity(WCE_computeFogFactorZ0ToFar(nearToFarZ));
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
#if defined(WCE_EACH_MESH)
|
||||
// [Each Mesh]
|
||||
#define WCE_clipOutside (_WCE_ClipOutside == 1)
|
||||
#else
|
||||
// [At Once]
|
||||
#define WCE_clipOutside true
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ Fragment
|
||||
#define CLR_COL half4(0, 0, 0, 0)
|
||||
|
||||
TEXTURE2D(_WCE_CausticsTex);
|
||||
TEXTURE2D(_WCE_ImageMaskTex);
|
||||
SAMPLER(sampler_WCE_CausticsTex);
|
||||
SAMPLER(sampler_WCE_ImageMaskTex);
|
||||
|
||||
half4 frag(v2f IN) : SV_Target {
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
|
||||
|
||||
// ---------- WorldPos
|
||||
float2 screenUV = IN.posScrn.xy / IN.posScrn.w;
|
||||
#if defined(WCE_EACH_MESH)
|
||||
// [Each Mesh]
|
||||
float3 posWS = IN.posWld;
|
||||
float3 posES = IN.posEffect;
|
||||
float rawDepth = 0.5;
|
||||
#else
|
||||
// [At Once]
|
||||
float rawDepth = SampleSceneDepth(screenUV);
|
||||
float3 posWS = WCE_reconstructPosWS(screenUV, rawDepth);
|
||||
float3 posES = TransformWorldToObject(posWS);
|
||||
#endif
|
||||
|
||||
// ---------- Debug Info
|
||||
#if defined(WCE_DEBUG_NORMAL) || defined(WCE_DEBUG_DEPTH) || defined(WCE_DEBUG_FACING) || defined(WCE_DEBUG_CAUSTICS) || defined(WCE_DEBUG_AREA)
|
||||
if ((WCE_clipOutside && WCE_checkOutside(posES)) || rawDepth == UNITY_RAW_FAR_CLIP_VALUE) discard;
|
||||
#endif
|
||||
#if defined(WCE_DEBUG_NORMAL)
|
||||
return half4(pow(saturate(WCE_getNormal(IN, screenUV, posWS, rawDepth) * 0.5 + 0.5), 4) * 0.9, 1);
|
||||
#elif defined(WCE_DEBUG_DEPTH)
|
||||
float debugDepth = -TransformWorldToView(posWS).z * _ProjectionParams.w;
|
||||
return half4(pow(abs(debugDepth), 0.7).xxx, 1);
|
||||
#elif defined(WCE_DEBUG_FACING)
|
||||
float3 n = WCE_getNormal(IN, screenUV, posWS, rawDepth);
|
||||
float b = dot(-n, WCE_viewDirWS(posWS));
|
||||
return half4((saturate(pow(abs(b), 2) * 0.5)).xxx, 1);
|
||||
#elif defined(WCE_DEBUG_CAUSTICS)
|
||||
_WCE_MultiplyByTex = 0;
|
||||
#elif defined(WCE_DEBUG_AREA)
|
||||
_WCE_MultiplyByTex = 0;
|
||||
#endif
|
||||
|
||||
// ---------- Clip Outside
|
||||
[branch] if ((WCE_clipOutside && WCE_checkOutside(posES)) || rawDepth == UNITY_RAW_FAR_CLIP_VALUE) return CLR_COL;
|
||||
|
||||
// ---------- Atten Start
|
||||
float atten = 1; // halfだとVRシングルパスで不安定?
|
||||
const float ATTEN_TH = 0.001;
|
||||
|
||||
// ---------- Fog
|
||||
#if defined(_USE_FOG)
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float viewDepth = IN.viewDepth;
|
||||
#else
|
||||
float viewDepth = -TransformWorldToView(posWS).z;
|
||||
#endif
|
||||
atten *= WCE_calcFog(viewDepth);
|
||||
#endif
|
||||
|
||||
// ---------- Distance Fade
|
||||
float3 viewDir = posWS - _WorldSpaceCameraPos; // ←ifに入れるとVR SinglePassでエラー
|
||||
[branch] if (atten > ATTEN_TH && _WCE_DistanceFadeCoef > 0.0001f) {
|
||||
atten *= smoothstep(0, 1, 1 - (length(viewDir) - _WCE_DistanceFadeStart) * _WCE_DistanceFadeCoef);
|
||||
}
|
||||
|
||||
// ---------- Image Mask
|
||||
[branch] if (atten > ATTEN_TH && _WCE_UseImageMask != 0) {
|
||||
atten *= _WCE_ImageMaskTex.Sample(sampler_WCE_ImageMaskTex, posES.xz + 0.5).r;
|
||||
}
|
||||
|
||||
// ---------- Atten End
|
||||
[branch] if (atten <= ATTEN_TH) return CLR_COL;
|
||||
_WCE_IntensityMainLit *= atten;
|
||||
_WCE_IntensityAddLit *= atten;
|
||||
|
||||
// ---------- Normal
|
||||
half3 normalWS = WCE_getNormal(IN, screenUV, posWS, rawDepth);
|
||||
|
||||
// ---------- Caustics
|
||||
half3 c = WCE_EffectCore(posWS, normalWS, screenUV, _WCE_CausticsTex, sampler_WCE_CausticsTex, _WCE_TexRotateSinCos, _WCE_TexChannels, _WCE_TilingSeed, _WCE_TilingRot, _WCE_TilingHard, _WCE_Density, _WCE_SurfaceY, _WCE_SurfFadeStart, _WCE_SurfFadeCoef, _WCE_DepthFadeStart, _WCE_DepthFadeCoef, _WCE_IntensityMainLit, _WCE_IntensityAddLit, _WCE_ShadowIntensity, _WCE_ColorShift, _WCE_LitSaturation, _WCE_NormalAtten, _WCE_NormalAttenRate, _WCE_TransparentBack, _WCE_BacksideShadow);
|
||||
|
||||
// ---------- Multiply Opaque Tex
|
||||
[branch] if (_WCE_MultiplyByTex > 0) {
|
||||
c *= 1 - (1 - SHADERGRAPH_SAMPLE_SCENE_COLOR(screenUV)) * _WCE_MultiplyByTex;
|
||||
}
|
||||
return half4(c, 1);
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
Fallback "Hidden/InternalErrorShader"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 348afebc23c3c6e4c8f05f2ea8f758fc
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,377 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#ifndef WCE_COMMON_INCLUDED
|
||||
#define WCE_COMMON_INCLUDED
|
||||
|
||||
#if defined(_LIGHT_COOKIES)
|
||||
#pragma warning(disable : 3595) // ループ内勾配命令warning
|
||||
#endif
|
||||
|
||||
#if !defined(SHADERGRAPH_PREVIEW)
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "hextiling.hlsl"
|
||||
#endif
|
||||
|
||||
#define WCE_LIT_DIR_MIN_Y 0.1
|
||||
|
||||
#if defined(WCE_USE_SAMPLER2D_INSTEAD_TEXTURE2D)
|
||||
#define WCE_TEX_ARGS(texName) sampler2D texName
|
||||
#define WCE_TEX_SAMPLE_GRAD(st, texName, uv, dx, dy) tex2Dgrad(st.texName, uv, dx, dy)
|
||||
#define WCE_TEX_STRUCT(texName) sampler2D texName
|
||||
#define WCE_TEX_STORE(st, texName) st.texName = texName
|
||||
#else
|
||||
#define WCE_TEX_ARGS(texName) TEXTURE2D(texName), SAMPLER(texName##SS)
|
||||
#define WCE_TEX_SAMPLE_GRAD(st, texName, uv, dx, dy) SAMPLE_TEXTURE2D_GRAD(st.texName, st.texName##SS, uv, dx, dy)
|
||||
#define WCE_TEX_STRUCT(texName) TEXTURE2D(texName); SAMPLER(texName##SS)
|
||||
#define WCE_TEX_STORE(st, texName) st.texName = texName; st.texName##SS = texName##SS
|
||||
#endif
|
||||
|
||||
|
||||
struct WCE_SamplingData {
|
||||
WCE_TEX_STRUCT(CausticsTex);
|
||||
float3 pos;
|
||||
float3 posDDX;
|
||||
float3 posDDY;
|
||||
int3 channel;
|
||||
float2 colShift;
|
||||
float2x2 rotMatrix;
|
||||
bool useTiling;
|
||||
uint tilingSeed;
|
||||
float tilingRot;
|
||||
float tilingHard;
|
||||
float2 dx;
|
||||
float2 dy;
|
||||
};
|
||||
|
||||
struct WCE_Lit {
|
||||
half3 dir;
|
||||
half3 dirDDX;
|
||||
half3 dirDDY;
|
||||
half3 color;
|
||||
half atten;
|
||||
half shadow;
|
||||
};
|
||||
|
||||
struct WCE_CommonData {
|
||||
float3 posW;
|
||||
float3 posWdX;
|
||||
float3 posWdY;
|
||||
half3 normWS;
|
||||
float2 scrnUV;
|
||||
half shadow;
|
||||
half saturation;
|
||||
half normAtten;
|
||||
half normRate;
|
||||
half transparent;
|
||||
half backShadow;
|
||||
float depthSign;
|
||||
half depthFade;
|
||||
uint layer;
|
||||
float3 posOnSurf;
|
||||
};
|
||||
|
||||
|
||||
// Mainライト事前チェック 水面通過時、光線が上向き(1)か下向き(-1)か / RenderingLayerMaskチェック
|
||||
void WCE_mainLitPreCheck(WCE_CommonData dt, out float signLitY, out bool result) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
signLitY = -1;
|
||||
result = true;
|
||||
#else
|
||||
Light l = GetMainLight();
|
||||
signLitY = sign(l.direction.y);
|
||||
#ifdef _LIGHT_LAYERS
|
||||
result = (dt.depthSign == signLitY) && IsMatchingLightLayer(l.layerMask, dt.layer);
|
||||
#else
|
||||
result = (dt.depthSign == signLitY);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Addライト事前チェック 水面通過時、光線が上向き(1)か下向き(-1)か / RenderingLayerMaskチェック
|
||||
void WCE_addLitPreCheck(uint idx, WCE_CommonData dt, out float signLitY, out bool result) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
signLitY = -1;
|
||||
result = false;
|
||||
#else
|
||||
Light l = GetAdditionalLight(idx, dt.posOnSurf);
|
||||
signLitY = sign(l.direction.y);
|
||||
#ifdef _LIGHT_LAYERS
|
||||
result = (dt.depthSign == signLitY) && IsMatchingLightLayer(l.layerMask, dt.layer);
|
||||
#else
|
||||
result = (dt.depthSign == signLitY);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Main Light Data
|
||||
void WCE_getMainLitData(WCE_CommonData dt, out WCE_Lit lit) {
|
||||
lit = (WCE_Lit)0;
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
lit.dir = normalize(half3(0, 1, -0.4));
|
||||
lit.color = half3(1, 1, 1);
|
||||
lit.atten = lit.shadow = 1;
|
||||
#else
|
||||
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN)) && !defined(_RECEIVE_SHADOWS_OFF)
|
||||
#if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
||||
float4 shadowCoord = float4(dt.scrnUV.xy, 0, 1);
|
||||
#else
|
||||
float4 shadowCoord = TransformWorldToShadowCoord(dt.posW);
|
||||
#endif
|
||||
Light l = GetMainLight(shadowCoord, dt.posW, half4(1, 1, 1, 1));
|
||||
#else
|
||||
Light l = GetMainLight();
|
||||
#endif
|
||||
lit.dir = lit.dirDDX = lit.dirDDY = l.direction;
|
||||
lit.color = l.color;
|
||||
lit.atten = l.distanceAttenuation;
|
||||
lit.shadow = l.shadowAttenuation;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Additional Light Data
|
||||
void WCE_getAddLitData(uint idx, WCE_CommonData dt, out WCE_Lit lit) {
|
||||
lit = (WCE_Lit)0;
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
lit.dir = lit.color = lit.dirDDX = lit.dirDDY = half3(0, -1, 0);
|
||||
lit.atten = lit.shadow = 0;
|
||||
#else
|
||||
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
|
||||
Light l = GetAdditionalLight(idx, dt.posW, half4(1, 1, 1, 1));
|
||||
#else
|
||||
Light l = GetAdditionalLight(idx, dt.posW);
|
||||
#endif
|
||||
lit.dir = l.direction;
|
||||
lit.color = l.color;
|
||||
lit.atten = l.distanceAttenuation;
|
||||
lit.shadow = l.shadowAttenuation;
|
||||
lit.dirDDX = GetAdditionalLight(idx, dt.posWdX).direction;
|
||||
lit.dirDDY = GetAdditionalLight(idx, dt.posWdY).direction;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// 水面付近減衰
|
||||
half WCE_SurfFade(float depthAbs, float SurfFadeStart, float SurfFadeCoef) {
|
||||
return saturate((depthAbs - SurfFadeStart) * SurfFadeCoef);
|
||||
}
|
||||
|
||||
// 深さによる減衰
|
||||
half WCE_depthFade(float depthAbs, float DepthFadeStart, float DepthFadeCoef) {
|
||||
return saturate(1 - (depthAbs - DepthFadeStart) * DepthFadeCoef);
|
||||
}
|
||||
|
||||
// ライト角度での減衰
|
||||
half WCE_litDirAtten(half3 litDir) {
|
||||
return saturate((abs(litDir.y) - WCE_LIT_DIR_MIN_Y) / (0.4 - WCE_LIT_DIR_MIN_Y));
|
||||
}
|
||||
|
||||
|
||||
// 減衰をまとめる
|
||||
half WCE_calcAtten(WCE_CommonData dt, WCE_Lit lit, half dotLN) {
|
||||
half dot = saturate(dotLN) + saturate(-dotLN) * dt.transparent;
|
||||
dot = pow(abs(dot), dt.normRate);
|
||||
dot = 1 - (1 - dot) * dt.normAtten;
|
||||
half litDirAtten = WCE_litDirAtten(lit.dir);
|
||||
return lit.atten * lit.shadow * dot * litDirAtten * dt.depthFade;
|
||||
}
|
||||
|
||||
|
||||
// 彩度調整
|
||||
half3 WCE_adjustSaturation(half3 litColor, WCE_CommonData dt) {
|
||||
half gray = dot(litColor, half3(0.299, 0.587, 0.114));
|
||||
return lerp(gray.xxx, litColor, dt.saturation.xxx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
half3 WCE_sampleColGrad(WCE_SamplingData smpDt, float2 uvG) {
|
||||
float2 uvR = uvG - smpDt.colShift;
|
||||
float2 uvB = uvG + smpDt.colShift;
|
||||
half3 c;
|
||||
c.r = WCE_TEX_SAMPLE_GRAD(smpDt, CausticsTex, uvR, smpDt.dx, smpDt.dy)[smpDt.channel[0]];
|
||||
c.g = WCE_TEX_SAMPLE_GRAD(smpDt, CausticsTex, uvG, smpDt.dx, smpDt.dy)[smpDt.channel[1]];
|
||||
c.b = WCE_TEX_SAMPLE_GRAD(smpDt, CausticsTex, uvB, smpDt.dx, smpDt.dy)[smpDt.channel[2]];
|
||||
return c;
|
||||
}
|
||||
|
||||
half3 WCE_sampleRandomTiling(WCE_SamplingData smpDt, float2 uvG) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
return WCE_sampleColGrad(smpDt, uvG);
|
||||
#else
|
||||
float2 uv1, uv2, uv3;
|
||||
float3 w;
|
||||
HEX_TILING_GetUV(uvG, smpDt.tilingRot, smpDt.tilingSeed, uv1, uv2, uv3, w);
|
||||
half3 c1 = WCE_sampleColGrad(smpDt, uv1);
|
||||
half3 c2 = WCE_sampleColGrad(smpDt, uv2);
|
||||
half3 c3 = WCE_sampleColGrad(smpDt, uv3);
|
||||
return HEX_TILING_MixColor(smpDt.tilingHard, c1, c2, c3, w);
|
||||
#endif
|
||||
}
|
||||
|
||||
// テクスチャサンプリング
|
||||
half3 WCE_sampleCausticsTex(WCE_SamplingData smpDt, WCE_Lit lit, float signLitY) {
|
||||
// ※litDir.yの絶対値がWCE_LIT_DIR_MIN_Y以下の場合はattenが0なので0除算は無視
|
||||
// smpDt.posは水面基準の位置(Density乗算済み) yは深さ
|
||||
float2 uvG = (lit.dir.xz / lit.dir.y) * smpDt.pos.y + smpDt.pos.xz;
|
||||
float2 uvDDX = (lit.dirDDX.xz / lit.dirDDX.y) * smpDt.posDDX.y + smpDt.posDDX.xz;
|
||||
float2 uvDDY = (lit.dirDDY.xz / lit.dirDDY.y) * smpDt.posDDY.y + smpDt.posDDY.xz;
|
||||
uvG = mul(smpDt.rotMatrix, uvG);
|
||||
smpDt.dx = mul(smpDt.rotMatrix, uvDDX) - uvG;
|
||||
smpDt.dy = mul(smpDt.rotMatrix, uvDDY) - uvG;
|
||||
|
||||
uvG += signLitY * 0.05; // ←鏡面すぎると不自然なのでずらす
|
||||
half3 c;
|
||||
[branch] if (smpDt.useTiling) {
|
||||
c = WCE_sampleRandomTiling(smpDt, uvG);
|
||||
} else {
|
||||
c = WCE_sampleColGrad(smpDt, uvG);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
half WCE_calcShadowIntensity(WCE_Lit lit, half dotLN, WCE_CommonData dt) {
|
||||
#if defined(_RECEIVE_SHADOWS_OFF)
|
||||
return lit.shadow;
|
||||
#else
|
||||
return 1 - (1 - lit.shadow) * lerp(dt.backShadow * (1 - step(dt.transparent, 0) * step(1, dt.normAtten)), dt.shadow, step(0, dotLN));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint WCE_getMeshRendLayer() {
|
||||
#if defined(SHADERGRAPH_PREVIEW) || !defined(_LIGHT_LAYERS)
|
||||
return 255;
|
||||
#else
|
||||
return GetMeshRenderingLightLayer();
|
||||
#endif
|
||||
}
|
||||
|
||||
half3 WCE_commonLitProcess(WCE_CommonData dt, WCE_SamplingData smpDt, half Intensity, WCE_Lit lit, float signLitY, half3 debugCol) {
|
||||
half dotLN = dot(lit.dir, dt.normWS);
|
||||
lit.shadow = WCE_calcShadowIntensity(lit, dotLN, dt);
|
||||
half3 color = half3(0, 0, 0);
|
||||
[branch] if (lit.atten * lit.shadow > 0) {
|
||||
half atten = WCE_calcAtten(dt, lit, dotLN);
|
||||
[branch] if (atten > 0) {
|
||||
#if defined(WCE_DEBUG_AREA)
|
||||
color = debugCol;
|
||||
#else
|
||||
half3 texColor = WCE_sampleCausticsTex(smpDt, lit, signLitY);
|
||||
lit.color = WCE_adjustSaturation(lit.color, dt);
|
||||
color = texColor * lit.color * atten * Intensity;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
half3 WCE_addLitProcess(uint i, WCE_CommonData dt, WCE_SamplingData smpDt, half Intensity) {
|
||||
WCE_Lit lit;
|
||||
float signLitY;
|
||||
bool checkResult;
|
||||
half3 debugCol = half3(0, 0.1, 0);
|
||||
WCE_addLitPreCheck(i, dt, /*out*/ signLitY, checkResult);
|
||||
half3 color = half3(0, 0, 0);
|
||||
[branch] if (checkResult) {
|
||||
WCE_getAddLitData(i, dt, /*out*/ lit);
|
||||
color = WCE_commonLitProcess(dt, smpDt, Intensity, lit, signLitY, debugCol);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
// Main
|
||||
half3 WCE_EffectCore(float3 WorldPos, half3 NormalWS, float2 ScreenUV, WCE_TEX_ARGS(CausticsTex), float2 TexRotSinCos, int3 TexChannels, int TilingSeed, float TilingRot, float TilingHard, float Density, float SurfY, float SurfFadeStart, float SurfFadeCoef, float DepthFadeStart, float DepthFadeCoef, half MainLitIntensity, half AddLitIntensity, half ShadowIntensity, float2 ColorShift, half LitSaturation, half NormalAtten, half NormalAttenRate, half TransparentBack, half BacksideShadow) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
SurfY = 10;
|
||||
SurfFadeStart = DepthFadeStart = DepthFadeCoef = AddLitIntensity = 0;
|
||||
SurfFadeCoef = 1;
|
||||
#endif
|
||||
|
||||
#if defined(_WCE_DISABLED)
|
||||
return half3(0, 0, 0);
|
||||
#else
|
||||
WCE_CommonData dt;
|
||||
dt.posW = WorldPos;
|
||||
dt.posWdX = WorldPos + ddx(WorldPos);
|
||||
dt.posWdY = WorldPos + ddy(WorldPos);
|
||||
dt.normWS = NormalWS;
|
||||
dt.scrnUV = ScreenUV;
|
||||
dt.shadow = ShadowIntensity;
|
||||
dt.saturation = LitSaturation;
|
||||
dt.normAtten = NormalAtten;
|
||||
dt.normRate = max(NormalAttenRate, 1);
|
||||
dt.transparent = TransparentBack;
|
||||
dt.backShadow = BacksideShadow;
|
||||
float depth = SurfY - WorldPos.y;
|
||||
float depthAbs = abs(depth);
|
||||
dt.depthSign = sign(depth);
|
||||
dt.depthFade = WCE_SurfFade(depthAbs, SurfFadeStart, SurfFadeCoef) * WCE_depthFade(depthAbs, DepthFadeStart, DepthFadeCoef);
|
||||
dt.layer = WCE_getMeshRendLayer();
|
||||
dt.posOnSurf = float3(WorldPos.x, SurfY, WorldPos.z);
|
||||
|
||||
WCE_SamplingData smpDt;
|
||||
smpDt.useTiling = (TilingSeed >= 0);
|
||||
smpDt.tilingSeed = asuint(TilingSeed);
|
||||
smpDt.tilingRot = TilingRot;
|
||||
smpDt.tilingHard = TilingHard;
|
||||
smpDt.rotMatrix = float2x2(TexRotSinCos.y, -TexRotSinCos.x, TexRotSinCos.x, TexRotSinCos.y);
|
||||
smpDt.colShift = mul(smpDt.rotMatrix, ColorShift);
|
||||
smpDt.channel = TexChannels;
|
||||
smpDt.pos = float3(dt.posW.x, depth, dt.posW.z) * Density;
|
||||
smpDt.posDDX = float3(dt.posWdX.x, depth, dt.posWdX.z) * Density;
|
||||
smpDt.posDDY = float3(dt.posWdY.x, depth, dt.posWdY.z) * Density;
|
||||
WCE_TEX_STORE(smpDt, CausticsTex);
|
||||
|
||||
half3 color = half3(0, 0, 0);
|
||||
|
||||
[branch] if (MainLitIntensity > 0) {
|
||||
float signLitY;
|
||||
bool checkResult;
|
||||
WCE_mainLitPreCheck(dt, /*out*/ signLitY, checkResult);
|
||||
[branch] if (checkResult) {
|
||||
WCE_Lit lit;
|
||||
half3 debugCol = half3(0.2, 0, 0);
|
||||
WCE_getMainLitData(dt, /*out*/ lit);
|
||||
color = WCE_commonLitProcess(dt, smpDt, MainLitIntensity, lit, signLitY, debugCol);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SHADERGRAPH_PREVIEW)
|
||||
#if defined(_ADDITIONAL_LIGHTS) || (defined(SHADERPASS) && (SHADERPASS == SHADERPASS_GBUFFER)) // Deferredは素通り
|
||||
[branch] if (AddLitIntensity > 0) {
|
||||
#if defined(_FORWARD_PLUS)
|
||||
// [Forward+]
|
||||
uint dirLitCnt = URP_FP_DIRECTIONAL_LIGHTS_COUNT;
|
||||
[loop] for (uint i = 0; i < min(dirLitCnt, MAX_VISIBLE_LIGHTS); i++) {
|
||||
color += WCE_addLitProcess(i, dt, smpDt, AddLitIntensity);
|
||||
}
|
||||
uint idx;
|
||||
ClusterIterator iterator = ClusterInit(ScreenUV, WorldPos, 0);
|
||||
[loop] while (ClusterNext(iterator, /*out*/ idx)) {
|
||||
color += WCE_addLitProcess(idx + dirLitCnt, dt, smpDt, AddLitIntensity);
|
||||
}
|
||||
#else
|
||||
// [Forward] & [Deferred]
|
||||
uint pixelLitCnt = GetAdditionalLightsCount();
|
||||
[loop] for (uint i = 0u; i < pixelLitCnt; i++) {
|
||||
color += WCE_addLitProcess(i, dt, smpDt, AddLitIntensity);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return color;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_LIGHT_COOKIES)
|
||||
#pragma warning(enable : 3595) // ループ内勾配命令warning
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3401e4fcc8ae3fa44926828d678fb61d
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Description : HexTilingFunction based on mmikk's hextile-demo
|
||||
// Original : mmikk
|
||||
// License : Copyright (c) 2022 mmikk
|
||||
// Distributed under the MIT License. See LICENSE file.
|
||||
// https://github.com/mmikk/hextile-demo/blob/main/LICENSE
|
||||
// Edited by : M.Hakozaki
|
||||
//
|
||||
|
||||
#ifndef HEX_TILING_INCLUDED
|
||||
#define HEX_TILING_INCLUDED
|
||||
|
||||
uint lowBias32(uint x) {
|
||||
// Best Integer Hash by FabriceNeyret2
|
||||
// https://www.shadertoy.com/view/WttXWX#
|
||||
x ^= x >> 16;
|
||||
x *= 0x7feb352dU;
|
||||
x ^= x >> 15;
|
||||
x *= 0x846ca68bU;
|
||||
x ^= x >> 16;
|
||||
return x;
|
||||
}
|
||||
|
||||
float2 HEX_TILING_hash3_2(int2 v, uint hashSeed) {
|
||||
uint2 u = uint2(asuint(v));
|
||||
uint x0 = u.x + (u.y << 16) + hashSeed;
|
||||
uint x1 = (u.x << 16) + u.y + (hashSeed << 16);
|
||||
return float2(lowBias32(x0), lowBias32(x1)) / float(0xffffffffU);
|
||||
}
|
||||
|
||||
float2 HEX_TILING_hash1_2(uint hashSeed) {
|
||||
return float2(hashSeed, lowBias32(hashSeed)) / float(0xffffffffU);
|
||||
}
|
||||
|
||||
float2x2 HEX_TILING_getRot(float2 hash, float rot) {
|
||||
const float M_PI = 3.14159;
|
||||
float rad = (frac((hash.x + hash.y) * 65536) - 0.5) * M_PI * rot;
|
||||
float c = cos(rad);
|
||||
float s = sin(rad);
|
||||
return float2x2(c, -s, s, c);
|
||||
}
|
||||
|
||||
void HEX_TILING_GetUV(float2 uv, float rot, uint seed, out float2 uv1, out float2 uv2, out float2 uv3, out float3 w) {
|
||||
const float TILE_SIZE = 1.3;
|
||||
const float HEX_RATE = sqrt(3) * 0.5; // 0.86602... 六角形の縦横比
|
||||
const float2x2 gridToSkewedGrid = float2x2(1 / HEX_RATE, 0, -0.5 / HEX_RATE, 1);
|
||||
uint hashSeed = lowBias32(seed);
|
||||
uv += HEX_TILING_hash1_2(hashSeed);
|
||||
float2 skewedCoord = mul(gridToSkewedGrid, uv * TILE_SIZE);
|
||||
int2 baseIdx = floor(skewedCoord);
|
||||
float3 temp = float3(frac(skewedCoord), 0);
|
||||
temp.z = 1 - temp.x - temp.y;
|
||||
float s = step(0, -temp.z);
|
||||
float s2 = 2 * s - 1;
|
||||
int2 idx1 = baseIdx + int2(s, s);
|
||||
int2 idx2 = baseIdx + int2(s, 1 - s);
|
||||
int2 idx3 = baseIdx + int2(1 - s, s);
|
||||
float2 hash1 = HEX_TILING_hash3_2(idx1, hashSeed);
|
||||
float2 hash2 = HEX_TILING_hash3_2(idx2, hashSeed);
|
||||
float2 hash3 = HEX_TILING_hash3_2(idx3, hashSeed);
|
||||
float2x2 rot1 = HEX_TILING_getRot(hash1, rot);
|
||||
float2x2 rot2 = HEX_TILING_getRot(hash2, rot);
|
||||
float2x2 rot3 = HEX_TILING_getRot(hash3, rot);
|
||||
uv1 = mul(uv, rot1) + hash1;
|
||||
uv2 = mul(uv, rot2) + hash2;
|
||||
uv3 = mul(uv, rot3) + hash3;
|
||||
w.x = -temp.z * s2;
|
||||
w.y = s - temp.y * s2;
|
||||
w.z = s - temp.x * s2;
|
||||
return;
|
||||
}
|
||||
|
||||
float3 HEX_TILING_gain3(float3 w, float hardness) {
|
||||
float k = log(1 - hardness) / log(0.5);
|
||||
float3 s = 2 * step(0.5, w);
|
||||
float3 m = 2 * (1 - s);
|
||||
w = 0.5 * s + 0.25 * m * pow(max(0.0, s + w * m), k);
|
||||
return w.xyz / (w.x + w.y + w.z);
|
||||
}
|
||||
|
||||
half3 HEX_TILING_MixColor(float hardness, half3 c1, half3 c2, half3 c3, float3 w) {
|
||||
half3 Lw = half3(0.299, 0.587, 0.114);
|
||||
half3 Dw = half3(dot(c1, Lw), dot(c2, Lw), dot(c3, Lw));
|
||||
Dw = lerp(1, Dw, 0.1);
|
||||
w = Dw * pow(w, 7); // 7
|
||||
w /= (w.x + w.y + w.z);
|
||||
w = HEX_TILING_gain3(w, hardness);
|
||||
return w.x * c1 + w.y * c2 + w.z * c3;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b3dda1ff7ed7ad49aa545454b7a9d6e
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user