Hello everyone, I've been trying to use Sebastian Lague's procedural planet generation and his ocean shader to make a game. Here's the video for reference: https://www.youtube.com/watch?v=lctXaT9pxA0
(The link to the procedural planet generation code: https://github.com/SebLague/Solar-System/tree/Episode-03)
Now I've tried updating this shader to add foam to the shorelines in a pattern that surrounds the shores and animates towards the inner part of the ocean, such as in his latest video (https://www.youtube.com/watch?v=sLqXFF8mlEU&t=1044s):
![islands with foam on the shore][1]
[1]: /storage/temp/190052-shorelinefoamexample.png
The code I'm trying to update to do so is the following:
Shader "Hidden/Ocean"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "../Includes/Math.cginc"
#include "../Includes/Triplanar.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewVector : TEXCOORD1;
};
v2f vert (appdata v) {
v2f output;
output.pos = UnityObjectToClipPos(v.vertex);
output.uv = v.uv;
// Camera space matches OpenGL convention where cam forward is -z. In unity forward is positive z.
// (https://docs.unity3d.com/ScriptReference/Camera-cameraToWorldMatrix.html)
float3 viewVector = mul(unity_CameraInvProjection, float4(v.uv * 2 - 1, 0, -1));
output.viewVector = mul(unity_CameraToWorld, float4(viewVector,0));
return output;
}
float4 colA;
float4 colB;
float4 specularCol;
float depthMultiplier;
float alphaMultiplier;
float smoothness;
sampler2D waveNormalA;
sampler2D waveNormalB;
float waveStrength;
float waveNormalScale;
float waveSpeed;
sampler2D _MainTex;
sampler2D _CameraDepthTexture;
float4 params;
float planetScale;
float3 oceanCentre;
float oceanRadius;
float3 dirToSun;
fixed4 frag (v2f i) : SV_Target
{
fixed4 originalCol = tex2D(_MainTex, i.uv);
float3 rayPos = _WorldSpaceCameraPos;
float viewLength = length(i.viewVector);
float3 rayDir = i.viewVector / viewLength;
float nonlin_depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
float sceneDepth = LinearEyeDepth(nonlin_depth) * viewLength;
float2 hitInfo = raySphere(oceanCentre, oceanRadius, rayPos, rayDir);
float dstToOcean = hitInfo.x;
float dstThroughOcean = hitInfo.y;
float3 rayOceanIntersectPos = rayPos + rayDir * dstToOcean - oceanCentre;
// dst that view ray travels through ocean (before hitting terrain / exiting ocean)
float oceanViewDepth = min(dstThroughOcean, sceneDepth - dstToOcean);
if (oceanViewDepth > 0) {
float3 clipPlanePos = rayPos + i.viewVector * _ProjectionParams.y;
float dstAboveWater = length(clipPlanePos - oceanCentre) - oceanRadius;
float t = 1 - exp(-oceanViewDepth / planetScale * depthMultiplier);
float alpha = 1-exp(-oceanViewDepth / planetScale * alphaMultiplier);
float4 oceanCol = lerp(colA, colB, t);
float3 oceanSphereNormal = normalize(rayOceanIntersectPos);
float2 waveOffsetA = float2(_Time.x * waveSpeed, _Time.x * waveSpeed * 0.8);
float2 waveOffsetB = float2(_Time.x * waveSpeed * - 0.8, _Time.x * waveSpeed * -0.3);
float3 waveNormal = triplanarNormal(rayOceanIntersectPos, oceanSphereNormal, waveNormalScale / planetScale, waveOffsetA, waveNormalA);
waveNormal = triplanarNormal(rayOceanIntersectPos, waveNormal, waveNormalScale / planetScale, waveOffsetB, waveNormalB);
waveNormal = normalize(lerp(oceanSphereNormal, waveNormal, waveStrength));
//return float4(oceanNormal * .5 + .5,1);
float diffuseLighting = saturate(dot(oceanSphereNormal, dirToSun));
float specularAngle = acos(dot(normalize(dirToSun - rayDir), waveNormal));
float specularExponent = specularAngle / (1 - smoothness);
float specularHighlight = exp(-specularExponent * specularExponent);
oceanCol *= diffuseLighting;
oceanCol += specularHighlight * (dstAboveWater > 0) * specularCol;
//return float4(oceanSphereNormal,1);
float4 finalCol = originalCol * (1-alpha) + oceanCol * alpha;
return float4(finalCol.xyz, params.x);
}
return originalCol;
}
ENDCG
}
}
}
I know that in his latest video he calculates this with a distance to shoreline map. However, I know this can be done with the depth of the water at any given point, but I do not know how to use this information to create the foam. If this is not possible, I would be fine with just creating foam at the shores when the depth of the water is under a maximum depth and then animating it with noise, as what this shader does: https://github.com/IronWarrior/ToonWaterShader/blob/master/Assets/Shaders/ToonWater.shader (how the shader looks is on the main GitHub page).
I have also tried integrating that shader's code into the shader that I have, but the furthest I've gotten is converting all water into white.
Any help, even just pointing me into the correct direction would be much appreciated.
Thank you in advance.
↧