Instructables universum i Three.js (12 / 13 steg)
Steg 12: Three.js: efterbehandling & effekter: mörkläggning, oskärpa
Kolla in! (och den handledning som går med det)
Galna effekter är möjliga med efterbehandling i ThreeJS, men jag behövde bara något enkelt: till dim allt utom stjärnbilden jag ville Visa. Ljusa vita linjer och punkter på en annars nedtonade scen.
Vänder ut, 3D-världen är inte som KineticJS. Jag kan inte bara lägga ett lager på toppen och räkna med webbläsaren rendering alfakanalen i lagret till dim grejer bakom den. Eller snarare jag kunde, men jag skulle behöva en helt separat scen, canvas och sammanhang, och det är inte helt klart vad som händer när du har två webgl windows ovanpå varandra. Jag tror inte det är trivialt att göra ett semi-transparent webgl rendering sammanhang.
Så var det nästa bästa att lägga till postprocesses till min befintliga återgivningstillägg. Detta är hur, när jag pratade om Partikelsystem i rörelse,
renderer.Render()
blev
_.each(Galaxy.Composers,function(Composer) {
Composer.Render();
});
Förbered:
1. i threejs reporäntan, ta en titt på exempel/js/shaders och exempel/js/efterbehandling
2. Välj några shaders. Detta är bara WebGL kod lagras i .js-filer, men de är samma i princip som jag gick igenom när han beskriver A olika ljusstyrka för varje stjärna shaders.
3. postprocessing katalogen har en massa verktyg, i huvudsak som du lager effekter på varandra
Montera (sätt skript på din sida):
-TRE. EffectComposer
-TRE. RenderPass (du behöver en renderpass så din påverkar gäller något )
-TRE. ShaderPass (eller två eller tre--dessa wrap din effekter)
-TRE. CopyShader (i fall du vill visa utan effekter ibland)
-TRE. AdditiveBlendShader (att blanda andra shaders)
-några shaders du
Koden:
Galaxy.ComposeScene = function(options) {
var kompositörer = [];
var mainComposer = nya tre. EffectComposer (renderer, renderTarget);
var renderPass = nya tre. RenderPass (scen, kamera);
mainComposer.addPass (renderPass);
om (_.isObject(options) & & options.blur === sant) {
var bluriness = 0,9;
Förbereda oskärpa skuggningen passerar
var hblur = nya tre. ShaderPass (tre. HorizontalBlurShader);
hblur.uniforms ["h"] .value = bluriness / Galaxy.Settings.width;
mainComposer.addPass(hblur);
var vblur = nya tre. ShaderPass (tre. VerticalBlurShader);
vblur.uniforms ["v"] .value = bluriness / Galaxy.Settings.height;
mainComposer.addPass (vblur);
var brightnessContrastPass = nya tre. ShaderPass (tre. BrightnessContrastShader);
brightnessContrastPass.uniforms ["ljusstyrka"] .value = -0,3;
brightnessContrastPass.uniforms ["kontrast"] .value = -0,2;
mainComposer.addPass(brightnessContrastPass);
} annat {
mainComposer.addPass (nya tre. ShaderPass (tre. CopyShader));
}
var topComposer = nya tre. EffectComposer (renderer, renderTarget2);
var topRenderPass = nya tre. RenderPass(topScene,camera);
topComposer.addPass(topRenderPass);
topComposer.addPass (nya tre. ShaderPass (tre. CopyShader));
////////////////////////////////////////////////////////////////////////
slutliga kompositör kommer att smälta composer2.render() resultat med scenen
////////////////////////////////////////////////////////////////////////
var blendPass = nya tre. ShaderPass (tre. AdditiveBlendShader);
blendPass.uniforms ['tBase'] .value = mainComposer.renderTarget1;
blendPass.uniforms ['tAdd'] .value = topComposer.renderTarget1;
var blendComposer = nya tre. EffectComposer (renderer);
blendComposer.addPass (blendPass);
blendPass.renderToScreen = sant;
Composers.push(mainComposer,topComposer,blendComposer);
returnera kompositörer;
};
I princip du kommer att ringa .render() på en kompositör nu, i stället för direkt på en renderare. Du kan sätta ihop ganska mycket någon rad effekter du vill genom att först göra en render passera, att lägga till kompositören, då lägga till efterföljande shaderpasses till samma kompositören. Så småningom skulle du vill lägga till en copyshader för att samla allt tillsammans, sätta den till renderToScreen och göra. Kokas ner, det kan se ut såhär:
var mainComposer = nya tre. EffectComposer (renderer, renderTarget);
var renderPass = nya tre. RenderPass (scen, kamera);
mainComposer.addPass (renderPass);
lägga till en skuggning
var shaderpass = nya tre. ShaderPass (tre. SomeShader);
... (göra en del inställningar för skuggningen här)
mainComposer.addPass(shaderpass);
lägga till en kopia, så webgl vet vad man ska göra:
var copypass = nya tre. ShaderPass (tre. CopyShader);
copypass.renderToScreen = sant;
mainComposer.addPass(copypass);
Render
mainComposer.render();
Men när det gäller vad jag har gjort här, det finns faktiskt två separata kompositörer som renderar två separata uppsättningar av objekt i scenen. När en konstellation är aktiv, återges dess stjärnor och anslutande linjer utan oskärpa, och vid full ljusstyrka. Bakgrund stjärnorna, men är mörkare och suddig. Så för att få de effekter som används på en uppsättning saker och inte andra, behöver du en helt separat scen med klonade objekt (topScene) och en helt separat kompositör stack.
Detta orsakar den liten komplikation som två behöva blandas ihop som ett sista steg: Jag skulle kunna göra topscene, men det skulle skymma botten scenen. Så är det sista som får återges i mitt fall en additiv blandning av de två tonsättarna resultat:
var blendPass = nya tre. ShaderPass (tre. AdditiveBlendShader);
blendPass.uniforms ['tBase'] .value = mainComposer.renderTarget1;
blendPass.uniforms ['tAdd'] .value = topComposer.renderTarget1;
var blendComposer = nya tre. EffectComposer (renderer);
blendComposer.addPass (blendPass);
blendPass.renderToScreen = sant;
Den sista biten: du har att göra alla tre kompositörer varje bildruta, eller innehållet i det kompositören kommer inte att uppdatera:
i funktionen composeScene
återvända composers.push(mainComposer,topComposer,blendComposer);
...
resultaten av ComposeScene lagras varje gång användaren går in och utgångar en konstellation
Galaxy.Composers = Galaxy.ComposeScene();
...
Render slingan återges varje kompositör
_.each(Galaxy.Composers,function(Composer) {
Composer.Render();
});
Det är allt det finns det!