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 ...
随机推荐
- Struts2标签库
一. 写jsp页面的时候,在struts2中,用的是s标记,先引入标记: <%@ taglib prefix="s" uri="/struts-tags" ...
- mysql 源码包 有的版本 可能没有 CMakeCache.txt
如果没有CMakeCache.txt 文件编译的时候会报错!!找不到CMakeCache.txt
- mysql多实例(个人的情况,不是大众的)里面有配置好的脚本+主从复制
[root@DB-S ~]# ll /usr/local/|grep mysql lrwxrwxrwx. 1 root root 21 Jun 14 01:52 mysql -> /alidat ...
- 搭建邮局(邮件服务器) - hmailserver
1.查看服务器mx是否解析成功 nslookup set type=mx 2.hmailserver服务器 smtp设置 3.foxmail 设置 4.使用webmail(after ...
- Gradle构建Java项目
前提:已经安装好Gradle 一.创建目录结构 在项目主目录下,创建以下子目录;在*nix系统下可以使用命令: mkdir -p src/main/java/hello vim src/main/ja ...
- Java Hour 44 Hibernate
其实要学习的东西很多,奈何人的精力和时间终归是有限的. 这里先暂且放下struts2 相关的东西,当然这里也先寄存这不少相关的好书,等我来看. 44.1 Hibernate 是一个好项目 目标在于成为 ...
- phpcms V9 改造:输出sql语句
.修改数据库驱动 phpcms/libs/classes/mysql..修改模型 phpcms/libs/classes/model..调用 使用自定义模型类查询完成之后,调用模型类的lastsql( ...
- URL和URI的区别与联系
转自:http://win7452.blog.51cto.com/147513/45741 今天在看STRUTS配置的时候,发现一个问题,就是在看配置文件的时候,有时出现URL有时又是URI, 让我心 ...
- C语言标量类型(转)
在C语言中,枚举类型.字符型和各种整数的表示形式统一叫做标量类型. 当在C表达式中使用标量类型的值时,编译器就会自动将这些标识符转换为整数保存. 这种机制的作用是,在这些标量类型上执行的操作与整型上执 ...
- 虚拟机下运行linux通过nat模式与主机通信、与外网连接
首先:打开虚拟机的编辑菜单下的虚拟网络编辑器,选中VMnet8 NAT模式.通过NAT设置获取网关IP,通过DHCP获取可配置的IP区间.同时,将虚拟机的虚拟机菜单的设置选项中的网络适配器改为NAT模 ...

