Friday, August 4, 2017

unity - 2D metaball liquid effect - how to feed output of one rendering pass as input to another shader


I'm attempting to make a shader for unity3d web project. I want to implement something like in the great answer by DMGregory in this question. in order to achieve a final look something like this.. enter image description here


Its metaballs with specular and shading.
The steps to make this shader are.

1. Convert the feathered blobs into a heightmap.
2. Generate a normalmap from the heightmap
3. Feed the normal map and height map into a standard unity shader, for instance transparent parallax specular.


I pretty much have all the pieces I need assembled but I am new to shaders and need help putting them together


I can generate a heightmap from the blobs using some fragment shader code I wrote (I'm just using the red channel here cus i dont know if you can access the brightness)


    half4 frag (v2f i) : COLOR{     
half4 texcol,finalColor;
texcol = tex2D (_MainTex, i.uv);
finalColor=_MyColor;
if(texcol.r<_botmcut)

{
finalColor.r= 0;
}
else if((texcol.r>_topcut))
{
finalColor.r= 0;
}
else
{
float r = _topcut-_botmcut;

float xpos = _topcut - texcol.r;

finalColor.r= (_botmcut + sqrt((xpos*xpos)-(r*r)))/_constant;
}
return finalColor;
}

turns these blobs.. enter image description here


into this heightmap enter image description here


Also I've found some CG code that generates a normal map from a height map. The bit of code that makes the normal map from finite differences is here



    void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = fixed3(0.5);

float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));

float me = tex2D(_HeightMap,IN.uv_MainTex).x;
float n = tex2D(_HeightMap,float2(IN.uv_MainTex.x,IN.uv_MainTex.y+1.0/_HeightmapDimY)).x;
float s = tex2D(_HeightMap,float2(IN.uv_MainTex.x,IN.uv_MainTex.y-1.0/_HeightmapDimY)).x;
float e = tex2D(_HeightMap,float2(IN.uv_MainTex.x-1.0/_HeightmapDimX,IN.uv_MainTex.y)).x;

float w = tex2D(_HeightMap,float2(IN.uv_MainTex.x+1.0/_HeightmapDimX,IN.uv_MainTex.y)).x;

float3 norm = normal;
float3 temp = norm; //a temporary vector that is not parallel to norm
if(norm.x==1)
temp.y+=0.5;
else
temp.x+=0.5;

//form a basis with norm being one of the axes:

float3 perp1 = normalize(cross(norm,temp));
float3 perp2 = normalize(cross(norm,perp1));

//use the basis to move the normal in its own space by the offset
float3 normalOffset = -_HeightmapStrength * ( ( (n-me) - (s-me) ) * perp1 + ( ( e - me ) - ( w - me ) ) * perp2 );
norm += normalOffset;
norm = normalize(norm);

o.Normal = norm;
}


Also here is the built-in transparent parallax specular shader for unity.


    Shader "Transparent/Parallax Specular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 0)
_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
_Parallax ("Height", Range (0.005, 0.08)) = 0.02
_MainTex ("Base (RGB) TransGloss (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}

_ParallaxMap ("Heightmap (A)", 2D) = "black" {}
}

SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 600

CGPROGRAM
#pragma surface surf BlinnPhong alpha
#pragma exclude_renderers flash


sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _ParallaxMap;
fixed4 _Color;
half _Shininess;
float _Parallax;

struct Input {
float2 uv_MainTex;

float2 uv_BumpMap;
float3 viewDir;
};

void surf (Input IN, inout SurfaceOutput o) {
half h = tex2D (_ParallaxMap, IN.uv_BumpMap).w;
float2 offset = ParallaxOffset (h, _Parallax, IN.viewDir);
IN.uv_MainTex += offset;
IN.uv_BumpMap += offset;


fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a * _Color.a;
o.Specular = _Shininess;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}


FallBack "Transparent/Bumped Specular"
}


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...