Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize the Stroke and projection of translucent objects by unity

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces unity how to achieve translucent objects stroke and projection related knowledge, content detailed and easy to understand, simple and fast operation, has a certain reference value, I believe everyone read this unity how to achieve translucent objects stroke and projection article will have some harvest, let's take a look at it.

Translucent strokes are roughly three options, 1. Draw as transparent but write depth, 2. Use template cache instead of depth, 3. Use GrabPass to simulate transparency when rendering opaque objects. I'm using the simplest one here.

Similar to hair, draw the back first, then draw the front, then expand the edge to draw the stroke of the back, 3 PASS, need to ensure that the depth of the inner surface of the model is higher. All closed objects have this property.

Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }

Pass

{

Blend SrcAlpha OneMinusSrcAlpha

ColorMask RGB

Cull Front

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

ENDCG

}

Pass

{

Blend SrcAlpha OneMinusSrcAlpha

ColorMask RGB

Cull Back

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

ENDCG

}

Pass

{

Blend SrcAlpha OneMinusSrcAlpha

ColorMask RGB

Cull Front

CGPROGRAM

#pragma vertex vert_line

#pragma fragment frag_line

ENDCG

}

This effect can be obtained by replacing vert,frag,vert_line,frag_line with ordinary transparent shader and backface extensions, because the specific implementation is different for each person, so it is not written.

The flaws that can occur are:

1. When two transparent objects cross each other, they will block each other, and when the transparency order changes, it will jump.

There is no good way to solve the inherent problem of transparent objects. Just don't let this happen.

2. The particles are in front of the model, and the emitted particles are blocked when they enter the sphere. If the particles are behind the model, they are not occluded anyway.

这其实也是半透明自己的问题。如果在意半透和非半透交叉产生的交线,可以开启软粒子回避(其实球和Cude的交线瑕疵也能这样回避)

半透阴影其实可行的就网点这种,其他的诸如给shadowmap加透明通道,都需要额外增加成本,而且难以处理多层叠加的问题(两层半透之间的物体的阴影接收也是需要处理的),真正完美的方案需要把shadowmap存UAV里实现多层shadowmap(还要带透明度),这可算了吧。

网点半透需要修改ShadowCast,做法是给原Shader增加一个LightMode标记为ShadowCaster的Pass,并重新定义绘制逻辑。

Pass{

Tags {"LightMode" = "ShadowCaster"}

Cull Off

CGPROGRAM

#pragma vertex vert_shadow

#pragma fragment frag_shadow

#pragma multi_compile_shadowcaster

ENDCG

}

绘制阴影的时候需要根据原图的透明度,输出下图这样的网点图案来模拟透明效果(为了方便观察故意把网点放大了)

网点的生成没有使用网点纹理,而使用了一个数值计算的结果:

void transparencyClip(float alpha, float2 screenPos)

{

// Screen-door transparency: Discard pixel if below threshold.

float4x4 thresholdMatrix =

{ 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,

13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,

4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,

16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0

};

float4x4 _RowAccess = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };

clip(alpha - thresholdMatrix[fmod(screenPos.x, 4)] * _RowAccess[fmod(screenPos.y, 4)]);

}

数值计算一般比用纹理采样要快。

原模型加入纹理后如下图

采样的瑕疵很难避免,所以需要开启软阴影。

使用较低的阴影质量时的情况:

瑕疵基本可以接受,但在镜头移动的时候会产生一定的抖动现象,因此最好还是保持较高的精度。

而描边本身的阴影……因为ShadowCast只能存在一个。如果想生成这个可能只能复制一个单独的描边材质了,这个就算了吧。

需要注意的是,绘制阴影的时候需要严格对齐像素,所以需要获得shadowmap纹理的具体大小,而_ScreenParams那一系列函数是无效的。即使定下某个固定缩放数值,如果使用了层级阴影,切换到不同级别的时候也无法统一。

这里获取具体的屏幕坐标用了VPOS,具体写法可查看代码:

//shadowCast

struct v2f_shadow

{

float2 uv : TEXCOORD2;

};

void transparencyClip(float alpha, float2 screenPos)

{

// Screen-door transparency: Discard pixel if below threshold.

float4x4 thresholdMatrix =

{ 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,

13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,

4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,

16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0

};

float4x4 _RowAccess = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };

clip(alpha - thresholdMatrix[fmod(screenPos.x, 4)] * _RowAccess[fmod(screenPos.y, 4)]);

}

v2f_shadow vert_shadow(appdata_base v,out float4 outpos : SV_POSITION)

{

v2f_shadow o;

TRANSFER_SHADOW_CASTER_NOPOS(o, outpos)

o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

return o;

}

float4 frag_shadow(v2f_shadow i, UNITY_VPOS_TYPE screenPos : VPOS) :SV_Target

{

fixed4 col = tex2D(_MainTex, i.uv) * _Color;

transparencyClip(col.a,screenPos.xy);

SHADOW_CASTER_FRAGMENT(i)

}关于"unity怎么实现半透明物体的描边和投影"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"unity怎么实现半透明物体的描边和投影"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report