diff options
| author | yum <yum.food.vr@gmail.com> | 2025-08-01 13:37:40 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-08-01 13:37:40 -0700 |
| commit | 512357cd6ffe15c4e4fb40ee09d4f04c51df95a3 (patch) | |
| tree | 6d77e0bc7be53063fc95a1255d24fc59860afdc8 /tessellation.cginc | |
| parent | 4186d84cccf1d0db4ba413dba63baf87c87b79bb (diff) | |
ocean wave work
- add sea foam feature, which takes horizontal displacement derivatives
and calculates folding areas (with a bias) using the Tessendorf
Jacobian method.
- add "isInViewFrustum" method to tessellation
Diffstat (limited to 'tessellation.cginc')
| -rw-r--r-- | tessellation.cginc | 158 |
1 files changed, 99 insertions, 59 deletions
diff --git a/tessellation.cginc b/tessellation.cginc index fce9979..24d53ab 100644 --- a/tessellation.cginc +++ b/tessellation.cginc @@ -13,6 +13,79 @@ struct tess_factors { float inside : SV_InsideTessFactor; }; +bool isInViewFrustum(float4 clipPos, float radius) { + return -clipPos.w - radius < clipPos.x && clipPos.x < clipPos.w + radius && + -clipPos.w - radius < clipPos.y && clipPos.y < clipPos.w + radius && + -clipPos.w - radius < clipPos.z && clipPos.z < clipPos.w + radius; +} + +#if defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3) || defined(_TESSELLATION_HEIGHTMAP_4) || defined(_TESSELLATION_HEIGHTMAP_5) || defined(_TESSELLATION_HEIGHTMAP_6) || defined(_TESSELLATION_HEIGHTMAP_7) +#define _TESSELLATION_HEIGHTMAP +#endif + +float4 applyHeightmap(float4 objPos, float2 uv, float3 normal, float3 tangent, float3 binormal) { +#if defined(_TESSELLATION) && defined(_TESSELLATION_HEIGHTMAP) + float3 height = 0; +#if defined(_TESSELLATION_HEIGHTMAP_0) + float3 heightmap_0_sample = _Tessellation_Heightmap_0.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_0_ST.xy, 0); + height += heightmap_0_sample * _Tessellation_Heightmap_0_Scale + _Tessellation_Heightmap_0_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_1) + float3 heightmap_1_sample = _Tessellation_Heightmap_1.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_1_ST.xy, 0); + height += heightmap_1_sample * _Tessellation_Heightmap_1_Scale + _Tessellation_Heightmap_1_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_2) + float3 heightmap_2_sample = _Tessellation_Heightmap_2.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_2_ST.xy, 0); + height += heightmap_2_sample * _Tessellation_Heightmap_2_Scale + _Tessellation_Heightmap_2_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_3) + float3 heightmap_3_sample = _Tessellation_Heightmap_3.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_3_ST.xy, 0); + height += heightmap_3_sample * _Tessellation_Heightmap_3_Scale + _Tessellation_Heightmap_3_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_4) + float3 heightmap_4_sample = _Tessellation_Heightmap_4.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_4_ST.xy, 0); + height += heightmap_4_sample * _Tessellation_Heightmap_4_Scale + _Tessellation_Heightmap_4_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_5) + float3 heightmap_5_sample = _Tessellation_Heightmap_5.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_5_ST.xy, 0); + height += heightmap_5_sample * _Tessellation_Heightmap_5_Scale + _Tessellation_Heightmap_5_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_6) + float3 heightmap_6_sample = _Tessellation_Heightmap_6.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_6_ST.xy, 0); + height += heightmap_6_sample * _Tessellation_Heightmap_6_Scale + _Tessellation_Heightmap_6_Offset; +#endif +#if defined(_TESSELLATION_HEIGHTMAP_7) + float3 heightmap_7_sample = _Tessellation_Heightmap_7.SampleLevel(bilinear_repeat_s, + uv * _Tessellation_Heightmap_7_ST.xy, 0); + height += heightmap_7_sample * _Tessellation_Heightmap_7_Scale + _Tessellation_Heightmap_7_Offset; +#endif + +#if defined(_TESSELLATION_HEIGHTMAP_WORLD_SPACE) + objPos.xyz += mul(unity_WorldToObject, height).xyz; +#else +#if defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) + float3 heightmap_direction = mul(transpose(-float3x3(normal, tangent, binormal)), _Tessellation_Heightmap_Direction_Control_Vector); +#elif defined(OUTLINE_PASS) && !defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) + float3 heightmap_direction = -normal; +#elif !defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) + float3 heightmap_direction = mul(transpose(float3x3(normal, tangent, binormal)), _Tessellation_Heightmap_Direction_Control_Vector); +#else + float3 heightmap_direction = normal; +#endif + objPos.xyz += heightmap_direction * height; +#endif + +#endif // _TESSELLATION_HEIGHTMAP + return objPos; +} + tess_factors patch_constant(InputPatch<v2f, 3> patch) { tess_factors f; #if defined(_TESSELLATION) @@ -32,6 +105,31 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) { #else float factor = 1; #endif + +#if defined(_TESSELLATION_HEIGHTMAP) + [branch] + if (factor > 3) { + // Scuffed occlusion culling. Need to know what the position will be after displacement + // in order to do it right. "Scuffed" because we repeat work :/ this same transform gets + // applied in the domain shader. This isn't so bad if we assume that we're tessellating + // at a relatively high factor. + float3 p0newObjPos = applyHeightmap(patch[0].objPos, patch[0].uv01.xy, patch[0].normal, patch[0].tangent, patch[0].binormal); + float3 p1newObjPos = applyHeightmap(patch[1].objPos, patch[1].uv01.xy, patch[1].normal, patch[1].tangent, patch[1].binormal); + float3 p2newObjPos = applyHeightmap(patch[2].objPos, patch[2].uv01.xy, patch[2].normal, patch[2].tangent, patch[2].binormal); + float4 p0newClipPos = UnityObjectToClipPos(p0newObjPos); + float4 p1newClipPos = UnityObjectToClipPos(p1newObjPos); + float4 p2newClipPos = UnityObjectToClipPos(p2newObjPos); + // Dirty hack to prevent objects that are currently outside the view frustum, + // but which are after displacement, from being culled. + float radius = 0.3; + bool inViewFrustum0 = isInViewFrustum(p0newClipPos, radius); + bool inViewFrustum1 = isInViewFrustum(p1newClipPos, radius); + bool inViewFrustum2 = isInViewFrustum(p2newClipPos, radius); + bool inViewFrustum = inViewFrustum0 || inViewFrustum1 || inViewFrustum2; + factor = inViewFrustum ? factor : 1; + } +#endif + f.edge[0] = factor; f.edge[1] = factor; f.edge[2] = factor; @@ -82,65 +180,7 @@ v2f domain( #endif #endif -#if defined(_TESSELLATION) && (defined(_TESSELLATION_HEIGHTMAP_0) || defined(_TESSELLATION_HEIGHTMAP_1) || defined(_TESSELLATION_HEIGHTMAP_2) || defined(_TESSELLATION_HEIGHTMAP_3) || defined(_TESSELLATION_HEIGHTMAP_4) || defined(_TESSELLATION_HEIGHTMAP_5) || defined(_TESSELLATION_HEIGHTMAP_6) || defined(_TESSELLATION_HEIGHTMAP_7)) - float3 height = 0; -#if defined(_TESSELLATION_HEIGHTMAP_0) - float3 heightmap_0_sample = _Tessellation_Heightmap_0.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_0_ST.xy, 0); - height += heightmap_0_sample * _Tessellation_Heightmap_0_Scale + _Tessellation_Heightmap_0_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_1) - float3 heightmap_1_sample = _Tessellation_Heightmap_1.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_1_ST.xy, 0); - height += heightmap_1_sample * _Tessellation_Heightmap_1_Scale + _Tessellation_Heightmap_1_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_2) - float3 heightmap_2_sample = _Tessellation_Heightmap_2.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_2_ST.xy, 0); - height += heightmap_2_sample * _Tessellation_Heightmap_2_Scale + _Tessellation_Heightmap_2_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_3) - float3 heightmap_3_sample = _Tessellation_Heightmap_3.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_3_ST.xy, 0); - height += heightmap_3_sample * _Tessellation_Heightmap_3_Scale + _Tessellation_Heightmap_3_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_4) - float3 heightmap_4_sample = _Tessellation_Heightmap_4.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_4_ST.xy, 0); - height += heightmap_4_sample * _Tessellation_Heightmap_4_Scale + _Tessellation_Heightmap_4_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_5) - float3 heightmap_5_sample = _Tessellation_Heightmap_5.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_5_ST.xy, 0); - height += heightmap_5_sample * _Tessellation_Heightmap_5_Scale + _Tessellation_Heightmap_5_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_6) - float3 heightmap_6_sample = _Tessellation_Heightmap_6.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_6_ST.xy, 0); - height += heightmap_6_sample * _Tessellation_Heightmap_6_Scale + _Tessellation_Heightmap_6_Offset; -#endif -#if defined(_TESSELLATION_HEIGHTMAP_7) - float3 heightmap_7_sample = _Tessellation_Heightmap_7.SampleLevel(bilinear_repeat_s, - o.uv01.xy * _Tessellation_Heightmap_7_ST.xy, 0); - height += heightmap_7_sample * _Tessellation_Heightmap_7_Scale + _Tessellation_Heightmap_7_Offset; -#endif - -#if defined(_TESSELLATION_HEIGHTMAP_WORLD_SPACE) - o.objPos.xyz += mul(unity_WorldToObject, height).xyz; -#else -#if defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) - float3 heightmap_direction = mul(transpose(-float3x3(o.normal, o.tangent, o.binormal)), _Tessellation_Heightmap_Direction_Control_Vector); -#elif defined(OUTLINE_PASS) && !defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) - float3 heightmap_direction = -o.normal; -#elif !defined(OUTLINE_PASS) && defined(_TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL) - float3 heightmap_direction = mul(transpose(float3x3(o.normal, o.tangent, o.binormal)), _Tessellation_Heightmap_Direction_Control_Vector); -#else - float3 heightmap_direction = o.normal; -#endif - o.objPos.xyz += heightmap_direction * height; -#endif - -#endif // _TESSELLATION_HEIGHTMAP + o.objPos = applyHeightmap(o.objPos, o.uv01.xy, o.normal, o.tangent, o.binormal); o.pos = UnityObjectToClipPos(o.objPos); o.worldPos = mul(unity_ObjectToWorld, o.objPos).xyz; |
