着色器执行顺序

顶点着色器—>曲面细分着色器—>几何着色器—>片元着色器

曲面细分着色器细分后的顶点属于重心空间。

曲面细分着色器

应用:海浪、雪地等

与置换贴图结合:只使用法线贴图模型的边缘凹凸感差,使用曲面细分着色器增强模型边缘的凹凸感

输入 Patch,可以看成是多个顶点的集合,包含每个顶点的属性,可以指定一个Patch包含的顶点数以及自己的属性
功能 将图元细分(可以是三角形,矩形等)
输出 细分后的顶点

工作流程:

●HULL Shader
        1.决定细分的数量(设定Tessellation factor以及Inside Tessellationfactor)
        2.对输入的Patch参数进行改变(如果需要)
●Tessellation Primitive Generation
        进行细分操作
●Domain Shader
        对细分后的点进行处理,从重心空间(Barycentric coordinate system)转换到屏幕空间

参数解析:

HULL Shader:

●Tessellation Factor:决定将一条边分成几部分
        equal_ Spacing        等分
        fractional_ even_ spacing         向上取偶数,最小值是2
        fractional odd_ spacing             向上取奇数,最小值是1
●Inner Tessellation Factor:【3等分】将三角形每条边3等分,并通过等分点做边的垂线,交点为新的内部三角形顶点,直到不可再等分。

在使用曲面细分着色器前需要定义shader:

Shader "Unlit/TessShader"
{Properties{_TessellationUniform("TessellationUniform",Range(1,64)) = 1}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM//定义2个函数 hull domain#pragma hull hullProgram#pragma domain ds#pragma vertex tessvert#pragma fragment frag#include "UnityCG.cginc"//引入曲面细分的头文件#include "Tessellation.cginc" #pragma target 5.0struct VertexInput{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;float4 tangent : TANGENT;};struct VertexOutput{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;};VertexOutput vert (VertexInput v)//这个函数应用在domain函数中,用来空间转换的函数{VertexOutput o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.tangent = v.tangent;o.normal = v.normal;return o;}//有些硬件不支持曲面细分着色器,定义了该宏就能够在不支持的硬件上不会变粉,也不会报错#ifdef UNITY_CAN_COMPILE_TESSELLATION//顶点着色器结构的定义struct TessVertex{float4 vertex : INTERNALTESSPOS;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;};struct OutputPatchConstant { //不同的图元,该结构会有所不同//该部分用于Hull Shader里面//定义了patch的属性//Tessellation Factor和Inner Tessellation Factorfloat edge[3] : SV_TESSFACTOR;float inside  : SV_INSIDETESSFACTOR;};TessVertex tessvert (VertexInput v){//顶点着色器函数TessVertex o;o.vertex  = v.vertex;o.normal  = v.normal;o.tangent = v.tangent;o.uv      = v.uv;return o;}float _TessellationUniform;OutputPatchConstant hsconst (InputPatch<TessVertex,3> patch){//定义曲面细分的参数OutputPatchConstant o;o.edge[0] = _TessellationUniform;o.edge[1] = _TessellationUniform;o.edge[2] = _TessellationUniform;o.inside  = _TessellationUniform;return o;}[UNITY_domain("tri")]//确定图元,quad,triangle等[UNITY_partitioning("fractional_odd")]//拆分edge的规则,equal_spacing,fractional_odd,fractional_even[UNITY_outputtopology("triangle_cw")][UNITY_patchconstantfunc("hsconst")]//一个patch一共有三个点,但是这三个点都共用这个函数[UNITY_outputcontrolpoints(3)]      //不同的图元会对应不同的控制点TessVertex hullProgram (InputPatch<TessVertex,3> patch,uint id : SV_OutputControlPointID){//定义hullshaderV函数return patch[id];}[UNITY_domain("tri")]//同样需要定义图元VertexOutput ds (OutputPatchConstant tessFactors, const OutputPatch<TessVertex,3>patch,float3 bary :SV_DOMAINLOCATION)//bary:重心坐标{VertexInput v;v.vertex = patch[0].vertex*bary.x + patch[1].vertex*bary.y + patch[2].vertex*bary.z;v.tangent = patch[0].tangent*bary.x + patch[1].tangent*bary.y + patch[2].tangent*bary.z;v.normal = patch[0].normal*bary.x + patch[1].normal*bary.y + patch[2].normal*bary.z;v.uv = patch[0].uv*bary.x + patch[1].uv*bary.y + patch[2].uv*bary.z;VertexOutput o = vert (v);return o;}#endiffloat4 frag (VertexOutput i) : SV_Target{return float4(1.0,1.0,1.0,1.0);}ENDCG}}Fallback "Diffuse"
}

与置换图结合

Shader "Unlit/Tess_Diss_Shader"
{Properties{_MainTex("MainTex",2D) = "white"{}_DisplacementMap("_DisplacementMap",2D)="gray"{}_DisplacementStrength("DisplacementStrength",Range(0,1)) = 0_Smoothness("Smoothness",Range(0,5))=0.5_TessellationUniform("TessellationUniform",Range(1,64)) = 1}SubShader{Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}LOD 100Pass{CGPROGRAM//定义2个函数 hull domain#pragma hull hullProgram#pragma domain ds#pragma vertex tessvert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"//引入曲面细分的头文件#include "Tessellation.cginc" #pragma target 5.0float _TessellationUniform;sampler2D _MainTex;float4 _MainTex_ST;sampler2D _DisplacementMap;float4 _DisplacementMap_ST;float _DisplacementStrength;float _Smoothness;struct VertexInput{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;float4 tangent : TANGENT;};struct VertexOutput{float2 uv : TEXCOORD0;float4 pos : SV_POSITION;float4 worldPos:TEXCOORD1;half3 tspace0 :TEXCOORD2;half3 tspace1 :TEXCOORD3;half3 tspace2 :TEXCOORD4;};VertexOutput vert (VertexInput v)//这个函数应用在domain函数中,用来空间转换的函数{VertexOutput o;o.uv = TRANSFORM_TEX(v.uv,_MainTex);//Displacement//由于并不是在Fragnent shader中读取图片,GPU无法获取mipmap信息,因此需要使用tex2Dlod来读取图片,使用第四坐标作为mipmap的level,这里取了0float Displacement = tex2Dlod(_DisplacementMap,float4(o.uv.xy,0.0,0.0)).g;Displacement = (Displacement-0.5)*_DisplacementStrength;v.normal = normalize(v.normal);v.vertex.xyz += v.normal * Displacement;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);//计算切线空间转换矩阵half3 vNormal = UnityObjectToWorldNormal(v.normal);half3 vTangent = UnityObjectToWorldDir(v.tangent.xyz);//compute bitangent from cross product of normal and tangenthalf tangentSign = v.tangent.w * unity_WorldTransformParams.w;half3 vBitangent = cross(vNormal,vTangent)*tangentSign;//output the tangent space matrixo.tspace0 = half3(vTangent.x,vBitangent.x,vNormal.x);o.tspace1 = half3(vTangent.y,vBitangent.y,vNormal.y);o.tspace2 = half3(vTangent.z,vBitangent.z,vNormal.z);return o;}//有些硬件不支持曲面细分着色器,定义了该宏就能够在不支持的硬件上不会变粉,也不会报错#ifdef UNITY_CAN_COMPILE_TESSELLATION//顶点着色器结构的定义struct TessVertex{float4 vertex : INTERNALTESSPOS;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;};struct OutputPatchConstant { //不同的图元,该结构会有所不同//该部分用于Hull Shader里面//定义了patch的属性//Tessellation Factor和Inner Tessellation Factorfloat edge[3] : SV_TESSFACTOR;float inside  : SV_INSIDETESSFACTOR;};TessVertex tessvert (VertexInput v){//顶点着色器函数TessVertex o;o.vertex  = v.vertex;o.normal  = v.normal;o.tangent = v.tangent;o.uv      = v.uv;return o;}//float _TessellationUniform;OutputPatchConstant hsconst (InputPatch<TessVertex,3> patch){//定义曲面细分的参数OutputPatchConstant o;o.edge[0] = _TessellationUniform;o.edge[1] = _TessellationUniform;o.edge[2] = _TessellationUniform;o.inside  = _TessellationUniform;return o;}[UNITY_domain("tri")]//确定图元,quad,triangle等[UNITY_partitioning("fractional_odd")]//拆分edge的规则,equal_spacing,fractional_odd,fractional_even[UNITY_outputtopology("triangle_cw")][UNITY_patchconstantfunc("hsconst")]//一个patch一共有三个点,但是这三个点都共用这个函数[UNITY_outputcontrolpoints(3)]      //不同的图元会对应不同的控制点TessVertex hullProgram (InputPatch<TessVertex,3> patch,uint id : SV_OutputControlPointID){//定义hullshaderV函数return patch[id];}[UNITY_domain("tri")]//同样需要定义图元VertexOutput ds (OutputPatchConstant tessFactors, const OutputPatch<TessVertex,3>patch,float3 bary :SV_DOMAINLOCATION)//bary:重心坐标{VertexInput v;v.vertex = patch[0].vertex*bary.x + patch[1].vertex*bary.y + patch[2].vertex*bary.z;v.tangent = patch[0].tangent*bary.x + patch[1].tangent*bary.y + patch[2].tangent*bary.z;v.normal = patch[0].normal*bary.x + patch[1].normal*bary.y + patch[2].normal*bary.z;v.uv = patch[0].uv*bary.x + patch[1].uv*bary.y + patch[2].uv*bary.z;VertexOutput o = vert (v);return o;}#endiffloat4 frag (VertexOutput i) : SV_Target{float3 lightDir =_WorldSpaceLightPos0.xyz;float3 tnormal = UnpackNormal (tex2D (_DisplacementMap, i.uv));half3 worldNormal;worldNormal.x=dot(i.tspace0,tnormal);worldNormal.y= dot (i.tspace1, tnormal);worldNormal.z=dot (i.tspace2, tnormal);float3 albedo=tex2D (_MainTex, i.uv). rgb;float3 lightColor = _LightColor0.rgb;float3 diffuse = albedo * lightColor * DotClamped(lightDir,worldNormal);float3 viewDir = normalize (_WorldSpaceCameraPos. xyz-i. worldPos. xyz);float3 halfVector = normalize(lightDir + viewDir);float3 specular = albedo * pow (DotClamped (halfVector, worldNormal), _Smoothness * 100);float3 result = specular + diffuse;return float4(result, 1.0);return float4(result,1.0);}ENDCG}}Fallback "Diffuse"
}

使用顶点片元着色器实现https://mp.weixin.qq.com/s?__biz=MzIxMzgzMzQxOA==&mid=2247485821&idx=1&sn=b319cd540eee34f8a064270b9cb933e2&chksm=97b18ad8a0c603ce412bab0666aa57f57320bb009cf9af2c0ce76ac14b10fa8bbe77a564436e&scene=178&cur_album_id=1745807625885171715#rd 使用表面着色器实现https://zhuanlan.zhihu.com/p/141021857

几何着色器

应用:几何动画、草地生成(与曲面细分着色器结合,控制草的密度)

输入 图元(三角形,矩形,线等),根据图元的不同,shader中会出现对应不同数量的顶点
输出 同样为图元,一个或多个,需要自己从顶点构建,顺序很重要同时需要定义最大输出的顶点数


几何着色器https://blog.csdn.net/sinat_25415095/article/details/111403397

无尽草地https://zhuanlan.zhihu.com/p/29632347

粒子和毛发效果https://blog.csdn.net/qq_36107199/article/details/88579359参考视频

参考大佬笔记

曲面细分着色器与几何着色器相关推荐

  1. Shader入门---曲面细分着色器和几何着色器

    Shader入门-曲面细分着色器和几何着色器 前记:学不可以停止-------------------------------mx 基础知识: 曲面细分着色器:可以将一个几何体细化为一个球体也能将一根 ...

  2. 翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化

    翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化 翻译自: Exploring GLSL – Normal Visualizer with Geometry Shaders (Shader ...

  3. UnityShader[4]几何着色器与可交互草地

    GeometryShader执行顺序在顶点着色器之后,片元着色器以前.GeometryShader以一个/多个顶点组成的图元为输入,开发人员可以修改/添加顶点,修改为完全不同的网格,得到更多好看的效果 ...

  4. Unity之几何着色器--草随风摇曳

    1. 简介12 1.1 主要工作: 通过HeightMap生成地形网格 通过分块的思想生成草的初始定位顶点 通过几何着色器配合伪随机数生成草的网格 通过伪随机函数来对风进行模拟 通过Blinn Pho ...

  5. LearnOpenGL学习笔记——几何着色器

    几何着色器 在顶点和片段着色器之间有一个可选的几何着色器(Geometry Shader),几何着色器的输入是一个图元(如点或三角形)的一组顶点.几何着色器可以在顶点发送到下一着色器阶段之前对它们随意 ...

  6. LearnOpenGL-高级OpenGL-9.几何着色器

    本人初学者,文中定有代码.术语等错误,欢迎指正 文章目录 几何着色器 使用几何着色器 造几个房子 爆破物体 法向量可视化 几何着色器 简介 在顶点和片段着色器之间有一个可选的几何着色器 几何着色器的输 ...

  7. OpenGL学习笔记(十)-几何着色器-实例化

    参考网址:LearnOpenGL 中文版 4.7 几何着色器 4.7.1 基本概念 1.顶点和片段着色器之间有一个可选的几何着色器,几何着色器的输入是一个图元(如点或三角形)的一组顶点,顶点发送到下一 ...

  8. DirectX11 使用几何着色器实现公告板效果

    之前说过,可编程的着色器阶段有三个,依次是顶点着色器.几何着色器.像素着色器.之前说的都是顶点着色器和像素着色器,今天第一次详细介绍几何着色器,几何着色器是一个可选的阶段. 一.使用几何着色器的好处 ...

  9. 顶点着色器和片段着色器的区别

    1:图片中,渲染管线大致被分为6个步骤,其中有3个步骤是蓝色背景.这3个蓝色背景的步骤,就是可编程渲染管线中用户可以自定义的部分.(一般来说,我们只自定义顶点着色器和片段着色器,几何着色器一般使用默认 ...

最新文章

  1. AI人工智能的未来?AI科技与AI教程?答案都在这里!
  2. MySQL事物系列:1:事物简介
  3. python面试题之“该死的for循环系列”(二)
  4. nginx 安装 虚拟主机
  5. TurboMail邮件服务器荣膺“2012年度中国行业信息化最佳产品奖”
  6. 我的世界服务器被无限循环怎么办,我的世界怎么制作无限循环装置_我的世界无限循环装置制作方法_游戏堡...
  7. ANT 运行jar包的中文乱码问题
  8. 牛客网_PAT乙级1004_福尔摩斯的约会 (20)
  9. python爬虫实际应用_如何使用python爬虫论坛?
  10. Android通过广播接收者调用服务内方法
  11. 颜色特征识别—识别红色,黄色,绿色,蓝色排针的数量
  12. Node.js 之 Crypto模块
  13. 机器学习实战——xgboost股票close预测
  14. uniapp App更新解决方法
  15. AndroidStudio 跑马灯效果不自动滚动的原因
  16. mp2551总线收发器芯片作用_高速CAN收发器MCP2551
  17. Linux驱动学习笔记之触摸屏驱动
  18. Yolov3没框原因和解决办法
  19. @用Python的turtle库画一个奥运五环!
  20. 小白推荐系统扫盲记——数据分析

热门文章

  1. php怎么点击确认收货,解决修正Ecshop的recieve.php邮件自动确认收货问题
  2. 视觉检测设备,工业视觉检测设备的介绍
  3. Adavanced Installer 用户自定义行为——卸载时删除残留日志文件
  4. 多媒体会议室解决方案,为企业高效会议助力!
  5. UVA OJ 650题, 2013年9月6日
  6. GEO数据库中单细胞测序数据下载
  7. 入门OJ 3793: [Noip模拟题]剪草 (DP)
  8. KlayGE中的字体
  9. 知识图谱构建技术一览 #CSDN博文精选# #高效学习法# #系统化学习# #IT技术学习#
  10. 2019icassp主页浏览见闻~~