/* Noise/Turbulence experiments (c) Holger Grahn - hg .at. snafu.de http://www.x79.net 05/2004 */ string description = "Turbulence distored texture"; //------------------------------------ // state parameters float4x4 worldViewProj : WorldViewProjection < string UIWidget="None"; >; float4x4 world : World < string UIWidget="None"; >; float4x4 worldInverseTranspose : WorldInverseTranspose < string UIWidget="None"; >; float4x4 viewInverse : ViewInverse < string UIWidget="None"; >; float4x4 proj : Projection < string UIWidget="None"; >; // parameters float time : Time < string UIWidget="None"; >; // Textures texture diffuseTexture : Diffuse < string ResourceName = "flame.png"; // colors2.dds >; #define VOLUME_SIZE 64 texture noiseTexture < // string Name = "noiseL8_32x32x32.dds"; string texturetype = "3D"; string format = "L8"; string function = "GenerateRadialGradient"; //"GenerateNoise"; int width = VOLUME_SIZE, height = VOLUME_SIZE, depth = VOLUME_SIZE; >; // Scalar noise float GenerateNoise(float3 Position : POSITION, float3 psize : PSIZE) : COLOR { float3 P = psize*0.5+ Position/psize; //float3 P = Position * (VOLUME_SIZE); // noise The output range is between -1 and 1 //return noise(P); //return noise(P)*0.5+0.5; //return abs(noise(P)); return abs(cos(noise(P)*3.1414*2)); } float GenerateRadialGradient(float3 position : POSITION, float3 psize : PSIZE) : COLOR { float3 p = (position-0.5)*2.0; // center in -1 1 float r = length(p); float a=1.0; if (r>1.0) a = 1.0f-(r-1.0f); // nm max is sqrt(2.0); float g = r; // saturate(r); g=0.5; //g = abs(sin(g)*3.1414); float4 color = float4(g,g,g,a); return color; } float noiseAmount < string UIWidget = "slider"; float UIMin = 0.000; float UIMax = 5.0; float UIStep = 0.01; > = 0.8; float noiseScale < string UIWidget = "slider"; float UIMin = 0.000; float UIMax = 2.0; float UIStep = 0.01; > = 0.1; float noiseTranslation < string UIWidget = "slider"; float UIMin = 0.000; float UIMax = 2.0; float UIStep = 0.01; > = 0.0; float4 lightDir : Direction < string Object = "DirectionalLight"; string Space = "World"; > = {1.0f, -1.0f, 1.0f, 0.0f}; float4 lightColor : Diffuse < string UIName = "Diffuse Light Color"; string Object = "DirectionalLight"; > = {1.0f, 1.0f, 1.0f, 1.0f}; float4 lightAmbient : Ambient < string UIWidget = "Ambient Light Color"; string Space = "material"; > = {0.0f, 0.0f, 0.0f, 1.0f}; float4 materialDiffuse : Diffuse < string UIWidget = "Surface Color"; string Space = "material"; > = {1.0f, 1.0f, 1.0f, 1.0f}; float4 materialSpecular : Specular < string UIWidget = "Surface Specular"; string Space = "material"; > = {1.0f, 1.0f, 1.0f, 1.0f}; float shininess : SpecularPower < string UIWidget = "slider"; float UIMin = 1.0; float UIMax = 128.0; float UIStep = 1.0; string UIName = "specular power"; > = 30.0; //------------------------------------ struct vertexInput { float3 position : POSITION; float3 normal : NORMAL; float3 texCoordDiffuse : TEXCOORD0; }; struct vertexOutput { float4 hPosition : POSITION; float3 texCoord0 : TEXCOORD0; float3 texCoord1 : TEXCOORD1; float4 diffAmbColor : COLOR0; float4 specCol : COLOR1; }; //------------------------------------ vertexOutput VS_TransformAndTexture(vertexInput IN) { vertexOutput OUT; OUT.hPosition = mul( float4(IN.position.xyz , 1.0) , worldViewProj); //OUT.hPosition = mul( float4(IN.position.xyz * float3(0.5, 0.5, 1.0) , 1.0) , proj); //OUT.texCoord0 = IN.texCoordDiffuse; // mirror x for fire OUT.texCoord0 = float3(-sin((IN.texCoordDiffuse.x-0.5)*3.14),IN.texCoordDiffuse.y,IN.texCoordDiffuse.z); //OUT.texCoord1 = noiseTranslation + IN.position * noiseScale + time; OUT.texCoord1 = noiseTranslation + IN.texCoordDiffuse * noiseScale + time; OUT.texCoord1.z *= 0.5; //calculate our vectors N, E, L, and H float3 worldEyePos = viewInverse[3].xyz; float3 worldVertPos = mul(IN.position, world).xyz; float4 N = mul(IN.normal, worldInverseTranspose); //normal vector float3 E = normalize(worldEyePos - worldVertPos); //eye vector float3 L = normalize( -lightDir.xyz); //light vector float3 H = normalize(E + L); //half angle vector //calculate the diffuse and specular contributions float diff = max(0 , dot(N,L)); float spec = pow( max(0 , dot(N,H) ) , shininess ); if( diff <= 0 ) { spec = 0; } //output diffuse float4 ambColor = materialDiffuse * lightAmbient; float4 diffColor = materialDiffuse * diff * lightColor ; OUT.diffAmbColor = diffColor + ambColor; //output specular float4 specColor = materialSpecular * lightColor * spec; OUT.specCol = specColor; return OUT; } //------------------------------------ // Samplers sampler TextureSampler = sampler_state { texture = ; AddressU = wrap; AddressV = wrap; AddressW = wrap; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; sampler NoiseSampler = sampler_state { texture = ; AddressU = wrap; AddressV = wrap; AddressW = wrap; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; // noise emulation functions via our noise sampler half4 noise(float3 P) { return tex3D(NoiseSampler, P); } half4 noiseSigned(float3 P) { return tex3D(NoiseSampler, P)*2-1; } half noiseSigned1(float3 P) { return tex3D(NoiseSampler, P).x*2-1; } // turbulence with 4 octaves, signed float turbulence3D_1( float3 P) { //half4 sum = noiseSigned(P)*0.5 + // noiseSigned(P*2)*0.25 + // noiseSigned(P*4)*0.125 + // noiseSigned(P*8)*0.0625; float sum = noiseSigned1(P)*0.5 + //noiseSigned1(P*2)*0.25 + //noiseSigned1(P*4)*0.125 + noiseSigned1(P*8)*0.0625; //return abs(sum); return sum; } // turbulence with 4 octaves 2D signed half4 turbulence3D_2( float3 P) { //half4 sum = noiseSigned(P)*0.5 + // noiseSigned(P*2)*0.25 + // noiseSigned(P*4)*0.125 + // noiseSigned(P*8)*0.0625; half sum1 = noiseSigned1(P)*0.5 + noiseSigned1(P*2)*0.25 + noiseSigned1(P*4)*0.125 + noiseSigned1(P*8)*0.0625; half sum2 = noiseSigned1(P.zxy)*0.5 + noiseSigned1(P.zxy*2)*0.25 + noiseSigned1(P.zxy*4)*0.125 + noiseSigned1(P.zxy*8)*0.0625; //return abs(sum); return half4(sum1,sum2,0,0); } // generic turbulence with H = 2.0 float turbulence(float3 p, int octaves) { float scale=1.0; float sum=0; while (octaves >0) { sum += noise(p)*scale; octaves--; scale /=2; p*=2.0; } return sum; } //----------------------------------- float4 PS_Textured( vertexOutput IN): COLOR { //half4 diffuseTexture = tex3D( NoiseSampler, IN.texCoordDiffuse ); //half4 diffuseTexture=noise(IN.texCoord1); // works in 1.4 half4 diffuseTexture = turbulence3D_1(IN.texCoord1); //half4 diffuseTexture = turbulence3D_2(IN.texCoord1); //half4 diffuseTexture = turbulence(IN.texCoord1,8); // too GPU intensive and erratic //return diffuseTexture; diffuseTexture = tex2D( TextureSampler, IN.texCoord0 + noiseAmount*diffuseTexture); //float4 diffuseTexture = noise(IN.texCoordDiffuse); return IN.diffAmbColor * diffuseTexture + IN.specCol; } float4 PS14_Textured( vertexOutput IN): COLOR { //float4 diffuseTexture = tex2D( NoiseSampler, IN.texCoordDiffuse ); //float4 diffuseTexture = turbulence3D_1(IN.texCoord1); float4 diffuseTexture = noise(IN.texCoord1); // works in 1.4 diffuseTexture = tex2D( TextureSampler, IN.texCoord0 + noiseAmount*diffuseTexture); //float4 diffuseTexture = noise(IN.texCoordDiffuse); return IN.diffAmbColor * diffuseTexture + IN.specCol; } //----------------------------------- technique PS20_textured_turbulence { pass p0 { VertexShader = compile vs_1_1 VS_TransformAndTexture(); PixelShader = compile ps_2_0 PS_Textured(); ZEnable = false; ZWriteEnable = false; AlphaBlendEnable = true; BlendOp = Add; SrcBlend = One; // gives more color density //SrcBlend = SrcAlpha; DestBlend = One; //AlphaTestEnable = TRUE; // can skip transparent pixels } } technique PS14_textured_noise { pass p0 { VertexShader = compile vs_1_1 VS_TransformAndTexture(); PixelShader = compile ps_1_4 PS14_Textured(); //ZEnable = true; ZWriteEnable = false; AlphaBlendEnable = true; BlendOp = Add; //SrcBlend = One; SrcBlend = SrcAlpha; DestBlend = One; AlphaTestEnable = TRUE; // can skip transparent pixels } }