【TA-霜狼_may-《百人计划》】图形3.3 曲面细分与几何着色器 大规模草渲染

  • @[TOC](【TA-霜狼_may-《百人计划》】图形3.3 曲面细分与几何着色器 大规模草渲染
  • 3.3.1 曲面细分着色器的应用
  • 3.3.2 几何着色器的应用
    • 着色器执行顺序
  • 3.3.3 TESS的输入输出
  • 3.3.4 TESS流程(Tessellation Shader )
    • HULL Shader
  • 3.3.5 GS的输入与输出
  • 作业
    • 曲面细分
    • 大面积草渲染
    • Tessellation Shader
    • 草 Shader
    • 补充

3.3.1 曲面细分着色器的应用

  1. 海浪、雪地
  2. 与置换贴图的结合

3.3.2 几何着色器的应用

着色器执行顺序

3.3.3 TESS的输入输出

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

3.3.4 TESS流程(Tessellation Shader )

  1. HULL Shader

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

HULL Shader

  • Tessellation Factor
    用于决定将一条边分成几个部分
    equal_Spacing
    fractional_even_spacing:最小值为2
    fractional_odd_spacing:最小值为1

    后面两个参数包含小数部分,在线段两端存在非等长的部分,作用是使被切割后的线段更加平滑

  • Inner Tessellation Factor
    在分割点上作垂线并生成交点,从而得到有效的内部分割

3.3.5 GS的输入与输出

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

作业

曲面细分

大面积草渲染


根据顶点数进行草的生成,并且可以修改朝向,长短,宽度,颜色,并利用扭曲纹理做了风的效果。
照着下面这个链接做的,太顶了,搞了一晚上,差不多明白了各段代码的作用。对代码添加了自己的理解汉化了以后记录在后面,方便以后找。
大面积草渲染教程(纯英文教程讲的超好,可能要梯子?)

Tessellation Shader

Shader "Custom/100 learning/MyTessShader"
{Properties{_TessellationUniform ("Tessellation Uniform", Range(1, 64)) = 1}SubShader{Tags {"RenderType" = "Opaque"}Pass{LOD 200Name "FORWARD"Tags{"LightMode" = "ForwardBase"}CGPROGRAM// 曲面细分着色器中包含 hull shader 和 domain shader// 另外加上 顶点着色器和片元着色器#pragma hull hullShader#pragma domain domainShader#pragma vertex tessVert#pragma fragment frag#include "UnityCG.cginc"//曲面细分头文件 包括一些辅助函数#include "Tessellation.cginc"#pragma target 5.0sampler2D _MainTex;float4 _MainTex_ST;struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;};struct v2f{float4 pos : SV_POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;};// 应用于domain函数中,用于处理坐标v2f vert (a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.normal = v.normal;o.tangent = v.tangent;o.uv = v.uv;return o;}#ifdef UNITY_CAN_COMPILE_TESSELLATIONstruct tessVertex{float4 vertex : INTERNALTESSPOS;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;};// 不同的图元,该结构会有所不同 用于Hull Shaderstruct outputPatchConstant{float edge[3] : SV_TESSFACTOR;float inside : SV_INSIDETESSFACTOR;};// 将顶点着色器中的数据传入曲面细分着色器tessVertex tessVert(a2v 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;}// 确定图元的种类:quad / triangle[UNITY_domain("tri")]// 拆分edge的规则:equal_spacing, fractional_odd, fractional_even[UNITY_partitioning("fractional_odd")]// 输出三角形的情况,例如顺时针或者逆时针 与背面剔除等有关[UNITY_outputtopology("triangle_cw")]// 一个patch一共有三个点,但是这三个点都共用这个函数[UNITY_patchconstantfunc("hsconst")]// 不同的图元会对应不同的控制点[UNITY_outputcontrolpoints(3)]// 定义hullShader函数tessVertex hullShader (InputPatch<tessVertex, 3> patch, uint id : SV_OUTPUTCONTROLPOINTID){return patch[id];}// 定义图元的种类:与hull shader中相同[UNITY_domain("tri")]// bary代表重心坐标下的系数,将重心坐标下的点重新还回去v2f domainShader(outputPatchConstant tessFactors, const OutputPatch<tessVertex, 3> patch, float3 bary : SV_DOMAINLOCATION){a2v 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;v2f o = vert (v);return o;}#endiffixed4 frag(v2f i):SV_Target{return fixed4(1.0, 1.0, 1.0, 1.0);}ENDCG}}FallBack Off
}

草 Shader

Shader "Custom/100 learning/MyGrassShader"
{Properties{[Header(Shading)]// 颜色_TopColor("Top Color", Color) = (1,1,1,1)_BottomColor("Bottom Color", Color) = (1,1,1,1)_TranslucentGain("Translucent Gain", Range(0,1)) = 0.5// 草的宽度和高度 以及 对应的随机调整阈值_BladeWidth("Blade Width", Float) = 0.05_BladeWidthRandom("Blade Width Random", Float) = 0.02_BladeHeight("Blade Height", Float) = 0.5_BladeHeightRandom("Blade Height Random", Float) = 0.3// 随机倾斜阈值_BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2// Tessellation Shader 相关_TessellationUniform("Tessellation Uniform", Range(1, 64)) = 1// 加入风吹的扭曲纹理_WindDistortionMap("Wind Distortion Map", 2D) = "white" {}_WindFrequency("Wind Frequency", Vector) = (0.05, 0.05, 0, 0)// 风的强度_WindStrength("Wind Strength", Float) = 1}// CGINCLUDE一般写在SubShader的外面 方便所有 SubShader共用CGINCLUDE#include "UnityCG.cginc"#include "Autolight.cginc"#include "Tessellation.cginc"// 这个引用的作用跟上面的这个Tessellation一模一样#include "Assets/100PersonPlan/Shader/CustomTessellation.cginc"float _BendRotationRandom;float _BladeHeight;float _BladeHeightRandom;float _BladeWidth;float _BladeWidthRandom;sampler2D _WindDistortionMap;float4 _WindDistortionMap_ST;float2 _WindFrequency;float _WindStrength;struct geometryOutput{float4 pos : SV_POSITION;#if UNITY_PASS_FORWARDBASE//     float3 normal : NORMAL;float2 uv : TEXCOORD0;//     // unityShadowCoord4 is defined as a float4 in UnityShadowLibrary.cginc//     unityShadowCoord4 _ShadowCoord : TEXCOORD1;#endif};// https://forum.unity.com/threads/am-i-over-complicating-this-random-function.454887/#post-2949326// Returns a number in the 0...1 range.float rand(float3 co){return frac(sin(dot(co.xyz,float3(12.9898, 78.233, 53.539))) * 43758.5453);}// Construct a rotation matrix that rotates around the provided axis, sourced from:// https://gist.github.com/keijiro/ee439d5e7388f3aafc5296005c8c3f33float3x3 AngleAxis3x3(float angle, float3 axis){float c, s;// return sin and cos values of the given anglesincos(angle, s, c);float t = 1 - c;float x = axis.x;float y = axis.y;float z = axis.z;return float3x3(t * x * x + c, t * x * y - s * z, t * x * z + s * y,t * x * y + s * z, t * y * y + c, t * y * z - s * x,t * x * z - s * y, t * y * z + s * x, t * z * z + c);}// 由于在CustomTessellation.cginc中已经定义了 vertexInput vertexOutput 以及 vert// 所以下面三个部分省略// struct vertexInput{//     float4 vertex : POSITION;//     float3 normal : NORMAL;//     float4 tangent : TANGENT;// };// struct vertexOutput{//     float4 vertex : SV_POSITION;//     float3 normal : NORMAL;//     float4 tangent : TANGENT;// };// // Modify the vertex shader// vertexOutput vert(vertexInput v){//     vertexOutput o;//     o.vertex = v.vertex;//     o.normal = v.normal;//     o.tangent = v.tangent;//     return o;// }geometryOutput VertexOutput(float3 pos, float2 uv){geometryOutput o;o.pos = UnityObjectToClipPos(pos);o.uv = uv;return o;}// 将变换顶点的操作 转移到了geometry shader中,所以UnityObjectToClipPos写在geo shader中// 在函数声明部分共有两个参数 第一个为输入,表示接收一个triangle类型, (内部包含三个顶点)//第二个参数表示输出一个triangles,并利用geometryOutput来承载其中的数据[maxvertexcount(3)]void geo(triangle vertexOutput IN[3], inout TriangleStream<geometryOutput> triStream){geometryOutput o;float3 pos = IN[0].vertex;float3 vNormal = IN[0].normal;float4 vTangent = IN[0].tangent;float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;//用于在世界空间和切线空间之间进行转换float3x3 tangentToLocal = float3x3(vTangent.x, vBinormal.x, vNormal.x,vTangent.y, vBinormal.y, vNormal.y,vTangent.z, vBinormal.z, vNormal.z);// 根据当前位置随机生成旋转角度,并指定旋转为 z 轴(切线空间下)float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0,0,1));float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1,0,0));// 利用当前点的位置来取样扭曲纹理,而不是给定的网格的纹理坐标,从而达到逼真的风的效果float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;// 结合风的强度对扭曲纹理进行采样 纹理采样范围从0 - 1变为 -1 - 1float2 windSample = (tex2Dlod(_WindDistortionMap, float4 (uv, 0, 0)).xy * 2 - 1)* _WindStrength;// 生成旋转的轴float3 wind = normalize(float3(windSample.x, windSample.y, 0));// 生成旋转矩阵float3x3 windRotation = AngleAxis3x3(UNITY_PI * windSample, wind);// 利用平移矩阵和旋转矩阵生成变换矩阵float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);// 利用随机数生成每一片草的高度和宽度float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;float width = (rand(pos.xzy) * 2 -1) * _BladeWidthRandom + _BladeWidth;// 将点从模型空间转换到世界空间的处理提取到外面变成函数调用// 加以切线变化矩阵的应用就变成从切线空间到世界空间的转化triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(width, 0, 0)), float2(0, 0)));triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(-width, 0, 0)), float2(1, 0)));// 在切线坐标下,指向上的方向为z轴,所以此处的1应该赋予ztriStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(0, 0, height)), float2(0.5, 1)));}ENDCGSubShader{Cull OffPass{Tags{"RenderType" = "Opaque""lightMode" = "ForwardBase"}CGPROGRAM#pragma vertex vert#pragma hull hull#pragma domain domain#pragma geometry geo#pragma fragment frag#pragma target 4.6#pragma multi_compile_fwdbase#include "Lighting.cginc"float4 _TopColor;float4 _BottomColor;float _TranslucentGain;fixed4 frag(geometryOutput i, fixed facing : VFACE) : SV_Target{return lerp(_BottomColor, _TopColor, i.uv.y);}ENDCG}}FallBack Off
}

补充

看了别人的作业发现艹还有很多可以优化的点,之后再改改!

【TA-霜狼_may-《百人计划》】图形3.3 曲面细分与几何着色器 大规模草渲染相关推荐

  1. 百人计划 图形1.4 PC手机图形API介绍

    前言 电脑工作原理:电脑是有各种不同的硬件组成,由驱动软件驱使硬件进行工作.所有的如软件工程师都会直接或间接使用到驱动. 定义:是一个针对GPU的图形库,用于渲染2D.3D矢量图形的跨语言.跨平台的应 ...

  2. 百人计划 图形 2.5 BUMP图改进

    基础感念 凹凸贴图技术是对物体表面贴图进行变化然后再进行光照计算的一种技术.例如给法线分量添加噪音,或者在一个保存扰动值的纹理图中进行查找,这是一种提升物体真实感的有效办法,但却不需要额外的提升物体的 ...

  3. 百人计划 图形2.1 色彩空间

    色彩发送器 色彩认知:光源是出生点,光源发出光线,光线通过直射反射折射等路径最终进入人眼.在接收到光线后,人眼产生了一系列化学反应.由此把产生的信号传入大脑,大脑对颜色产生了认知感知. 光的要素: 光 ...

  4. 百人计划 图形2.2 模型与材质基础

    渲染流水线大致过程 1.顶点数据输入到顶点着色器中进行相关的顶点计算,然后进行图元装配,通过点与点之间的关系将点进行连接.2.再到几何着色器(可选着色器)进行图元的增加,再到光栅化通过遍历像素点将一个 ...

  5. 技美 百人计划 (图形)1.1渲染流程

    技美 百人计划 (图形) 图形 1.1 渲染流水管线2.1数学基础 很早之前就有关注百人计划这个系列的课程,也跟着看到了2.几的教学但是一直没有写笔记,最近看到百人计划已经快更新完毕了,决定从头看一遍 ...

  6. 【TA-霜狼_may-《百人计划》】图形3.4 延迟渲染管线介绍

    [TA-霜狼_may-<百人计划>]图形3.4 延迟渲染管线介绍 @[TOC]([TA-霜狼_may-<百人计划>]图形3.4 延迟渲染管线介绍 3.4.1 渲染路径 3.4. ...

  7. 【TA-霜狼_may-《百人计划》】图形3.7.2 command buffer简

    [TA-霜狼_may-<百人计划>]图形3.72command buffer 及urp概述 @[TOC]([TA-霜狼_may-<百人计划>]图形3.72command buf ...

  8. 【TA-霜狼_may-《百人计划》】图形4.5 DoF景深基础

    [TA-霜狼_may-<百人计划>]图形4.5 Dof景深基础 @[TOC]([TA-霜狼_may-<百人计划>]图形4.5 Dof景深基础 4.5.1 景深 离散圈 4.5. ...

  9. 【TA-霜狼_may-《百人计划》】图形2.7.2 GPU硬件架构概述

    [TA-霜狼_may-<百人计划>]图形2.7.2 GPU硬件架构概述 @[TOC]([TA-霜狼_may-<百人计划>]图形2.7.2 GPU硬件架构概述 GPU是什么 GP ...

  10. 个人学习笔记 ——【技术美术百人计划】图形 2.1 色彩空间介绍

    个人学习笔记 --[技术美术百人计划]图形 2.1 色彩空间介绍 图形 2.1 色彩空间介绍 个人学习笔记 --[技术美术百人计划]图形 2.1 色彩空间介绍 图形 2.1 色彩空间介绍 一.色彩发送 ...

最新文章

  1. 【C#公共帮助类】给大家分享一些加密算法 (DES、HashCode、RSA、AES等)
  2. c 高级函数的简单用法
  3. TreeView控件中实现拖拽的功能
  4. Oracle启动和停止的方式详解
  5. android datepicker 参数设置,如何在Android DatePicker中设置最小和最大日期?
  6. linux里强制覆盖,Linux cp命令无法强制覆盖
  7. 编译GDAL支持OpenCL使用GPU加速
  8. 的内怎么放_燕窝买回来怎么炖?资深窝友告诉你!
  9. 使用HTML5构建iOS原生APP(2)
  10. 通往Java架构师之路
  11. 有限元工程应用方法-ANSYS单元刚度矩阵计算理论详解
  12. AtCoder Beginner Contest 160 A ~ E
  13. 美国大学计算机软件专业排名,美国大学计算机专业排名
  14. linux 内存取证_内存取证工具volatility
  15. 微信小程序多次跳转后不能点_微信突然更新,但我劝你这次别升级
  16. 三星官宣所有5G设备信息图 看完有何感想
  17. 查看自己电脑的处理器和操作系统的位数
  18. c语言iota怎么用,IOTA(埃欧塔)钱包使用教程
  19. MMX、SSE、AVX等SIMD指令集说明
  20. 《满城黄金甲》另类观后感

热门文章

  1. 阅读了Steve Yegge的文章。其中有一篇叫“Practicing Programming”(练习编程),写成于2005年
  2. 如何将WebRoot部署到tomcat中
  3. T 型与π型衰减网络
  4. Mysql创建事件执行任务
  5. VI设计手册制作全流程
  6. JAVA实现出题团队
  7. STM32F4移植ucos_II
  8. 基于随机森林实现特征选择降维及回归预测(Matlab代码实现)
  9. 用计算机求和公式,全国计算机一级等考excel之sum求和函数
  10. Pycharm画图中文显示报错:UserWarning: Glyph 20013 (\N{CJK UNIFIED IDEOGRAPH-4E2D}) missing from current font.