Nvidia VertexTextureFetch Water
http://http.download.nvidia.com/developer/SDK/Individual_Samples/samples.html
http://http.download.nvidia.com/developer/SDK/Individual_Samples/DEMOS/Direct3D9/VertexTextureFetchWater.zip
This sample demonstrates a technique for simulating and rendering water. The water is simulated via Verlet integration of the 2D wave equation using a pixel shader. The simulation result is used by a vertex shader via vertex texture fetch (VTF). The water surface is rendered by combining screen-space refraction and reflection textures. |
![]() |
![]() |
#include "registers.hlsl"
sampler refractionSampler : register(s0); // Refraction map
sampler reflectionSampler : register(s1); // Reflection map
sampler refractionNearSampler : register(s2); // Refraction map for objects penetrating water's surface
sampler fadeSampler : register(s4); // A fade texture to alleviate some border artifacts
sampler simulationSampler : register(s257);
struct Interpolants
{
float4 positionSS : POSITION; // Screen space position
float2 reflectionTexCoord : TEXCOORD0; // texture coordinates for reflection map
float4 refractionTexCoords : TEXCOORD1; // texture coordinates for refraction maps
float3 normalWS : TEXCOORD2; // normal in world space
float3 eyeVectorWS : TEXCOORD3; // eye vector in world space
float3 lightVectorWS : TEXCOORD4; // light vector in world space
float3 halfVectorWS : TEXCOORD5; // half vector in world space
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Vertex Shader
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Vertex shader Function declarations
float2 computeTextureCoord(float4 positionWS, float3 directionWS, float distance, float2 scale, float2 offset);
Interpolants vertexShader(float4 positionMS : POSITION, // Model space position
float4 color0 : COLOR0,
float4 simulationTexCoord : TEXCOORD0, // texture coord to look up simulated height and normal
float4 perturbation : TEXCOORD1) // Describes how much to reflect / refract
{
Interpolants o = (Interpolants)0;
float4 simulationSample; // Sample for simulation that contains the height and normal
float4 positionWS;
float3 normalModelSpace;
float3 normalWS;
float3 reflectionVectorWS;
float3 refractionVectorWS;
// Look up the simulation result for this vertex
// simulationSample.x is the height (simulationSample.y, simulationSample.z, simulationSample.w) is the normal
simulationSample = tex2Dlod(simulationSampler, simulationTexCoord);
// Extract the height and normal out of the sample
// Stick the height in the position where it belongs
positionMS.y = simulationSample.x;
positionMS.w = 1; // This probably isn't necessary
normalModelSpace = simulationSample.yzw;
// Output the screen space position
o.positionSS = mul(positionMS, vsWorldViewProjectionMatrix);
// Compute the world space position
positionWS = mul(positionMS, vsWorldMatrix);
// Compute the world space normal
normalWS = mul(normalModelSpace, vsWorldMatrix);
// Flip the normal if we're under water
normalWS.xyz *= vsNormalSign.x;
// Output the world space normal
o.normalWS = normalWS;
// Output the eye vector in world space
o.eyeVectorWS = normalize(vsEyePositionWorld - positionWS);
// Output the light vector in world space
o.lightVectorWS = normalize(vsLightPositionWorld - positionWS);
// Output the half vector in world space
// No need to normalize because it's normalized in the pixel shader
o.halfVectorWS = o.eyeVectorWS + o.lightVectorWS;
//////////////////////////////////////////////////////////////////////////////////
//
// Calculate reflection map coordinates
//
//////////////////////////////////////////////////////////////////////////////////
// Compute the reflection vector in world space
reflectionVectorWS = reflect(-o.eyeVectorWS, normalWS);
// Compute the reflection map coordinates
o.reflectionTexCoord.xy = computeTextureCoord(positionWS, reflectionVectorWS, perturbation.x, vsReflectionTexcoordScaleOffset.xy,
vsReflectionTexcoordScaleOffset.zw);
//////////////////////////////////////////////////////////////////////////////////
//
// Calculate refraction map coordinates
//
//////////////////////////////////////////////////////////////////////////////////
// Compute the refraction vector in world space
refractionVectorWS = refract(-o.eyeVectorWS, normalWS, vsEtaRatio.x);
// Calculate the refraction map coordinates for objects that are not penetrating the water
o.refractionTexCoords.xy = computeTextureCoord(positionWS, refractionVectorWS, perturbation.y, vsRefractionTexcoordScaleOffset.xy,
vsRefractionTexcoordScaleOffset.zw);
// Calculate the refraction map coordinates for objects that are penetrating the water
o.refractionTexCoords.zw = computeTextureCoord(positionWS, refractionVectorWS, perturbation.w, vsRefractionTexcoordScaleOffset.xy,
vsRefractionTexcoordScaleOffset.zw);
return(o);
}
// computeTextureCoord() takes a starting position, direction and distance in world space.
// It computes a new position by moving the distance along the direction vector. This new
// world space position is projected into screen space. The screen space coordinates are
// massaged to work as texture coordinates.
float2 computeTextureCoord(float4 positionWS, float3 directionWS, float distance, float2 scale, float2 offset)
{
float4 positionSS;
// Compute the position after traveling a fixed distance
positionWS.xyz = positionWS.xyz + directionWS * distance;
positionWS.w = 1.0;
// Compute the screen space position of the newly computed position
positionSS = mul(positionWS, vsViewProjectionMatrix);
// Do the perspective divide
positionSS.xy /= positionSS.w;
// Convert screen space position from [-1,-1]->[1,1] to [0,0]->[1,1]
// This is done to match the coordinate space of the reflection/refraction map
positionSS.xy = positionSS.xy * 0.5 + 0.5;
// Account for the fact that we use a different field of view for the reflection/refraction maps.
// This overdraw allows us to see stuff in the reflection/refraction maps that is not visible
// from the normal viewpoint.
positionSS.xy = positionSS.xy * scale + offset;
// Flip the t texture coordinate upside down to be consistent with D3D
positionSS.y = 1 - positionSS.y;
// Return the screen space position as the result. This will be used as the texture coordinate
// for the screenspace reflection/refraction maps.
return(positionSS.xy);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Pixel Shader
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Pixel shader Function declarations
half computeFresnel(half3 light, half3 normal, half R0);
half4 pixelShader(Interpolants i) : COLOR
{
half4 refraction;
half4 reflection;
half4 refractionNear;
half4 reflectionNear;
half2 refractionTexCoord;
half2 refractionNearTexCoord;
half2 reflectionNearTexCoord;
half refractionVisibility;
half4 fade;
half4 specular;
half depth;
half fresnel;
// Normalize direction vectors
i.lightVectorWS = normalize(i.lightVectorWS);
i.normalWS = normalize(i.normalWS);
i.halfVectorWS = normalize(i.halfVectorWS);
// Compute the specular term
specular.x = pow(max(dot(i.halfVectorWS, i.normalWS), 0), 3);
// Put a cliff in the specular function
if(specular.x < 0.5)
{
specular.x = 2.0 * specular.x * specular.x;
}
specular.xyz = specular.xxx * half3(0.2, 0.2, 0.2);
specular.w = 0;
// Do the texture lookup for the reflection
reflection = tex2D(reflectionSampler, i.reflectionTexCoord.xy);
// Modulate the reflection texture by a texture to fade out at the edges.
// This avoids an objectionable artifact when the reflection map
// doesn't cover enough area.
fade = tex2D(fadeSampler, i.reflectionTexCoord.xy);
reflection *= fade;
// Do the texture lookup for the refraction
refractionTexCoord = i.refractionTexCoords.xy;
refractionNearTexCoord = i.refractionTexCoords.zw;
refraction = tex2D(refractionSampler, refractionTexCoord);
refractionNear = tex2D(refractionNearSampler, refractionNearTexCoord);
// Do a very simple compositing of objects in the refraction textures
if(dot(refractionNear.xyz, refractionNear.xyz) > 0.1)
{
refraction.xyz = refractionNear.xyz;
}
// Compute the fresnel to blend the refraction and reflection terms together
fresnel = computeFresnel(i.eyeVectorWS, i.normalWS, psFresnelR0.x);
// Handle total internal reflection
refractionVisibility = saturate(dot(i.eyeVectorWS, i.normalWS));
refractionVisibility = saturate((refractionVisibility - psTotalInternalReflectionSlopeBias.y) * psTotalInternalReflectionSlopeBias.x +
psTotalInternalReflectionSlopeBias.z);
refraction *= refractionVisibility;
// Give some blue tint to the refraction
refraction = lerp(refraction, half4(0, 0, 1, 0), .1);
#ifdef RETURN_REFRACTION
return(refraction);
#endif
#ifdef RETURN_REFLECTION
return(reflection);
#endif
#ifdef RETURN_FRESNEL
return(half4(fresnel, fresnel, fresnel, 1.0));
#endif
#ifdef RETURN_NORMALS
return(half4(i.normalWS.xyz, 1.0));
#endif
// Combine the refraction, reflection and specular terms
return(lerp(refraction, reflection, fresnel) + specular);
}
half computeFresnel(half3 eye, half3 normal, half R0)
{
// R0 = pow(1.0 - refractionIndexRatio, 2.0) / pow(1.0 + refractionIndexRatio, 2.0);
half eyeDotNormal;
eyeDotNormal = dot(eye, normal);
// Make sure eyeDotNormal is positive
eyeDotNormal = max(eyeDotNormal, -eyeDotNormal);
return(R0 + (1.0 - R0) * pow(1.0 - eyeDotNormal, 4.5));
}
Nvidia VertexTextureFetch Water的更多相关文章
- nVIDIA SDK White Paper ----Vertex Texture Fetch Water
http://blog.csdn.net/soilwork/article/details/713842 nVIDIA SDK White Paper ----Vertex Texture Fetch ...
- Using Vertex Texture Displacement for Realistic Water Rendering
http://blog.csdn.net/soilwork/article/details/709869 Using Vertex Texture Displacement for Realistic ...
- 解决Ubuntu Kylin 1610安装ANSYS17.2的NVIDIA显卡驱动问题
Ubuntu Kylin 1610在安装完毕后,会自动安装显卡驱动,对于一般的图形图像使用来说自然不会有太大的问题,但是对于ANSYS17.2的一些模块,还是会出现问题.一个比较常见的问题就是Open ...
- Fedora 21 安装 Nvidia 驱动以及失败后的补救方法
在 Linux 桌面系统下玩了这么久,大部分时间都是使用 Ubuntu,偶尔使用一下 Fedora.我的电脑中安装有多个 Linux 发行版,见这里<在同一个硬盘上安装多个Linux发行版及Fe ...
- 笔记:xubuntu下如何让系统默认使用nvidia显卡,而不是intel集显
经反复折腾,得到如下的解决方法: prime-select nvidia 简单吧,但关系是如果让它开机自动执行一次. 反复折腾了xinitrc ,~/.xinitrc , /etc/rc.local ...
- [LeetCode] Pacific Atlantic Water Flow 太平洋大西洋水流
Given an m x n matrix of non-negative integers representing the height of each unit cell in a contin ...
- [LeetCode] Trapping Rain Water II 收集雨水之二
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- [LeetCode] Water and Jug Problem 水罐问题
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...
- [LeetCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
随机推荐
- COURSES(poj 1469)
题意: 给你p门课程和n个学生,一个学生可以选0门,1门,或者多门课程,现在要求一个由p个学生组成的集合,满足下列2个条件: 1.每个学生选择一个不同的课程 2.每个课程都有不同的代表 如果满足,就输 ...
- 说说localStorage
HTML5的本地存储是大势所趋,如果仅存储在内存中,则是sessionStorage,他们的语法都是一样,仅仅是一个存储在本地文件系统中,另一个存储在内存中(随着浏览器的关闭而消失),其语句如下: l ...
- hrbustoj 1161:Leyni(树状数组练习)
LeyniTime Limit: 3000 MS Memory Limit: 65536 KTotal Submit: 260(59 users) Total Accepted: 80(55 user ...
- 【Android】SlidingMenu属性详解(转)
原文:http://my.eoe.cn/1169143/archive/21892.html SlidingMenu简介:SlidingMenu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者 ...
- 如何开启SQL Server 2008的远程联机
需要开启SQL Server 2008 远程联机,需按如下操作步骤执行: 1.首先需要在{程序}-{Microsoft SQL Server 2008}-{配置工具}-{SQL Server 配置管理 ...
- 输入文本框,当点击enter时,做进一步处理!
//登录用户文本框敲回车键 private void txtCode_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.En ...
- 在crontab中动态写日志
45 3 * * * setsid script -c /home/dlht/shell/coreBusiness/coreOpt.sh >> /home/dlht/logs/coreO ...
- linux全部命令
linux全部命令 一.安装和登陆命令1.进入图形界面startx 2.进入图形界面init 5 3.进入字符界面init 3 4.登陆login 5.关机poweroff-p 关闭机器的时候关闭电源 ...
- js:数据结构笔记3--栈
栈是一种特殊的列表,数据结构为LIFO: 定义: function Stack() { this.dataStore = []; this.top = 0; this.push = push; thi ...
- android studio ndk 调试
一: 先看看用 ndk-gdb 手动调试 这种方法只适用于手动编写 Android.mk 的情况,因为我们要手动 build debug 版本的 .so 文件.具体可以参考我的前一篇文章. 1 And ...