How to use the Custom Material node and create Metaballs 官方视频学习笔记

Posted 湛蓝玫瑰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了How to use the Custom Material node and create Metaballs 官方视频学习笔记相关的知识,希望对你有一定的参考价值。

这个视频Youtube没有字幕着实蛋疼,本人英语很渣,几乎听不懂,里面有很多文档没讲的重要信息(文档讲的东西太少了)。

不过学习过后你可以解锁好几个姿势。这个视频主要是教你做DistanceField来写Shader,以下是最终效果:

一开始需要通过 r.ShaderDevelopmentMode 1,r.DumpShaderDebugInfo 1开启着色器开发模式(不过本人没感觉有什么用,可能到了用RHI写HLSL会比较有用)

为了方便之后的各位,本人在此贴上视频以及材质节点:

第一段代码:

float3 CamVec=normalize(WorldPos-View.ViewOrigin);
float3 curpos=WorldPos;
float3 normal=0;

int maxsteps=16;
float curdist,accum=0;
float minstepsize=0.01;
int i=0;
while(i<maxsteps)
{
	curdist=CustomExpression0(Parameters,curpos,k,Spere1,Spere2,Spere3,t);
	if(curdist<thresh)
	{
		return float4(1.0,1.0,1.0,1.0);
	}
	curpos+=CamVec*max(minstepsize,curdist);
	minstepsize+=0.02;
	i++;
}
return 0;

  第二个CustomNode,于37:08贴出代码

//evaluate the distance
float s1=distance(Sphere1.xyz,curpos)-Sphere1.w;
float s2=distance(Sphere2.xyz,curpos)-Sphere2.w;
float s3=distance(Sphere3.xyz,curpos)-Sphere3.w;

float dot1=dot(normalize(curpos-Sphere1.xyz),float3(0.707,0.707,0))-1;
float dot2=sin(dot1*2+(t*2))*1.5;
dot2+=sin(dot1*24+(t*8))*0.07;
s1-=dot2;

float h=saturate(0.5+0.5*(s2-s1)/k);
s2=lerp(s2,s1,h)-k*h*(1.0-h);

h=saturate(0.5+0.5(s3-s2)/k);
float curdf=lerp(s3,s2,h)-k*h(1.0-h);

return curdf;

  33:20 查看HLSL代码中的 GetMaterialEmissiveRaw,发现这个函数写了连接到自发光上的所有节点信息,也就说把之前的节点都转化为代码了。

50:00为止的完整代码(之前的代码为了方便演示,把法线以为密度部分分离,以下是最后以后的代码):

//metaballs simple
float3 CamVec=normalize(WorldPos-ViewOrigin);
float3 curpos=WorldPos;
float3 normal=0;

int maxsteps=64;
float curdist,accum=0;
float minstepsize=0.01;
int i=0;
while(i<maxsteps)
{
	curdist=CustomExpression0(Parameters,curpos,k,Sphere1,Sphere2,Sphere3,t);
	if(curdist<thresh)
	{
		
		curpos+=CamVec*curdist;
		normal.x=CustomExpression0(Parameters,curpos+float3(1,0,0)*o,k,Sphere1,Sphere2,Sphere3,t);
		normal.y=CustomExpression0(Parameters,curpos+float3(0,1,0)*o,k,Sphere1,Sphere2,Sphere3,t);
		normal.z=CustomExpression0(Parameters,curpos+float3(0,0,1)*o,k,Sphere1,Sphere2,Sphere3,t);
		normal=normalize(normal);
		CamVec=lerp(CamVec,-normal,Refraction);
		
		int j=0;
		while(j<16)
		{
			curdist=CustomExpression0(Parameters,curpos,k,Sphere1,Sphere2,Sphere3,t);
			if(curdist<ShadowMult)
			{
				curdist=max(0,curdist);
				accum+=ShadowMult-curdist;
			}
			curpos+=CamVec*10;
			j++;
		}
		return float4(normal,accum);
	}
	curpos+=CamVec*max(minstepsize,curdist);
	minstepsize+=0.02;
	i++;
}
return 0;

以下是最终的材质节点连线: 

 

 

 50:00之后演示了最终在Demo中用的部分代码(这个我没测试过):

float3 startpos=curpos
float3 accum=0;
float3 normal=0;

int i=0;
	float curdist =CustomExpression2(Parameters,curpos,k,sphere1,sphere2,sphere3,sphere4.t);
	accum-=curdist*TraceVec;
	curpos-=TraceVec*curdist;
	
	curdist=CustomExpression2(Parameters,curpos,k,sphere1,sphere2,sphere3,sphere4.t);
	accum-=curdist*TraceVec;
	curpos-=TraceVec*curdist;
	
	curdist=CustomExpression2(Parameters,curpos,k,sphere1,sphere2,sphere3,sphere4.t);
	accum-=curdist*TraceVec;
	curpos-=TraceVec*curdist;
	
return startpos+accum;

  最后传入WorldPositionOffset,可以做出一个球体融合效果。

1:00:00 演示了获取各种屏幕属性
https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/FViewUniformShaderParameters/index.html

在CustomNode中输入View.ExposureScale;当然还有别的几个UniformShader条目,可以得到的属性还挺多。

1:08:50 Height to DF,一个高度图转Distance Field代码(也没测试过,图片用的是引擎里的,可以通过展开EngineContent搜索Texture找到):

heightratio=min(0.2,heightratio);
float 2 texsize=0;
float levels=0;
Tex.GetDimensions(0,texsize.x,texsize.y,levels);
texsize.x=min(texsize.x,256*s);
texsize.y=min(texsize.y,256*s);

float searchlength=max(texsize.x,texsize.y)*heightratio;
float mindist=1;

float3 startpos=float3(UV.x,UV.y,1);
float3 sampledpos=0;
for(int i=-searchlength;i<=searchlength;i++)
{
	for(int j=-searchlength;j<=searchlength;j++)
	{
		sampledpos.xy=UV+float2(i,j)/texsize;
		float texatray=Tex.SampleLevel(TexSampler,sampledpos.xy,0);
		sampledpos.z=lerp(1,1-texatray,heightratio);
		mindist=min(mindist,length(startpos-sampledpos));
	}
}
return mindist/heightratio;

  

最后推荐了这个网站
http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
里面介绍了几个基本形状的距离计算公式

 

最终输出法线与ALPHA,存在XYZ与w通道中。法线用于从环境贴图中获得颜色信息,做出物体反射效果。

可惜英语不好,不然学起来会更快,所以我只能直接啃代码(第一段的抖动代码让我懵逼了很久),本人自己做了笔记,但是鉴于能力不足就不贴出来,怕误导大家,不过如果有不懂可以在此提问,我可以说一下我一些想法。

看完可以学会四个姿势:
1、距离场的简单计算(没看过距离场算法不好确认)
2、法线计算
3、距离融合算法
4、RayMarching

以上是关于How to use the Custom Material node and create Metaballs 官方视频学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

How To Use the AWK language to Manipulate Text in Linux

How to use the audio gadget driver

How to use the attributes :layout_weight

How to use the function of assembly.

The Beginner’s Guide on How to Use TaoBao

How to Stop Procrastinating by Using the “2-Minute Rule”