shader学习笔记 - 水底效果
2016-08-30 18:32
585 查看
来自:DX Samples: PIXGameDebugging.fx
包括两个部分:
1. 棋盘上所看到的水波花纹
2. 纵向的光纹
水波花纹
关键:
1. 使用32张现成的腐蚀纹理(caustic),来做水波变化的动态效果 2. 将光线、腐蚀因子、物体颜色,三者相乘
CPU部分:
1. 需要输入时间; 2. 预先加载所有纹理,利用时间(或其他)计算选取哪张腐蚀纹理,并设置。
效果代码:
VS_OUT CausticVS(VS_IN IN) // vertex shader { VS_OUT OUT; float2x2 rotation = {COS_0_15F, -SIN_0_15F, SIN_0_15F, COS_0_15F}; // 一个常数 float4 viewPosition = mul(IN.Position, WorldView); // 在观察空间的位置。【位置 * ( worldTrans * ViewTrans )】 float3 viewNormal = normalize(mul(IN.Normal, WorldViewIT)); // 把法线转换到观察空间。【法线 / ( worldTrans * ViewTrans )】【这里为啥是除法,不懂】 OUT.Position = mul(IN.Position, WorldViewProj); // 输出位置 = 输入位置变换到投影空间的结果 OUT.Color = Light1Ambient + dot(viewNormal, Light1Dir); // 输出颜色 = 环境光 + 漫反射光(此处没有使用漫反射系数) OUT.TexCoord0 = IN.TexCoord; // 输出纹理坐标0 = 原纹理坐标0,将会被用作获取物体本身的纹理 OUT.TexCoord1.xy = mul(viewPosition.xz, rotation); // 输出纹理坐标1 = 观察空间的位置 * 一个固定的旋转,将会被用作获取腐蚀纹理 OUT.Fog = FogData.z * (FogData.y - length(viewPosition.xyz)); // 对观察空间位置到原点的距离,利用一个输入的变量进行线性变换,得到最终的雾效大小 return OUT; } float4 CausticPS(VS_OUT IN) : COLOR // pixel shader { float2 movement = IN.TexCoord1.xy; movement.x = movement.x + cos(Time * 0.2f) * 0.3f; // 对vs中计算的“表征观察空间中的位置”的二维向量,加上一个时间相位 movement.y = movement.y + sin(Time * 0.3f) * 0.2f; float3 color = IN.Color.rgb * tex2D(CausticTextureSampler, movement.xy * 0.9f); // 将上述随时间和空间变化的固定值,作为纹理坐标,索引到腐蚀纹理中,然后与原有光效颜色,使用乘法进行混合 color = color * tex2D(MeshTextureSampler, IN.TexCoord0.xy); // 将物体本身颜色与水波花纹相乘,也使用乘法 return float4(color, 1.0f); }
纵向光纹 - 第一种
关键:
在CPU中多次渲染,来控制光线厚度;使用一个两个三角形组成的长方形,来作为渲染对象,以此在ps中遍历屏幕;
使用上述长方形本身的颜色的alpha值,来控制在屏幕上的透明变化;
CPU部分:
按照light layer的值进行多次渲染;制作一个由两个三角形组成的长方形的模型,作为渲染对象【不知道为什么要用1.1和1.5】;
LightShaftVertex g_LightVertices[] = // triangle list for lightshafts { { -1.0f, -1.1f, 0.0f, 0x0066ccff }, { -1.0f, 1.5f, 0.0f, 0x1166ccff }, // x, y, z, color { 1.0f, -1.10f, 0.0f, 0x0066ccff }, { -1.0f, 1.5f, 0.0f, 0x1166ccff }, { 1.0f, 1.5f, 0.0f, 0x1166ccff }, { 1.0f, -1.1f, 0.0f, 0x0066ccff }, };
效果部分:
VS_LIGHTSHAFT_OUT LightShaftAlternateVS(VS_LIGHTSHAFT_IN IN) // vertex shader { VS_LIGHTSHAFT_OUT OUT; OUT.Position = IN.Position; // 输出位置依然是输入位置,因为输入已经被当做是屏幕位置了 OUT.Position.z = OUT.Position.z + LightShaftZ; // 由CPU控制z值平滑变化,防止重叠;在多层layer的情况下,z值还会有一个平滑的变化,从而也使得重叠显得更为有质感 OUT.Color = IN.Color; // 颜色固定 OUT.TexCoord0.xy = OUT.Position.xz*0.9f; // 把屏幕坐标的x和z作为输出的纹理坐标,亦即其z值不变【不知道为什么要带一个缩放】 return OUT; } float4 LightShaftPS(VS_LIGHTSHAFT_OUT IN) : COLOR // pixel shader { float3 color = IN.Color.rgb * tex2D(CausticTextureSampler, IN.TexCoord0.xy); // 根据上边生成出的uv坐标,在腐蚀纹理中得到颜色。将其与原有颜色相乘作为最终颜色 return float4(color, IN.Color.a); // 注:本效果框架中alpha混合模式为src=srcalpha, dest=one,因而对最终颜色总是加强的 }
纵向光纹 - 第二种
关键:
在第一种的基础上,修改alpha值为一个程序输入的固定值,从而造成在y方向上光纹透明度不变CPU部分:
效果部分:
VS_LIGHTSHAFT_OUT LightShaftVS(VS_LIGHTSHAFT_IN IN) // vertex shader { VS_LIGHTSHAFT_OUT OUT; float2x2 rotation = {COS_0_15F, -SIN_0_15F, SIN_0_15F, COS_0_15F}; // 固定的旋转 OUT.Position = IN.Position; // 输出的位置为输入的位置(屏幕位置) float4 movement = IN.Position; movement.x = movement.x + cos(Time * 0.2f) * 0.3f; // 增加时间相位 movement.z = movement.z + sin(Time * 0.3f) * 0.2f; OUT.Position.z = OUT.Position.z + LightShaftZ; // z值增加一个可控变量。该值在多层layer时平滑递减 OUT.Color = IN.Color; OUT.Color.a = LightShaftAlpha; // 颜色为本身颜色,alpha值为程序控制,为固定值 OUT.TexCoord0.xy = mul(OUT.Position.xz, rotation) + movement.xz; // 原位置的旋转 + 原位置 + 时间相位 OUT.TexCoord0.xy = OUT.TexCoord0.xy * 0.9f + 1.0f / (1.0f - OUT.Position.z); // 缩放后加上一个外部控制的变量LightShaftZ 【不知道为什么要加这个变量】 return OUT; } float4 LightShaftPS(VS_LIGHTSHAFT_OUT IN) : COLOR // pixel shader { float3 color = IN.Color.rgb * tex2D(CausticTextureSampler, IN.TexCoord0.xy); // 同前 return float4(color, IN.Color.a); }
相关文章推荐
- Unity Shader入门精要学习笔记 - 第8章 透明效果
- Unity Shader 学习笔记(22) Bloom效果
- Unity Shader 学习笔记 (五) 积雪效果Shader
- UnityShader入门精要学习笔记(十一):透明效果-下部分
- Unity Shader 学习笔记(28) 噪声纹理、消融效果、水波效果、噪声雾效
- Unity Shader 学习笔记(十) 滚动效果Shader实例
- Unity Shader入门精要学习笔记 - 第8章 透明效果
- UnityShader入门精要学习笔记(十):透明效果-上部分
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
- Unity Shader学习笔记:Bloom效果
- Shader 学习笔记 ---Z-Buffering or W-Buffering
- Shader 学习笔记 (1)
- FLEX拖拽效果中的DragManager等关键词学习笔记
- papervision3d学习笔记:螺旋效果
- flash学习笔记:模仿QQ振动效果(转载夏天的树)
- SHADER 学习笔记 (2)
- Shader 学习笔记 ---Looking Through a Filter 过滤器
- Silverlight学习笔记--动画效果-- 渐变风格方式动画
- jQuery学习笔记:效果
- jQuery 学习笔记之十五 图片切换效果