当前位置:网站首页>Unity3d human skin real time rendering real simulated human skin real time rendering "suggestions collection"
Unity3d human skin real time rendering real simulated human skin real time rendering "suggestions collection"
2022-07-03 02:40:00 【Java architects must see】
First release the result picture ... Because the online and offline models are spelled , So eyelids , cheek , The lips look like they have cracks , The solution is to add surface subdivision and displacement mapping Make a certain uplift , But the blogger tried fragment shader Subdivision of the surface , Although the subdivision was successful, the shading effect became very strange , There is no need for surface subdivision , If you are in fragment shader A good way to use surface subdivision , Please tell me if you can
Parameter setting 1
Parameter setting 2
Fine to pore highlights
Subsurface scattering ears
Human skin rendering has been a topic for more than ten years , People try every means to make it authentic , large 3A Level era games have become more and more real recently, such as 《 The son of Rome 》, Their skin claims to have surpassed NVIDIA Example
This is 2005 year SIGGRAPH Multi layer skin rendering , Their parameters have been accurately measured in medicine , And rendering costs 5 Minutes of time ...
I found a lot of data to study this , In combination with the previous knowledge, we have made a human skin that looks quite eye-catching This example achieves the following 1. Subsurface scattering
2. Physics based rendering
Include specular and brdf wait ,brdf I used a map to adjust the curvature instead ,specular This article has explained in detail before Link here
3. Normal blur
And so on. ...
Why is skin rendering so difficult ? 1. Most diffuse light comes from subsurface scattering 2. Skin color mainly comes from the upper epidermis 3. Pink or red is mainly the blood in the dermis This picture shows the composition simulation of human skin , People have many layers of skin , This means that in the real situation, several refractions and reflections are required , This makes it more difficult to achieve reality
Refraction and reflection of light
The figure above shows the light intuitively “ What happened to me ” When light touches the skin , There are about 96% Scattered by all layers of skin , Only about 4% Reflected
Besides, specular, Human skin will be oily , So there will be reflection , But human skin cannot reflect like a mirror , Because human skin is rough , In this case, use physics based (physically based) The method is the best , Never understood. physically based You can learn about this article first It's the same as up here
The best method tried before is used , Call of duty 2 Methods used in , At the same time, I tried beckmann Methods , But the effect is not good ,phong And other methods have not been tried here , Our implementation method is like this
<span style="font-size:14px;"> /*
*this part is compute Physically-Based Rendering
*the method is in the ppt about "ops2"
*/
float _SP = pow(8192, _GL);
float d = (_SP + 2) / (8 * PIE) * pow(dot(n2, H), _SP);
float f = _SC + (1 - _SC)*pow(2, -10 * dot(H, lightDir));
float k = min(1, _GL + 0.545);
float v = 1 / (k* dot(viewDir, H)*dot(viewDir, H) + (1 - k));
float all = d*f*v;
float3 refDir = reflect(-viewDir, n2);
float3 ref = texCUBElod(_Cubemap, float4(refDir, _nMips - _GL*_nMips)).rgb;</span>And then I found that although gloss The maximum adjustment did not achieve the effect we expected , It's going on again “ Intelligent fill light ” That is, the conventional way of seeking highlights , We added a highlight map here , Don't let places that shouldn't be highlighted ( Like eyebrows ) Produce high light
float specBase = max(0, dot(n2, H)); float spec = pow(specBase, 10) *(_GL + 0.2); spec = lerp(0, 1.2, spec); float3 spec3 = spec * (tex2D(_SpecularTex, i.uv_MainTex) - 0.1); spec3 *= Luminance(diff); spec3 = saturate(spec3); spec3 *= _SpecularPower;
Where does light go , Just take some of the colors there , Light can be found from incident to exit , The position and direction have changed
The number of paths that light travels is infinite , What light reflects back is diffuse , The transparency of the oil surface is also different , This produces subsurface scattering NVIDIA stay GDC2007 In the speech in, it was mentioned that images blur Six times to achieve a soft sub surface scattering effect Every time blur They are carried out in different color channels with different ranges and degrees blur Because our mapping is like this “ With high ”
Using this example will lose a little detail on the original map , But it does have some sub surface scattering effect , You watchers choose by yourselves , And don't just do Gaussian blur , In this way, more details will be lost , And there is no sense of subsurface scattering
To save money , No ppt Medium rendering when blur, Directly in ps I did 6 A Gauss blurred map is placed material, And mixed linearly
float3 c = tex2D(_MainTex, i.uv_MainTex) * 128; c += tex2D(_BlurTex1, i.uv_MainTex) * 64; c += tex2D(_BlurTex2, i.uv_MainTex) * 32; c += tex2D(_BlurTex3, i.uv_MainTex) * 16; c += tex2D(_BlurTex4, i.uv_MainTex) * 8; c += tex2D(_BlurTex5, i.uv_MainTex) * 4; c += tex2D(_BlurTex6, i.uv_MainTex) * 2; c /= 256;
We also play an important role in edge light rim and brdf, Used BRDF The most obvious benefit is ,Brdf The map indirectly controls the color of the light and dark boundary , It can be controlled by curvature , It simulates the reflection and refraction of light on the skin at the junction of light and shadow , If it is all black, it means that light is just ordinary diffuse reflection .
And make human skin have the texture of sub surface scattering
/* *this part is to add the sss *used front rim,back rim and BRDF */ float3 rim = (1 - dot(viewDir, n2))*_RimPower * _RimColor *tex2D(_RimTex, i.uv_MainTex); float3 frontrim = (dot(viewDir, n2))*_FrontRimPower * _FrontRimColor *tex2D(_FrontRimTex, i.uv_MainTex); float3 sss = (1 - dot(viewDir, n2)) / 50 * _SSSPower; sss = lerp(tex2D(_SSSFrontTex, i.uv_MainTex), tex2D(_SSSBackTex, i.uv_MainTex), sss * 20)*sss; fixed atten = LIGHT_ATTENUATION(i); float curvature = length(fwidth(mul(_Object2World, float4(normalize(i.normal), 0)))) / length(fwidth(i.worldpos)) * _CurveScale; float3 brdf = tex2D(_BRDFTex, float2((dot(normalize(i.normal), lightDir) * 0.5 + 0.5)* atten, curvature)).rgb;
about rim Add forward rim And back rim In fact, it is still rim, Back rim White pictures are used to produce a feeling of jade ( Well, it's actually more like sheep soup ), Forward direction rim Red pictures are used , It is equivalent to adding the scattering of light in the blood layer , Let people's faces have real blood
This is the result of subsurface scattering :
The light source is in your mouth
Like the effect of putting your fingers or ears in front of a flashlight ? That is subsurface scattering Need one Intense strips Map to mix the original colors , The method is in the case of point light , Find the distance between the current point and the point light , The closer the distance, the brighter
About normals , A new mixing method is used , This will preserve more normal details , Here is a brief introduction to normal blending ,
float3 n1 = tex2D(texBase, uv).xyz*2 - 1; float3 n2 = tex2D(texDetail, uv).xyz*2 - 1; float3 r = normalize(n1 + n2); return r*0.5 + 0.5;
You may have used this method to mix two normal maps , This linear approach compromises the two maps , The detail weight obtained is average , The effect is not good , This is the result
Improved a little bit , It becomes a covering mix
float3 n1 = tex2D(texBase, uv).xyz; float3 n2 = tex2D(texDetail, uv).xyz; float3 r = n1 < 0.5 ? 2*n1*n2 : 1 - 2*(1 - n1)*(1 - n2); r = normalize(r*2 - 1); return r*0.5 + 0.5;
It's the normal 1 Where the normal of is deeper , Just a little more weight , The shallower part is called normal 2 Cover properly , But this effect is not real enough
stay GDC2012 Of Mastering DX11 with unity An official method mentioned in is as follows :
float3x3 nBasis = float3x3(
float3(n1.z, n1.y, -n1.x), // Around y Axis +90 Degree of rotation
float3(n1.x, n1.z, -n1.y),// Around x Axis -90 Degree of rotation
float3 (n1.x, n1.y, n1.z ));
n = normalize (n2.x*nBasis[0] + n2.y*nBasis[1] + n2.z*nBasis[2]);The result is like this , Is it much better ?
The level of detail of both sides has been greatly improved ,
They used a basis To transform the second normal . For details, see This article — link
use AutoLight.cginc A function defined in LIGHT_ATTENUATION Find the attenuation of light atten,atten stay directional light The middle fixing is 1, Only in the point light source can there be attenuation effect , because directional light stay unity There is no position difference in , It's the same everywhere .
fixed atten = LIGHT_ATTENUATION(i);
For details , Such as pores , In this example, the map and normal map are very detailed , Already includes pores and skin lines , If you want high detail with low mapping accuracy , You can post details
All settable variables :
All codes have been shared to GitHub link ---- by wolf96
边栏推荐
- 简单理解svg
- [flutter] example of asynchronous programming code between future and futurebuilder (futurebuilder constructor setting | handling flutter Chinese garbled | complete code example)
- 4. Classes and objects
- GBase 8c 函数/存储过程参数(一)
- 为什么会选择框架?选择什么样的框架
- GBase 8c系统表-pg_aggregate
- 左值右指解释的比较好的
- Awk from getting started to getting into the ground (3) the built-in functions printf and print of awk realize formatted printing
- 基于can总线的A2L文件解析(2)
- Oauth2.0 authentication, login and access "/oauth/token", how to get the value of request header authorization (basictoken)???
猜你喜欢

A2L file parsing based on CAN bus (2)

基于can总线的A2L文件解析(2)

Random Shuffle attention

Choose it when you decide
![[principles of multithreading and high concurrency: 1_cpu multi-level cache model]](/img/7e/ad9ea78868126b149bd9f15f587e6c.jpg)
[principles of multithreading and high concurrency: 1_cpu multi-level cache model]
![[fluent] JSON model conversion (JSON serialization tool | JSON manual serialization | writing dart model classes according to JSON | online automatic conversion of dart classes according to JSON)](/img/6a/ae44ddb090ce6373f04a550a15f973.jpg)
[fluent] JSON model conversion (JSON serialization tool | JSON manual serialization | writing dart model classes according to JSON | online automatic conversion of dart classes according to JSON)

搭建私有云盘 cloudreve

"Analysis of 43 cases of MATLAB neural network": Chapter 43 efficient programming skills of neural network -- Discussion Based on the characteristics of the new version of MATLAB r2012b

Today, it's time to copy the bottom!

Oauth2.0 authentication, login and access "/oauth/token", how to get the value of request header authorization (basictoken)???
随机推荐
sql server 查詢指定錶的錶結構
Gbase 8C trigger (III)
Add MDF database file to SQL Server database, and the error is reported
Gbase 8C function / stored procedure parameters (I)
【教程】chrome關閉跨域策略cors、samesite,跨域帶上cookie
Pytest (6) -fixture (Firmware)
GBase 8c系统表-pg_collation
Gbase 8C system table PG_ amop
[tutorial] chrome turns off cross domain policies CORS and samesite, and brings cookies across domains
random shuffle注意
[fluent] futurebuilder asynchronous programming (futurebuilder construction method | asyncsnapshot asynchronous calculation)
二维格式数组格式索引下标连续问题导致 返回json 格式问题
Javescript 0.1 + 0.2 = = 0.3 problem
Add automatic model generation function to hade
Tongda OA V12 process center
Awk from introduction to earth (0) overview of awk
GBase 8c 函数/存储过程定义
"Analysis of 43 cases of MATLAB neural network": Chapter 43 efficient programming skills of neural network -- Discussion Based on the characteristics of the new version of MATLAB r2012b
Gbase 8C system table PG_ conversion
Oauth2.0 authentication, login and access "/oauth/token", how to get the value of request header authorization (basictoken)???