游戏中各向异性头发的渲染
2017-11-03 16:29
561 查看
趁有时间写一篇关于各向异性头发的渲染。
先上效果图(不含Ao)。
这个是04年的一个ppt,主要介绍了头发的渲染,其追到源头还是要看这个原理。
各向异性的主要计算公式:
主要代码如下:
切线混合扰动部分(这部分也可以用T+k*N,来对切线进行扰动):
主要是通过改变切线的xy值来造成头发高光部分的多样性。
高光部分,按公式计算即可:
注意,为了模拟的更贴近真实性,应用两层高光,第一层高光代表直射光直接反射出去,第二层代表次表面散射现象具体看代码。
最终渲染部分:
这里我注释掉了AO和高光遮罩,需要的同学可以加上。
最后一点为了不让头发的边经过clip之后太硬,需要进行两个通道的belnd。
第二个pass使用以下指令:
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
注意第二个通道无需再进行clip操作。
至此,头发渲染完毕。
先上效果图(不含Ao)。
这个是04年的一个ppt,主要介绍了头发的渲染,其追到源头还是要看这个原理。
各向异性的主要计算公式:
主要代码如下:
切线混合扰动部分(这部分也可以用T+k*N,来对切线进行扰动):
float3x3 tangentTransform = float3x3(i.tangentDir, i.bitangentDir, i.normalDir); float3 _T_var = UnpackNormal(tex2D(_Tangent, TRANSFORM_TEX(i.uv0, _Tangent))); float3 temp = lerp(_TangentParam.xyz, _T_var, _BlenfTangent); float3 T = normalize(mul(float3(temp.xy,0), tangentTransform));
主要是通过改变切线的xy值来造成头发高光部分的多样性。
高光部分,按公式计算即可:
float StrandSpecular(float3 T, float3 V, float3 L, float exponent) { float3 H = normalize(L + V); float dotTH = dot(T, H); float sinTH = sqrt(1 - dotTH*dotTH); float dirAtten = smoothstep(-1, 0, dotTH); return dirAtten*pow(sinTH, exponent); }
注意,为了模拟的更贴近真实性,应用两层高光,第一层高光代表直射光直接反射出去,第二层代表次表面散射现象具体看代码。
最终渲染部分:
float4 HairLighting(float3 T, float3 N, float3 L, float3 V, float2 uv, float3 lightColor) { float diffuse = saturate(lerp(0.25, 1.0, dot(N, L)))*lightColor; float3 indirectDiffuse = float3(0, 0, 0); indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb; // Ambient Light float3 H = normalize(L + V); float LdotH = saturate(dot(L, H)); float3 specular = _Specular*StrandSpecular(T, V, L, exp2(lerp(1, 11, _Gloss))); //float specMask = tex2D(_SpecMask, TRANSFORM_TEX(uv, _SpecMask)); specular += /*specMask*/_SubColor*StrandSpecular(T, V, L, exp2(lerp(1, 11, _ScatterFactor))); float4 final; float4 base = tex2D(_MainTex, TRANSFORM_TEX(uv, _MainTex)); float3 diffuseColor = (_Color.rgb*base.rgb); //float ao = tex2D(_AO, TRANSFORM_TEX(uv, _AO)).g; final.rgb = (diffuse + indirectDiffuse)*diffuseColor + specular*lightColor* FresnelTerm(_Specular, LdotH); //final.rgb *= ao; final.a = base.a; clip(final.a - _CutOff); return final; }
这里我注释掉了AO和高光遮罩,需要的同学可以加上。
最后一点为了不让头发的边经过clip之后太硬,需要进行两个通道的belnd。
第二个pass使用以下指令:
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
注意第二个通道无需再进行clip操作。
至此,头发渲染完毕。
相关文章推荐
- 各向异性的头发渲染
- 头发各向异性之comb map
- 利用镜面反射让游戏闪耀起来 - 创建各向异性高光类型
- 【Cocos2d-x游戏引擎开发笔记(3)】在屏幕上渲染菜单并添加消息响应
- 图像各向异性滤波
- 一些游戏用到的渲染技术
- 游戏引擎剖析--第1部分: 游戏引擎介绍, 渲染和构造3D世界
- ArcGIS教程:使用方向半变异函数和协方差函数考虑各向异性
- 游戏引擎架构----渲染
- 从GPU到3D渲染:游戏图形渲染技巧与性能优化
- atitit ui引擎之道 游戏引擎之道.docx 1. 概念 2 1.1. (cocos,createjs,dom) 2 2. 游戏引擎的构成(图形引擎(渲染系统),控件部件系统,事件系统 ,布局
- 【Cocos2d-x游戏引擎开发笔记(3)】在屏幕上渲染菜单并添加消息响应
- Unity3D游戏制作(二)——如何渲染3D角色
- 游戏中基于物理的渲染(一)
- 【《Real-Time Rendering 3rd》 提炼总结】(九) 第十章 · 游戏开发中基于图像的渲染技术总结
- 一点一滴完全突破KAZE特征检测算法,从各向异性扩散滤波开始(2)
- 自己动手写cocos2dx游戏引擎(五)——渲染对象
- 棋盘类游戏中的栅格地形渲染
- 游戏最高渲染帧率的垂直同步方式-----显示器的垂直刷新率
- 【游戏渲染】unity海边波浪效果的实现