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 ...
随机推荐
- NEXTDAY
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "com_time ...
- java中基本输入输出流的解释(flush方法的使用)
转自:http://fsz521job.itpub.net/post/5606/34827 网络程序的很大一部分是简单的输入输出,即从一个系统向另一个系统移动字节.字节就是字节,在很大程度上,读服务器 ...
- 前端调试效率低?试试这10个“Chrome开发者工具”使用技巧
摘要:今天给大家分享一些使用“Chrome开发者工具”的小技巧.包括调试,优化页面渲染速度等.希望能提升Web开发人员的工作效率. 今天给大家分享一些使用“Chrome开发者工具”的小技巧.包括调试, ...
- 【spring 区别】ClassXmlAplicationContext和FileSystemXmlApplicationContext的区别
今天写一个简单的spring使用例子,遇到这个问题: 项目结构如下: 代码如下: package com.it.sxd; import java.nio.file.FileSystem; import ...
- hive复杂类型与java类型的对应
因为要往自定义的UDF传入复杂类型,所以需要对于这块的对应简单做一下总结 string java.lang.String, org.apache.hadoop.io.Text int int, jav ...
- node工具--express
//使用supervisor Connect是基于HTTP米快创建的:Express则是基于Connect上创建的: 绝大多数web服务器和浏览器之间的任务是通过url和method完成的,两者的组 ...
- 数据采集器移动手持打印POS终端(PDA)商超抄单方案-PDA抄单无线开单+进销存软件
PDA主要应用在业务员外出在超市能及时抄单发送回总公司,总公司办公人员及时在软件里面调出业务员的抄单数量进行配货,大大提供工作效率. 移动数据终端和无线基础架构相结合,面向零售与批发门店店员的解决方案 ...
- MVC _ViewStart文件的作用
指定目录下的所有文件均继承自 某个Layout. 支持最近原则. 参考:http://www.cnblogs.com/iamlilinfeng/archive/2013/02/28/2934397.h ...
- !cocos2d 重复添加action事件
当点击的时候,如果不是按照开始点击计算的,那么持续点击会导致不会变大. void Piece::setActived(bool active) { _actived = active; CCActio ...
- C++中inline这个玩意儿
inline 说明这个函数是内联的,在编译过程中内联函数会直接被源代码替换,提高执行效率 如果类中的某个函数会被调用很多次或者放在循环中,那么建议将这个函数声明为内联,可以提高程序的运行效率