2017-10-21 1 views
2

Ich habe ein Objekt, wo zufällige offene Teilchen und andere fest sind. Wie platziere ich eine gefälschte Sonne in das Objekt und bekomme Strahlen durch die offenen Teilchen mit Hilfe von threejs. Wenn das Objekt entweder X dreht, sollten Y-Strahlen durch die offenen Partikel gespreizt werden (POST PROCESSING)?Wie bekomme ich Sonnenstrahlen aus der Mitte des Objekts in threejs

SAMPLE VIDEO

Mein Objekt Three.js Code ist unten

var camera, scene, renderer; 
var geometry, material, mesh; 

    init(); 
    animate(); 

function init() { 

    camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 10, 10000); 
    camera.position.z = 200; 

    scene = new THREE.Scene(); 

    hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.6); 
    scene.add(hemiLight); 

    var geometry = new THREE.DodecahedronGeometry(80, 0); 

    var material = new THREE.MeshPhongMaterial({ 
    color: 0xffffff, 
    specular: 0xffffff, 
    shininess: 1, 
    shading: THREE.FlatShading, 
    polygonOffset: true, 
    polygonOffsetFactor: 1, 
    wireframe:true 

    }); 

    mesh = new THREE.Mesh(geometry, material); 

    scene.add(mesh); 

    var geo = new THREE.EdgesGeometry(mesh.geometry); // or WireframeGeometry 
    var mat = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 2 }); 
    var wireframe = new THREE.LineSegments(geo, mat); 
    mesh.add(wireframe); 

    //outer frame end 

    //inner world like object start 

    var sphere_material = [ 
     new THREE.MeshLambertMaterial({ color: 0xffff00, side: THREE.DoubleSide }), 
     new THREE.MeshBasicMaterial({ transparent: true, opacity: 0 }) 
    ]; 

    var sphere_geometry = new THREE.OctahedronGeometry(60, 3); 
    // assign material to each face 
    for(var i = 0; i < sphere_geometry.faces.length; i++) { 
     sphere_geometry.faces[ i ].materialIndex = THREE.Math.randInt(0, 1); 
    } 

    sphere_geometry.sortFacesByMaterialIndex(); 

    var sphere_mesh = new THREE.Mesh(sphere_geometry, sphere_material); 
    sphere_mesh.position.set(0, 0, 0) 
    mesh.add(sphere_mesh); 


    renderer = new THREE.WebGLRenderer({ 
    antialias: true 
    }); 

    renderer.setSize(window.innerWidth, window.innerHeight); 
    document.body.appendChild(renderer.domElement); 

} 
renderer.gammaInput = true; 
renderer.gammaOutput = true; 

function animate() { 

    requestAnimationFrame(animate); 

    mesh.rotation.x += 0.003; 
    mesh.rotation.y += 0.003; 

    renderer.render(scene, camera); 

} 

DEMO

+0

Könnten Sie bitte erklären, was "zufällig offen Partikel und andere" ist? Oder besser, um zu veranschaulichen, was es ist. Im Moment ist Ihre Frage sehr schwer zu verstehen, was Sie im Ergebnis wollen. Oder Sie müssen die Frage überarbeiten. – prisoner849

+0

@ häftling849 danke für den Kommentar. Ich habe meinen Code eingegeben. – underscore

+0

sieht aus, als ob du versuchst, [diesen] zu wiederholen (https://www.youtube.com/watch?v=suqFV7VGsL4) – prisoner849

Antwort

2

Sie suchen nach volumetric lights suchen. Überprüfen Sie dieses Codebeispiel unten, oder sehen Sie es sich besser unter jsfiddle an (um es in vollen Dimensionen zu sehen, die nicht vom Konsolenprotokoll überspielt werden).

Es basiert auf this Artikel. Ich habe Ihren Code etwas optimiert und die Farben sowie einige Werte und den Code aktualisiert. Es benötigt immer noch etwas Spiel (z. B. Anzahl der Gesichter, helle Farbe, Shader-Eigenschaften usw.), aber hoffentlich wird es dir helfen. Alles hängt davon ab, wie Sie es aussehen lassen möchten.

THREE.VolumetericLightShader = { 
 
    uniforms: { 
 
    tDiffuse: {value:null}, 
 
    lightPosition: {value: new THREE.Vector2(0.5, 0.5)}, 
 
    exposure: {value: 0.18}, 
 
    decay: {value: 0.95}, 
 
    density: {value: 0.8}, 
 
    weight: {value: 0.4}, 
 
    samples: {value: 50} 
 
    }, 
 

 
    vertexShader: [ 
 
    "varying vec2 vUv;", 
 
    "void main() {", 
 
     "vUv = uv;", 
 
     "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", 
 
    "}" 
 
    ].join("\n"), 
 

 
    fragmentShader: [ 
 
    "varying vec2 vUv;", 
 
    "uniform sampler2D tDiffuse;", 
 
    "uniform vec2 lightPosition;", 
 
    "uniform float exposure;", 
 
    "uniform float decay;", 
 
    "uniform float density;", 
 
    "uniform float weight;", 
 
    "uniform int samples;", 
 
    "const int MAX_SAMPLES = 100;", 
 
    "void main()", 
 
    "{", 
 
     "vec2 texCoord = vUv;", 
 
     "vec2 deltaTextCoord = texCoord - lightPosition;", 
 
     "deltaTextCoord *= 1.0/float(samples) * density;", 
 
     "vec4 color = texture2D(tDiffuse, texCoord);", 
 
     "float illuminationDecay = 1.0;", 
 
     "for(int i=0; i < MAX_SAMPLES; i++)", 
 
     "{", 
 
     "if(i == samples){", 
 
      "break;", 
 
     "}", 
 
     "texCoord -= deltaTextCoord;", 
 
     "vec4 sample = texture2D(tDiffuse, texCoord);", 
 
     "sample *= illuminationDecay * weight;", 
 
     "color += sample;", 
 
     "illuminationDecay *= decay;", 
 
     "}", 
 
     "gl_FragColor = color * exposure;", 
 
    "}" 
 
    ].join("\n") 
 
}; 
 

 
THREE.AdditiveBlendingShader = { 
 
    uniforms: { 
 
    tDiffuse: { value:null }, 
 
    tAdd: { value:null } 
 
    }, 
 

 
    vertexShader: [ 
 
    "varying vec2 vUv;", 
 
    "void main() {", 
 
     "vUv = uv;", 
 
     "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", 
 
    "}" 
 
    ].join("\n"), 
 

 
    fragmentShader: [ 
 
    "uniform sampler2D tDiffuse;", 
 
    "uniform sampler2D tAdd;", 
 
    "varying vec2 vUv;", 
 
    "void main() {", 
 
     "vec4 color = texture2D(tDiffuse, vUv);", 
 
     "vec4 add = texture2D(tAdd, vUv);", 
 
     "gl_FragColor = color + add;", 
 
    "}" 
 
    ].join("\n") 
 
}; 
 

 
THREE.PassThroughShader = { 
 
\t uniforms: { 
 
\t \t tDiffuse: { value: null } 
 
\t }, 
 

 
\t vertexShader: [ 
 
\t \t "varying vec2 vUv;", 
 
    "void main() {", 
 
\t \t "vUv = uv;", 
 
\t \t \t "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", 
 
\t \t "}" 
 
\t ].join("\n"), 
 

 
\t fragmentShader: [ 
 
    "uniform sampler2D tDiffuse;", 
 
    "varying vec2 vUv;", 
 
    "void main() {", 
 
\t \t \t "gl_FragColor = texture2D(tDiffuse, vec2(vUv.x, vUv.y));", 
 
\t \t "}" 
 
\t ].join("\n") 
 
}; 
 

 
(function(){ 
 
    var scene, camera, renderer, composer, box, pointLight, 
 
     occlusionComposer, occlusionRenderTarget, occlusionBox, lightSphere, 
 
     volumetericLightShaderUniforms, 
 
     DEFAULT_LAYER = 0, 
 
     OCCLUSION_LAYER = 1, 
 
     renderScale = 0.5, 
 
     angle = 0, 
 
     sphere_mesh, 
 
     mesh; 
 
    
 
    scene = new THREE.Scene(); 
 
    camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setPixelRatio(window.devicePixelRatio); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
    document.body.appendChild(renderer.domElement); 
 

 
    function setupScene(){ 
 
    var ambientLight, 
 
     geometry, 
 
     material; 
 

 
    ambientLight = new THREE.AmbientLight(0x2c3e50); 
 
    scene.add(ambientLight); 
 
    
 
    pointLight = new THREE.PointLight(0xddddff); 
 
    scene.add(pointLight); 
 
    
 
    geometry = new THREE.SphereBufferGeometry(1, 32, 32); 
 
    material = new THREE.MeshBasicMaterial({ color: 0x99ddff }); 
 
    lightSphere = new THREE.Mesh(geometry, material); 
 
    lightSphere.layers.set(OCCLUSION_LAYER); 
 
    scene.add(lightSphere); 
 
    
 
    camera.position.z = 6; 
 
    } 
 
    
 
    function addFragmentedSphere(){ 
 
    var geometry = new THREE.DodecahedronGeometry(2.9, 0); 
 

 
    var material = new THREE.MeshPhongMaterial({ 
 
    color: 0x000000, 
 
    specular: 0xffffff, 
 
    shininess: 1, 
 
    shading: THREE.FlatShading, 
 
    polygonOffset: true, 
 
    polygonOffsetFactor: 1, 
 
    wireframe:true 
 

 
    }); 
 

 
    mesh = new THREE.Mesh(geometry, material); 
 

 
    scene.add(mesh); 
 

 
    //outer frame end 
 

 
    //inner world like object start 
 

 
    var sphere_material = [ 
 
     new THREE.MeshLambertMaterial({ color: 0xffff00, side: THREE.DoubleSide }), 
 
     new THREE.MeshBasicMaterial({ transparent: true, opacity: 0 }) 
 
    ]; 
 

 
    var sphere_geometry = new THREE.OctahedronGeometry(2.7, 4); 
 
    // assign material to each face 
 
    for(var i = 0; i < sphere_geometry.faces.length; i++) { 
 
     sphere_geometry.faces[ i ].materialIndex = THREE.Math.randInt(0, 1); 
 
    } 
 

 
    sphere_geometry.sortFacesByMaterialIndex(); 
 

 
    sphere_mesh = new THREE.Mesh(sphere_geometry, sphere_material); 
 
    sphere_mesh.position.set(0, 0, 0) 
 
    mesh.add(sphere_mesh); 
 
    sphere_mesh.layers.set(OCCLUSION_LAYER); 
 
    } 
 

 
    function setupPostprocessing(){ 
 
    var pass; 
 
    
 
    occlusionRenderTarget = new THREE.WebGLRenderTarget(window.innerWidth * renderScale, window.innerHeight * renderScale); 
 
    occlusionComposer = new THREE.EffectComposer(renderer, occlusionRenderTarget); 
 
    occlusionComposer.addPass(new THREE.RenderPass(scene, camera)); 
 
    pass = new THREE.ShaderPass(THREE.VolumetericLightShader); 
 
    pass.needsSwap = false; 
 
    occlusionComposer.addPass(pass); 
 
    
 
    volumetericLightShaderUniforms = pass.uniforms; 
 
    volumetericLightShaderUniforms.exposure.value = 0.5; 
 
    volumetericLightShaderUniforms.decay.value = 0.96; 
 
    volumetericLightShaderUniforms.density.value = 0.95; 
 
    volumetericLightShaderUniforms.weight.value = 0.59; 
 
    volumetericLightShaderUniforms.samples.value = 100; 
 
    
 
    composer = new THREE.EffectComposer(renderer); 
 
    composer.addPass(new THREE.RenderPass(scene, camera)); 
 
    pass = new THREE.ShaderPass(THREE.AdditiveBlendingShader); 
 
    pass.uniforms.tAdd.value = occlusionRenderTarget.texture; 
 
    composer.addPass(pass); 
 
    pass.renderToScreen = true; 
 
    } 
 
    
 
    function onFrame(){ 
 
    requestAnimationFrame(onFrame); 
 
    update(); 
 
    render(); 
 
    } 
 
    
 
    function update(){ 
 
    mesh.rotation.x += 0.003; 
 
    mesh.rotation.y += 0.003; 
 
    } 
 

 
    function render(){ 
 
    camera.layers.set(OCCLUSION_LAYER); 
 
    renderer.setClearColor(0x000000); 
 
    occlusionComposer.render(); 
 
    
 
    camera.layers.set(DEFAULT_LAYER); 
 
    renderer.setClearColor(0x090611); 
 
    composer.render(); 
 
    } 
 
    
 
    function addRenderTargetImage(){   
 
    var material, 
 
     mesh, 
 
     folder; 
 

 
    material = new THREE.ShaderMaterial(THREE.PassThroughShader); 
 
    material.uniforms.tDiffuse.value = occlusionRenderTarget.texture; 
 

 
    mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), material); 
 
    composer.passes[1].scene.add(mesh); 
 
    mesh.visible = false; 
 
    } 
 
    
 
    window.addEventListener('resize', function(){ 
 

 
    camera.aspect = window.innerWidth/window.innerHeight; 
 
    camera.updateProjectionMatrix(); 
 

 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
    var pixelRatio = renderer.getPixelRatio(), 
 
     newWidth = Math.floor(window.innerWidth/pixelRatio) || 1, 
 
     newHeight = Math.floor(window.innerHeight/pixelRatio) || 1; 
 

 
    composer.setSize(newWidth, newHeight); 
 
    occlusionComposer.setSize(newWidth * renderScale, newHeight * renderScale); 
 
     
 
    }, false); 
 
    
 
    setupScene(); 
 
    setupPostprocessing(); 
 
    addFragmentedSphere();// 
 
    addRenderTargetImage(); 
 
    onFrame(); 
 
}())
<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script> 
 
<script src="https://abberg.github.io/lib/shaders/CopyShader.js"></script> 
 
<script src="https://abberg.github.io/lib/postprocessing/EffectComposer.js"></script> 
 
<script src="https://abberg.github.io/lib/postprocessing/RenderPass.js"></script> 
 
<script src="https://abberg.github.io/lib/postprocessing/ShaderPass.js"></script>

+0

Wie können wir die Parameter anpassen, wenn Hintergrundbild zu Szene hinzufügen? – underscore

+0

@underscore Hallo dort. Meiner Ansicht nach ist der relevanteste Parameter die Farbe der Strahlen (definiert durch die Punkte "pointLight = new THREE.PointLight (0xddddff);") und die volumetrischen Lichteigenschaften (definiert durch das Shader-Objekt "volumetericLightShaderUniforms" innerhalb der 'setupPostprocessing()' -Funktion). Vielleicht auch die Größe der Lichtkugel im Vergleich zur Größe der Kugelgeometrie. –

+0

Hast du eine schnelle Chat-Methode? – underscore

Verwandte Themen