I was a little too hasty with my joy. I took a Data3DTexture from an example from three.js. I pass this on to my webgl2 shader. the shader works but the screen is black. I tried to find help in the documentation for Data3DTexture on the three.js site but I can’t find a solution there. I suspect that I have to read a Data3DTexture differently and that’s where the problem lies. can anyone confirm this and know how to correct it in the shader?
I think it’s probably a simple thing, but I don’t see it
import * as THREE from "../lib/three/build/three.module.js";
import { OrbitControls } from '../lib/three/examples/jsm/controls/OrbitControls.js';
import { RenderPass } from '../lib/three/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from '../lib/three/examples/jsm/postprocessing/ShaderPass.js';
import { EffectComposer } from '../lib/three/examples/jsm/postprocessing/EffectComposer.js';
import WebGL from '../lib/three/examples/jsm/WebGL.js';
import { ImprovedNoise } from '../lib/three/examples/jsm/math/ImprovedNoise.js';
function main() {
new Main();
}
class Main {
constructor(){
this.init();
this.animate();
}
init(){
if (!WebGL.isWebGL2Available()) {
return false;
}
const canvas = document.createElement('canvas');
const context = canvas.getContext('webgl2');
this.renderer = new THREE.WebGLRenderer({
canvas: canvas,
context: context,
antialias: true
});
this.renderer.setPixelRatio( window.devicePixelRatio );
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.autoClear = false;
this.container = document.getElementById('container');
this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
this.container.appendChild( this.renderer.domElement );
this.aspect = this.container.clientWidth / this.container.clientHeight;
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color( 0x000000 );
this.camera = new THREE.PerspectiveCamera( 60, this.aspect, .1, 10000 );
this.camera.position.set(0, 100, 0);
this.controls = new OrbitControls( this.camera, this.renderer.domElement );
this.controls.enableZoom = true;
this.controls.enabled = true;
this.controls.target.set(0, 0, 0);
this.composer = new EffectComposer(this.renderer);
const renderPass = new RenderPass(this.scene, this.camera);
this.composer.addPass(renderPass);
//-------------------------------------------------------------------------------------------------
// Texture
const size = 128;
const data = new Uint8Array( size * size * size );
let i = 0;
const perlin = new ImprovedNoise();
const vector = new THREE.Vector3();
for ( let z = 0; z < size; z ++ ) {
for ( let y = 0; y < size; y ++ ) {
for ( let x = 0; x < size; x ++ ) {
vector.set( x, y, z ).divideScalar( size );
const d = perlin.noise( vector.x * 6.5, vector.y * 6.5, vector.z * 6.5 );
data[ i ++ ] = d * 128 + 128;
}
}
}
this.texture = new THREE.Data3DTexture( data, size, size, size );
this.texture.format = THREE.RedFormat;
this.texture.minFilter = THREE.LinearFilter;
this.texture.magFilter = THREE.LinearFilter;
this.texture.unpackAlignment = 1;
this.texture.needsUpdate = true;
const VS =`
in vec2 uv;
out vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4( (uv - 0.5)*2.0, 0.0, 1.0 );
}`;
const FS =`
precision highp sampler3D;
precision highp float;
precision highp int;
uniform sampler3D tDiffuse;
uniform float uZCoord;
in vec2 vUv;
out vec4 outColor;
void main() {
vec3 color = texture(tDiffuse, vec3(vUv, uZCoord)).rgb;
//color = vec3(0.1, 0.5, 1.); //just for test, work fine!
outColor = vec4(color, 1.);
}`;
const shaderMaterial = new THREE.RawShaderMaterial({
glslVersion: THREE.GLSL3,
uniforms: {
tDiffuse: { value: this.texture},
uZCoord: { value: 0 },
},
vertexShader: VS,
fragmentShader: FS,
});
this.composer.addPass(new ShaderPass(shaderMaterial));
}//end init
animate(){
requestAnimationFrame( this.animate.bind(this) );
this.render();
}//end animate
render(){
this.controls.update();
this.renderer.render(this.scene, this.camera);
this.composer.render();
}//end render
}//end class
main();
Unfortunately no difference. The program runs but the screen is black. By the way, your example helped me a lot to understand webgl2 shader. My goal is to create a 3D texture with a shader that can then be used by another shader. Your example here:
is the best I’ve found about “THREE.WebGL3DRenderTarget”. WebGL3DRenderTarget creates a Data3DTexture. That’s great. Now I just need to know how to use a Data3DTexture in a shader. The topic has been on my mind for a whole week and every small step is a great joy for me, and a hard fight . Now this last step is missing and i will finally have my peace with it.