Hi David,
Thanks for your answer.
1. Yes i am using the same shader for the PolyVox cube and the irrlicht cube.
2. The input is
normalize(gl_Vertex.xyz) which i pass to a varying variable in the vertex shader, so that i can use it in the fragment shader. The x, y, and z positions are then multiplied with a frequency value to add noise detail, e.g. known as fractal brownian motion. The multiplied positions are passed as input for the 3D-simplexnoise function. See the function calculateFBM in the fragment shader.
3. I attached the the screenshots in wireframe and visualized RGB, see attachments and following posts. The visualized RGB images are also in wireframe. I hope i understood you correctly, for RGB visualization i simply pass the vertex positions directly to gl_FragColor: e.g.
gl_FragColor = vec4(vTexCoord3D.xyz, 1.0); 4. The shader code:
Vertex shader:
Code:
#version 120
// vertex positions for 3D-noise
varying vec3 vTexCoord3D;
// variables for lighting model
uniform vec3 camPos;
uniform vec3 lightPosition;
varying vec3 lightPos;
varying vec4 lightdiffuse;
varying vec4 lightambient;
varying vec3 lightnormal;
varying vec3 lightHV;
void computeVertexLight()
{
/* first transform the normal into eye space and normalize the result */
lightnormal = gl_Normal;
lightPos = lightPosition;
/* compute the vertex position in camera space. */
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
vec3 eyeVect = normalize(camPos - vec3(pos.xyz));
lightHV = normalize(normalize(lightPosition) + eyeVect) * 0.5;
/* Compute the diffuse, ambient and globalAmbient terms */
lightdiffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
lightambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
lightambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;
}
void main()
{
//computeVertexLight();
vTexCoord3D = normalize(gl_Vertex.xyz);
gl_Position = ftransform();
}
Fragment shader:
Code:
#version 120
varying vec3 vTexCoord3D;
varying vec3 lightPos;
varying vec4 lightdiffuse;
varying vec4 lightambient;
varying vec3 lightnormal;
varying vec3 lightHV;
// ================================================================================
// 3D Simplex noise, courtesy of Stefan Gustavson and Ian McEwan fromm Ashima Arts.
// Copyright (C) 2011 Ashima Arts. Distributed under the MIT License.
// ================================================================================
vec4 mod289(vec4 x)
{
return x - floor(x * 0.003460208) * 289.0;
}
vec3 mod289(vec3 x)
{
return x - floor(x * 0.003460208) * 289.0;
}
vec4 permute(vec4 x)
{
return mod289(((x * 34.0) + 1.0) * x);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
float simplexNoise3D(vec3 v)
{
const vec2 C = vec2(0.1666, 0.3333) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1),
dot(p2, x2), dot(p3, x3)));
}
// ================================================================================
vec3 RGBConv(vec3 rgb)
{
return vec3(rgb.r * 0.003921569, rgb.g * 0.003921569, rgb.b * 0.003921569);
}
vec4 RGBAConv(vec4 rgba)
{
return vec4(rgba.r * 0.003921569, rgba.g * 0.003921569, rgba.b * 0.003921569, rgba.a * 0.003921569);
}
// apply fractal Brownian motion
float calculateFBM(vec3 coord, float persistence, float numOctaves, float frequency)
{
float noiseVal = 0.0;
float amplitude = 1;
for (int i = 0; i < numOctaves; ++i) {
noiseVal += simplexNoise3D(frequency * coord) * amplitude;
frequency *= 2;
amplitude *= persistence;
}
return noiseVal;
}
vec4 computePixelLight()
{
vec4 color = lightambient;
vec3 lightDir = normalize(lightPos);
/* a fragment shader can't write a varying variable, hence we need
a new variable to store the normalized interpolated normal */
vec3 n = normalize(lightnormal);
// compute the dot product between normal and ldir
float NdotL = max(dot(n, lightDir), 0.0);
if (NdotL > 0.0) {
color += lightdiffuse * NdotL;
vec3 halfV = normalize(lightHV);
float NdotHV = max(dot(n, halfV) ,0.0);
color += vec4(0.0, 0.0, 0.0, 1.0) * pow(NdotHV, 0.0);
}
return color;
}
void main()
{
float mixFactor = calculateFBM(vTexCoord3D, 0.5, 1, 16);
float mixFactor2 = calculateFBM(vTexCoord3D, 1, 4, 16);
float mixFactor3 = calculateFBM(vTexCoord3D, 0.0625, 1, 8);
vec4 color1 = RGBAConv(vec4(237, 211, 161, 255));
vec4 color2 = RGBAConv(vec4(161, 129, 69, 255));
vec4 noiseColor1 = mix(color1, color2, mixFactor);
vec4 noiseColor2 = mix(color2, color1, mixFactor2);
vec4 noiseColor3 = mix(color1, color2, mixFactor3);
vec4 col1 = mix(noiseColor1, noiseColor2, mixFactor3);
vec4 col2 = mix(noiseColor1, noiseColor3, mixFactor3);
vec4 col3 = mix(noiseColor2, noiseColor3, mixFactor3);
gl_FragColor = col1 * col2 * col3;// * computePixelLight();
//suggested rgb visualization by David Williams from volumesoffun.com
//gl_FragColor = vec4(vTexCoord3D.xyz, 1.0);
}